aboutsummaryrefslogtreecommitdiffstats
path: root/android/utils/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'android/utils/misc.c')
-rw-r--r--android/utils/misc.c120
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;
+ }
+}