#include "mdbfakeglib.h" #include #include #include #include #include #include /* string functions */ void *g_memdup(const void *src, size_t len) { void *dst = malloc(len); memcpy(dst, src, len); return dst; } int g_str_equal(const void *str1, const void *str2) { return strcmp(str1, str2) == 0; } char **g_strsplit(const char *haystack, const char *needle, int something) { char **ret = NULL; char *found = NULL; size_t components = 1; while ((found = strstr(haystack, needle))) { components++; haystack = found + strlen(needle); } ret = malloc(components * sizeof(char *)); int i = 0; while ((found = strstr(haystack, needle))) { ret[i++] = strndup(haystack, found - haystack); haystack = found + strlen(needle); } ret[i] = strdup(haystack); return ret; } void g_strfreev(char **dir) { int i=0; while (dir[i]) { free(dir[i]); i++; } free(dir); } char *g_strconcat(const char *first, ...) { char *ret = NULL; size_t len = strlen(first); char *arg = NULL; va_list argp; va_start(argp, first); while ((arg = va_arg(argp, char *))) { len += strlen(arg); } va_end(argp); ret = malloc(len+1); char *pos = stpcpy(ret, first); va_start(argp, first); while ((arg = va_arg(argp, char *))) { pos = stpcpy(pos, arg); } va_end(argp); ret[len] = '\0'; return ret; } char *g_strdup_printf(const char *format, ...) { char *ret = NULL; va_list argp; va_start(argp, format); vasprintf(&ret, format, argp); va_end(argp); return ret; } gchar *g_strdelimit(gchar *string, const gchar *delimiters, gchar new_delimiter) { char *orig = string; if (delimiters == NULL) delimiters = G_STR_DELIMITERS; size_t n = strlen(delimiters); while (*string) { size_t i; for (i=0; iarray->len; i++) { MyNode *node = g_ptr_array_index(table->array, i); if (table->compare(key, node->key)) return node->value; } return NULL; } void g_hash_table_insert(GHashTable *table, void *key, void *value) { MyNode *node = calloc(1, sizeof(MyNode)); node->value = value; node->key = key; g_ptr_array_add(table->array, node); } GHashTable *g_hash_table_new(GHashFunc hashes, GEqualFunc equals) { GHashTable *table = calloc(1, sizeof(GHashTable)); table->array = g_ptr_array_new(); table->compare = equals; return table; } void g_hash_table_foreach(GHashTable *table, GHFunc function, void *data) { int i; for (i=0; iarray->len; i++) { MyNode *node = g_ptr_array_index(table->array, i); function(node->key, node->value, data); } } void g_hash_table_destroy(GHashTable *table) { int i; for (i=0; iarray->len; i++) { MyNode *node = g_ptr_array_index(table->array, i); free(node); } g_ptr_array_free(table->array, TRUE); free(table); } /* GPtrArray */ void g_ptr_array_sort(GPtrArray *array, GCompareFunc func) { qsort(array->pdata, array->len, sizeof(void *), func); } void g_ptr_array_foreach(GPtrArray *array, GFunc function, gpointer user_data) { int i; for (i=0; ilen; i++) { function(g_ptr_array_index(array, i), user_data); } } GPtrArray *g_ptr_array_new() { GPtrArray *array = malloc(sizeof(GPtrArray)); array->len = 0; array->pdata = NULL; return array; } void g_ptr_array_add(GPtrArray *array, void *entry) { array->pdata = realloc(array->pdata, (array->len+1) * sizeof(void *)); array->pdata[array->len++] = entry; } void g_ptr_array_free(GPtrArray *array, gboolean something) { free(array->pdata); free(array); } /* GList */ GList *g_list_append(GList *list, void *data) { GList *new_list = calloc(1, sizeof(GList)); new_list->data = data; new_list->next = list; if (list) list->prev = new_list; return new_list; } GList *g_list_last(GList *list) { while (list && list->next) { list = list->next; } return list; } GList *g_list_remove(GList *list, void *data) { GList *link = list; while (link) { if (link->data == data) { GList *return_list = list; if (link->prev) link->prev->next = link->next; if (link->next) link->next->prev = link->prev; if (link == list) return_list = link->next; free(link); return list; } link = link->next; } return list; } void g_list_free(GList *list) { GList *next = NULL; while (list) { next = list->next; free(list); list = next; } } /* GOption */ void g_option_context_add_main_entries (GOptionContext *context, const GOptionEntry *entries, const gchar *translation_domain) { context->entries = entries; } gchar *g_option_context_get_help (GOptionContext *context, gboolean main_help, void *group) { #if defined(__APPLE__) || defined(__FreeBSD__) const char * appname = getprogname(); #elif defined(_GNU_SOURCE) const char * appname = program_invocation_name; #else const char * appname = "mdb-util"; #endif char *help = malloc(4096); char *end = help + 4096; char *p = help; p += snprintf(p, end - p, "Usage:\n %s [OPTION\xE2\x80\xA6] %s\n\n", appname, context->desc); p += snprintf(p, end - p, "Help Options:\n -h, --%-20s%s\n\n", "help", "Show help options"); p += snprintf(p, end - p, "Application Options:\n"); int i=0; for (i=0; context->entries[i].long_name; i++) { p += snprintf(p, end - p, " "); if (context->entries[i].short_name) { p += snprintf(p, end - p, "-%c, ", context->entries[i].short_name); } p += snprintf(p, end - p, "--"); if (context->entries[i].arg_description) { char *long_name = g_strconcat( context->entries[i].long_name, "=", context->entries[i].arg_description, NULL); p += snprintf(p, end - p, "%-20s", long_name); free(long_name); } else { p += snprintf(p, end - p, "%-20s", context->entries[i].long_name); } if (!context->entries[i].short_name) { p += snprintf(p, end - p, " "); } p += snprintf(p, end - p, "%s\n", context->entries[i].description); } p += snprintf(p, end - p, "\n"); return help; } GOptionContext *g_option_context_new(const char *description) { GOptionContext *ctx = calloc(1, sizeof(GOptionContext)); ctx->desc = description; return ctx; } gboolean g_option_context_parse(GOptionContext *context, gint *argc, gchar ***argv, GError **error) { int i; int count = 0; int len = 0; if (*argc == 2 && (strcmp((*argv)[1], "-h") == 0 || strcmp((*argv)[1], "--help") == 0)) { fprintf(stderr, "%s", g_option_context_get_help(context, TRUE, NULL)); exit(0); } for (i=0; context->entries[i].long_name; i++) { GOptionArg arg = context->entries[i].arg; count++; len++; if (arg == G_OPTION_ARG_STRING || arg == G_OPTION_ARG_INT) { len++; } } struct option *long_opts = calloc(count+1, sizeof(struct option)); char *short_opts = calloc(1, len+1); int j=0; for (i=0; ientries[i]; GOptionArg arg = entry->arg; short_opts[j++] = entry->short_name; if (arg == G_OPTION_ARG_STRING || arg == G_OPTION_ARG_INT) { short_opts[j++] = ':'; } long_opts[i].name = entry->long_name; long_opts[i].has_arg = entry->arg == G_OPTION_ARG_NONE ? no_argument : required_argument; } int c; int longindex = 0; opterr = 0; while ((c = getopt_long(*argc, *argv, short_opts, long_opts, &longindex)) != -1) { if (c == '?') { *error = malloc(sizeof(GError)); (*error)->message = malloc(100); if (optopt) { snprintf((*error)->message, 100, "Unrecognized option: -%c", optopt); } else { snprintf((*error)->message, 100, "Unrecognized option: %s", (*argv)[optind-1]); } free(short_opts); free(long_opts); return FALSE; } const GOptionEntry *entry = NULL; if (c == 0) { entry = &context->entries[longindex]; } else { for (i=0; ientries[i].short_name == c) { entry = &context->entries[i]; break; } } } if (entry->arg == G_OPTION_ARG_NONE) { *(int *)entry->arg_data = !(entry->flags & G_OPTION_FLAG_REVERSE); } else if (entry->arg == G_OPTION_ARG_INT) { char *endptr = NULL; *(int *)entry->arg_data = strtol(optarg, &endptr, 10); if (*endptr) { *error = malloc(sizeof(GError)); (*error)->message = malloc(100); snprintf((*error)->message, 100, "Argument to --%s must be an integer", entry->long_name); free(short_opts); free(long_opts); return FALSE; } } else if (entry->arg == G_OPTION_ARG_STRING) { *(char **)entry->arg_data = strdup(optarg); } } *argc -= (optind - 1); *argv += (optind - 1); free(short_opts); free(long_opts); return TRUE; } void g_option_context_free(GOptionContext *context) { free(context); }