diff options
Diffstat (limited to 'util/cbfstool/flashmap/kv_pair.c')
-rw-r--r-- | util/cbfstool/flashmap/kv_pair.c | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/util/cbfstool/flashmap/kv_pair.c b/util/cbfstool/flashmap/kv_pair.c new file mode 100644 index 0000000000..2572c642f8 --- /dev/null +++ b/util/cbfstool/flashmap/kv_pair.c @@ -0,0 +1,242 @@ +/* + * Copyright 2010, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> + +#include "kv_pair.h" + +/* Internal variable for output style. Use accessors to get/set style. */ +static enum kv_pair_style _style; + +void kv_pair_set_style(enum kv_pair_style style) +{ + _style = style; +} + +enum kv_pair_style kv_pair_get_style() +{ + return _style; +} + +struct kv_pair *kv_pair_new(void) +{ + struct kv_pair *kv; + + kv = calloc(0, sizeof(*kv)); + if (!kv) + return NULL; + + return kv; +} + +struct kv_pair **kv_pair_new_array(size_t size) +{ + struct kv_pair **kv; + size_t i; + + kv = (struct kv_pair **) calloc(0, sizeof(kv) * size); + for (i = 0; i < size; ++i) { + kv[i] = kv_pair_new(); + } + return kv; +} + +struct kv_pair *kv_pair_add(struct kv_pair *kv_list, + const char *key, const char *value) +{ + struct kv_pair *kv_new; + struct kv_pair *kv_ptr; + + kv_new = kv_pair_new(); + if (!kv_new) + return NULL; + + /* save key=value strings if provided */ + if (key) { + kv_new->key = strdup(key); + if (!kv_new->key) + goto kv_pair_add_failed; + } + if (value) { + kv_new->value = strdup(value); + if (!kv_new->value) + goto kv_pair_add_failed; + } + + /* first in the list if no list provided */ + if (kv_list) { + /* find the end of list */ + for (kv_ptr = kv_list; kv_ptr->next != NULL; + kv_ptr = kv_ptr->next) + ; + + /* link in the new pair at the end */ + kv_ptr->next = kv_new; + } + + /* return pointer to the new pair */ + return kv_new; + +kv_pair_add_failed: + kv_pair_free(kv_new); + return NULL; +} + +struct kv_pair *kv_pair_add_bool(struct kv_pair *kv_list, + const char *key, int value) +{ + const char *str; + + if (value) { + str = "yes"; + } else { + str = "no"; + } + return kv_pair_add(kv_list, key, str); +} + +struct kv_pair *kv_pair_fmt(struct kv_pair *kv_list, + const char *kv_key, const char *format, ...) +{ + char kv_value[KV_PAIR_MAX_VALUE_LEN]; + va_list vptr; + + memset(kv_value, 0, sizeof(kv_value)); + + va_start(vptr, format); + vsnprintf(kv_value, sizeof(kv_value), format, vptr); + va_end(vptr); + + return kv_pair_add(kv_list, kv_key, kv_value); +} + +void kv_pair_free(struct kv_pair *kv_list) +{ + struct kv_pair *kv_ptr = kv_list; + struct kv_pair *kv_next; + + while (kv_ptr != NULL) { + /* free key/value strings */ + if (kv_ptr->key) + free(kv_ptr->key); + if (kv_ptr->value) + free(kv_ptr->value); + + /* free current pair move to next */ + kv_next = kv_ptr->next; + free(kv_ptr); + kv_ptr = kv_next; + } +} + +void kv_pair_free_array(struct kv_pair **kv_array, size_t size) +{ + size_t i; + for (i = 0; i < size; ++i) { + kv_pair_free(kv_array[i]); + } + free(kv_array); +} + +void kv_pair_print_to_file(FILE* fp, struct kv_pair *kv_list, + enum kv_pair_style style) +{ + struct kv_pair *kv_ptr; + + switch (style) { + case KV_STYLE_PAIR: + for (kv_ptr = kv_list; kv_ptr != NULL; kv_ptr = kv_ptr->next) { + if (kv_ptr->key && kv_ptr->value) { + fprintf(fp, "%s=\"%s\" ", + kv_ptr->key, kv_ptr->value); + } + } + break; + + case KV_STYLE_VALUE: + for (kv_ptr = kv_list; kv_ptr != NULL; kv_ptr = kv_ptr->next) { + if (kv_ptr->value) { + fprintf(fp, "%s", kv_ptr->value); + if (kv_ptr->next) + fprintf(fp, " | "); + } + } + break; + + case KV_STYLE_LONG: + for (kv_ptr = kv_list; kv_ptr != NULL; kv_ptr = kv_ptr->next) { + if (kv_ptr->key && kv_ptr->value) + fprintf(fp, "%-20s | %s\n", + kv_ptr->key, kv_ptr->value); + } + break; + } + + fprintf(fp, "\n"); +} + +void kv_pair_print(struct kv_pair *kv_list) +{ + kv_pair_print_to_file(stdout, kv_list, kv_pair_get_style()); +} + +const char *kv_pair_get_value(struct kv_pair *kv_list, const char *kv_key) +{ + const char *kv_value = NULL; + struct kv_pair *kv_ptr; + + for (kv_ptr = kv_list; kv_ptr != NULL; kv_ptr = kv_ptr->next) { + if (kv_ptr->key && strcmp(kv_ptr->key, kv_key) == 0) { + kv_value = kv_ptr->value; + break; + } + } + return kv_value; +} + +int kv_pair_size(struct kv_pair *kv_list) { + struct kv_pair *kv_ptr; + int count; + + count = 0; + for (kv_ptr = kv_list; kv_ptr != NULL; kv_ptr = kv_ptr->next) { + if (kv_ptr->key) { + count++; + } + } + return count; +} |