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
132ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine#include "qemu-common.h"
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/misc.h"
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/stralloc.h"
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/debug.h"
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h>
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
212ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine#define  E(...)    derror(__VA_ARGS__)
222ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectprint_tabular( const char** strings, int  count,
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               const char*  prefix,  int  width )
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nrows, ncols, r, c, n, maxw = 0;
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (n = 0; n < count; n++) {
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  len = strlen(strings[n]);
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (len > maxw)
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            maxw = len;
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    maxw += 2;
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ncols = width/maxw;
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    nrows = (count + ncols-1)/ncols;
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (r = 0; r < nrows; r++) {
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf( "%s", prefix );
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (c = 0; c < ncols; c++) {
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int  index = c*nrows + r;
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (index >= count) {
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf( "%-*s", maxw, strings[index] );
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf( "\n" );
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstring_translate_char( char*  str, char from, char to )
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*  p = str;
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (p != NULL && (p = strchr(p, from)) != NULL)
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *p++ = to;
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbuffer_translate_char( char*        buff,
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       unsigned     buffLen,
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       const char*  src,
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       char         fromChar,
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       char         toChar )
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int    len = strlen(src);
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len >= buffLen)
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len = buffLen-1;
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memcpy(buff, src, len);
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buff[len] = 0;
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    string_translate_char( buff, fromChar, toChar );
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** TEMP CHAR STRINGS
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ** implement a circular ring of temporary string buffers
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct Temptring {
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct TempString*  next;
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*               buffer;
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int                 size;
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} TempString;
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  MAX_TEMP_STRINGS   16
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic TempString  _temp_strings[ MAX_TEMP_STRINGS ];
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int         _temp_string_n;
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern char*
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttempstr_get( int  size )
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TempString*  t = &_temp_strings[_temp_string_n];
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ++_temp_string_n >= MAX_TEMP_STRINGS )
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        _temp_string_n = 0;
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    size += 1;  /* reserve 1 char for terminating zero */
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (t->size < size) {
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        t->buffer = realloc( t->buffer, size );
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (t->buffer == NULL) {
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            derror( "%s: could not allocate %d bytes",
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    __FUNCTION__, size );
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        t->size   = size;
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return  t->buffer;
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern char*
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttempstr_format( const char*  fmt, ... )
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_list  args;
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*    result;
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    STRALLOC_DEFINE(s);
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_start(args, fmt);
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_formatv(s, fmt, args);
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_end(args);
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result = stralloc_to_tempstr(s);
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_reset(s);
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** QUOTING
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ** dumps a human-readable version of a string. this replaces
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ** newlines with \n, etc...
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern const char*
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectquote_bytes( const char*  str, int  len )
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    STRALLOC_DEFINE(s);
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*  q;
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_add_quote_bytes( s, str, len );
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    q = stralloc_to_tempstr( s );
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_reset(s);
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return q;
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern const char*
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectquote_str( const char*  str )
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  len = strlen(str);
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return quote_bytes( str, len );
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** HEXADECIMAL CHARACTER SEQUENCES
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecthexdigit( int  c )
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned  d;
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    d = (unsigned)(c - '0');
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (d < 10) return d;
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    d = (unsigned)(c - 'a');
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (d < 6) return d+10;
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    d = (unsigned)(c - 'A');
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (d < 6) return d+10;
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecthex2int( const uint8_t*  hex, int  len )
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  result = 0;
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (len > 0) {
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  c = hexdigit(*hex++);
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (c < 0)
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        result = (result << 4) | c;
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len --;
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint2hex( uint8_t*  hex, int  len, int  val )
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static const uint8_t  hexchars[16] = "0123456789abcdef";
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while ( --len >= 0 )
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *hex++ = hexchars[(val >> (len*4)) & 15];
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1972ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine
1982ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine/** STRING PARAMETER PARSING
1992ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine **/
2002ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine
2012ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkineint
2022ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkinestrtoi(const char *nptr, char **endptr, int base)
2032ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine{
2042ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    long val;
2052ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine
2062ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    errno = 0;
2072ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    val = strtol(nptr, endptr, base);
2082ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    if (errno) {
2092ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        return (val == LONG_MAX) ? INT_MAX : INT_MIN;
2102ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    } else {
2112ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        if (val == (int)val) {
2122ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine            return (int)val;
2132ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        } else {
2142ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine            errno = ERANGE;
2152ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine            return val > 0 ? INT_MAX : INT_MIN;
2162ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        }
2172ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    }
2182ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine}
2192ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine
2202ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkineint
2212ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkineget_token_value(const char* params, const char* name, char* value, int val_size)
2222ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine{
2232ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    const char* val_end;
2242ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    int len = strlen(name);
2252ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    const char* par_end = params + strlen(params);
2262ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    const char* par_start = strstr(params, name);
2272ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine
2282ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    /* Search for 'name=' */
2292ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    while (par_start != NULL) {
2302ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        /* Make sure that we're within the parameters buffer. */
2312ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        if ((par_end - par_start) < len) {
2322ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine            par_start = NULL;
2332ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine            break;
2342ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        }
2352ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        /* Make sure that par_start starts at the beginning of <name>, and only
2362ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine         * then check for '=' value separator. */
2372ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        if ((par_start == params || (*(par_start - 1) == ' ')) &&
2382ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine                par_start[len] == '=') {
2392ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine            break;
2402ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        }
2412ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        /* False positive. Move on... */
2422ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        par_start = strstr(par_start + 1, name);
2432ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    }
2442ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    if (par_start == NULL) {
2452ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        return -1;
2462ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    }
2472ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine
2482ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    /* Advance past 'name=', and calculate value's string length. */
2492ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    par_start += len + 1;
2502ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    val_end = strchr(par_start, ' ');
2512ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    if (val_end == NULL) {
2522ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        val_end = par_start + strlen(par_start);
2532ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    }
2542ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    len = val_end - par_start;
2552ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine
2562ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    /* Check if fits... */
2572ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    if ((len + 1) <= val_size) {
2582ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        memcpy(value, par_start, len);
2592ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        value[len] = '\0';
2602ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        return 0;
2612ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    } else {
2622ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        return len + 1;
2632ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    }
2642ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine}
2652ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine
2662ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkineint
2672ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkineget_token_value_alloc(const char* params, const char* name, char** value)
2682ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine{
2692ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    char tmp;
2702ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    int res;
2712ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine
2722ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    /* Calculate size of string buffer required for the value. */
2732ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    const int val_size = get_token_value(params, name, &tmp, 0);
2742ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    if (val_size < 0) {
2752ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        *value = NULL;
2762ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        return val_size;
2772ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    }
2782ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine
2792ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    /* Allocate string buffer, and retrieve the value. */
2802ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    *value = (char*)malloc(val_size);
2812ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    if (*value == NULL) {
2822ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        E("%s: Unable to allocated %d bytes for string buffer.",
2832ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine          __FUNCTION__, val_size);
2842ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        return -2;
2852ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    }
2862ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    res = get_token_value(params, name, *value, val_size);
2872ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    if (res) {
2882ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        E("%s: Unable to retrieve value into allocated buffer.", __FUNCTION__);
2892ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        free(*value);
2902ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        *value = NULL;
2912ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    }
2922ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine
2932ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    return res;
2942ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine}
2952ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine
2962ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkineint
2972ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkineget_token_value_int(const char* params, const char* name, int* value)
2982ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine{
2992ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    char val_str[64];   // Should be enough for all numeric values.
3002ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    if (!get_token_value(params, name, val_str, sizeof(val_str))) {
3012ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        errno = 0;
3022ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        *value = strtoi(val_str, (char**)NULL, 10);
3032ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        if (errno) {
3042ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine            E("%s: Value '%s' of the parameter '%s' in '%s' is not a decimal number.",
3052ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine              __FUNCTION__, val_str, name, params);
3062ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine            return -2;
3072ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        } else {
3082ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine            return 0;
3092ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        }
3102ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    } else {
3112ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine        return -1;
3122ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine    }
3132ae501556f90647e40466b6a1948f6f7f51cf251Vladimir Chtchetkine}
314