18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful,
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/stralloc.h"
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/debug.h"
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/misc.h"
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h>
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <limits.h>
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
22062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turnerstralloc_tabular( stralloc_t*  out,
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  const char** strings, int  count,
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  const char*  prefix,  int  width )
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nrows, ncols, r, c, n, maxw = 0;
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (n = 0; n < count; n++) {
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  len = strlen(strings[n]);
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (len > maxw)
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            maxw = len;
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    maxw += 2;
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ncols = width/maxw;
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nrows = (count + ncols-1)/ncols;
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (r = 0; r < nrows; r++) {
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        stralloc_add_str( out, prefix );
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (c = 0; c < ncols; c++) {
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int  index = c*nrows + r;
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (index >= count) {
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            stralloc_add_format( out, "%-*s", maxw, strings[index] );
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        stralloc_add_str( out, "\n" );
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** DYNAMIC STRINGS
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_reset( stralloc_t*  s )
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    free(s->s);
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->s = NULL;
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->n = 0;
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->a = 0;
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_ready( stralloc_t*  s, unsigned int  len )
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned  old_max = s->a;
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned  new_max = old_max;
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (new_max < len) {
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        unsigned  new_max2 = new_max + (new_max >> 1) + 16;
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (new_max2 < new_max)
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            new_max2 = UINT_MAX;
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        new_max = new_max2;
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->s = realloc( s->s, new_max );
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->s == NULL) {
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        derror( "%s: not enough memory to reallocate %ld bytes",
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                __FUNCTION__, new_max );
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->a = new_max;
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_readyplus( stralloc_t*  s, unsigned int  len )
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned  len2 = s->n + len;
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len2 < s->n) { /* overflow ? */
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        derror("%s: trying to grow by too many bytes: %ld",
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               __FUNCTION__, len);
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_ready( s, len2 );
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_copy( stralloc_t*  s, stralloc_t*  from )
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_ready(s, from->n);
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memcpy( s->s, from->s, from->n );
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->n = from->n;
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_append( stralloc_t*  s, stralloc_t*  from )
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_readyplus( s, from->n );
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memcpy( s->s + s->n, from->s, from->n );
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->n += from->n;
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_add_c( stralloc_t*  s, int  c )
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_add_bytes( s, (char*)&c, 1 );
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_add_str( stralloc_t*  s, const char*  str )
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_add_bytes( s, str, strlen(str) );
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_add_bytes( stralloc_t*  s, const void*  from, unsigned len )
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_readyplus( s, len );
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memcpy( s->s + s->n, from, len );
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->n += len;
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern char*
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_cstr( stralloc_t*  s )
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_readyplus( s, 1 );
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->s[s->n] = 0;
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return s->s;
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
141062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turnervoid
142062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turnerstralloc_lstrip( stralloc_t*  s )
143062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner{
144062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    int  count;
145062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
146062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    for (count = 0; count < s->n; count++) {
147062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        if (s->s[count] != ' ' && s->s[count] != '\t')
148062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner            break;
149062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    }
150062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
151062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    if (count > 0) {
152062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        memmove(s->s, s->s + count, s->n - count);
153062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        s->n -= count;
154062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    }
155062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner}
156062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
157062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turnervoid
158062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turnerstralloc_rstrip( stralloc_t*  s )
159062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner{
160062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    int  count = s->n;
161062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
162062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    while (count > 0 && (s->s[count-1] == ' ' || s->s[count-1] == '\t'))
163062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        count--;
164062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
165062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    s->n = count;
166062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner}
167062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
168062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turnervoid
169062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turnerstralloc_strip( stralloc_t* s )
170062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner{
171062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    stralloc_rstrip(s);
172062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    stralloc_lstrip(s);
173062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner}
174062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern char*
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_to_tempstr( stralloc_t*  s )
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*  q = tempstr_get( s->n );
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memcpy( q, s->s, s->n );
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    q[s->n] = 0;
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return q;
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_formatv( stralloc_t*  s, const char*  fmt, va_list  args )
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_reset(s);
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_ready(s,10);
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (1) {
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int      n;
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        va_list  args2;
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        va_copy(args2, args);
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        n = vsnprintf( s->s, s->a, fmt, args2 );
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        va_end(args2);
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* funky old C libraries returns -1 when truncation occurs */
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (n > -1 && n < s->a) {
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->n = n;
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (n > -1) {  /* we now precisely what we need */
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            stralloc_ready( s, n+1 );
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            stralloc_ready( s, s->a*2 );
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_format( stralloc_t*  s, const char*  fmt, ... )
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_list  args;
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_start(args, fmt);
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_formatv(s, fmt, args);
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_end(args);
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_add_formatv( stralloc_t*  s, const char*  fmt, va_list  args )
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    STRALLOC_DEFINE(s2);
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_formatv(s2, fmt, args);
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_append( s, s2 );
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_reset( s2 );
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_add_format( stralloc_t*  s, const char*  fmt, ... )
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_list  args;
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_start(args, fmt);
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_add_formatv( s, fmt, args );
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_end(args);
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_add_quote_c( stralloc_t*  s, int  c )
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_add_quote_bytes( s, (char*)&c, 1 );
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_add_quote_str( stralloc_t*  s, const char*  str )
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_add_quote_bytes( s, str, strlen(str) );
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_add_quote_bytes( stralloc_t*  s, const void*  from, unsigned  len )
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t*   p   = (uint8_t*) from;
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t*   end = p + len;
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for ( ; p < end; p++ ) {
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  c = p[0];
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (c == '\\') {
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            stralloc_add_str( s, "\\\\" );
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else if (c >= ' ' && c < 128) {
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            stralloc_add_c( s, c );
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else if (c == '\n') {
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            stralloc_add_str( s, "\\n" );
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else if (c == '\t') {
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            stralloc_add_str( s, "\\t" );
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else if (c == '\r') {
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            stralloc_add_str( s, "\\r" );
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            stralloc_add_format( s, "\\x%02x", c );
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_add_hex( stralloc_t*  s, unsigned  value, int  num_digits )
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char   hexdigits[16] = "0123456789abcdef";
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int          nn;
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (num_digits <= 0)
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_readyplus(s, num_digits);
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = num_digits-1; nn >= 0; nn--) {
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->s[s->n+nn] = hexdigits[value & 15];
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        value >>= 4;
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->n += num_digits;
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstralloc_add_hexdump( stralloc_t*  s, void*  base, int  size, const char*  prefix )
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t*   p          = (uint8_t*)base;
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const int  max_count  = 16;
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int        prefix_len = strlen(prefix);
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (size > 0) {
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int          count = size > max_count ? max_count : size;
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int          count2;
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int          n;
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        stralloc_add_bytes( s, prefix, prefix_len );
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        stralloc_add_hex( s, p[0], 2 );
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (n = 1; n < count; n++) {
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            stralloc_add_c( s, ' ' );
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            stralloc_add_hex( s, p[n], 2 );
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        count2 = 4 + 3*(max_count - count);
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        stralloc_readyplus( s, count2 );
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memset( s->s + s->n, ' ', count2 );
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->n += count2;
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        stralloc_readyplus(s, count+1);
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (n = 0; n < count; n++) {
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int  c = p[n];
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (c < 32 || c > 127)
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                c = '.';
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->s[s->n++] = c;
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->s[s->n++] = '\n';
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        size -= count;
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p    += count;
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
335