diff options
Diffstat (limited to 'android/utils/misc.c')
-rw-r--r-- | android/utils/misc.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/android/utils/misc.c b/android/utils/misc.c index 818ab78..80dc9a4 100644 --- a/android/utils/misc.c +++ b/android/utils/misc.c @@ -10,6 +10,7 @@ ** GNU General Public License for more details. */ +#include "qemu-common.h" #include "android/utils/misc.h" #include "android/utils/stralloc.h" #include "android/utils/debug.h" @@ -17,6 +18,8 @@ #include <stdio.h> #include <stdlib.h> +#define E(...) derror(__VA_ARGS__) + extern void print_tabular( const char** strings, int count, const char* prefix, int width ) @@ -191,3 +194,120 @@ int2hex( uint8_t* hex, int len, int val ) while ( --len >= 0 ) *hex++ = hexchars[(val >> (len*4)) & 15]; } + +/** STRING PARAMETER PARSING + **/ + +int +strtoi(const char *nptr, char **endptr, int base) +{ + long val; + + errno = 0; + val = strtol(nptr, endptr, base); + if (errno) { + return (val == LONG_MAX) ? INT_MAX : INT_MIN; + } else { + if (val == (int)val) { + return (int)val; + } else { + errno = ERANGE; + return val > 0 ? INT_MAX : INT_MIN; + } + } +} + +int +get_token_value(const char* params, const char* name, char* value, int val_size) +{ + const char* val_end; + int len = strlen(name); + const char* par_end = params + strlen(params); + const char* par_start = strstr(params, name); + + /* Search for 'name=' */ + while (par_start != NULL) { + /* Make sure that we're within the parameters buffer. */ + if ((par_end - par_start) < len) { + par_start = NULL; + break; + } + /* Make sure that par_start starts at the beginning of <name>, and only + * then check for '=' value separator. */ + if ((par_start == params || (*(par_start - 1) == ' ')) && + par_start[len] == '=') { + break; + } + /* False positive. Move on... */ + par_start = strstr(par_start + 1, name); + } + if (par_start == NULL) { + return -1; + } + + /* Advance past 'name=', and calculate value's string length. */ + par_start += len + 1; + val_end = strchr(par_start, ' '); + if (val_end == NULL) { + val_end = par_start + strlen(par_start); + } + len = val_end - par_start; + + /* Check if fits... */ + if ((len + 1) <= val_size) { + memcpy(value, par_start, len); + value[len] = '\0'; + return 0; + } else { + return len + 1; + } +} + +int +get_token_value_alloc(const char* params, const char* name, char** value) +{ + char tmp; + int res; + + /* Calculate size of string buffer required for the value. */ + const int val_size = get_token_value(params, name, &tmp, 0); + if (val_size < 0) { + *value = NULL; + return val_size; + } + + /* Allocate string buffer, and retrieve the value. */ + *value = (char*)malloc(val_size); + if (*value == NULL) { + E("%s: Unable to allocated %d bytes for string buffer.", + __FUNCTION__, val_size); + return -2; + } + res = get_token_value(params, name, *value, val_size); + if (res) { + E("%s: Unable to retrieve value into allocated buffer.", __FUNCTION__); + free(*value); + *value = NULL; + } + + return res; +} + +int +get_token_value_int(const char* params, const char* name, int* value) +{ + char val_str[64]; // Should be enough for all numeric values. + if (!get_token_value(params, name, val_str, sizeof(val_str))) { + errno = 0; + *value = strtoi(val_str, (char**)NULL, 10); + if (errno) { + E("%s: Value '%s' of the parameter '%s' in '%s' is not a decimal number.", + __FUNCTION__, val_str, name, params); + return -2; + } else { + return 0; + } + } else { + return -1; + } +} |