⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glib-util.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
字号:
/* * Copyright (c) 2005 Zmanda, Inc.  All Rights Reserved. *  * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 2.1 as  * published by the Free Software Foundation. *  * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public * License for more details. *  * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA. *  * Contact information: Zmanda Inc., 505 N Mathlida Ave, Suite 120 * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com *//* * Utilities that aren't quite included in glib * * Author: Dustin J. Mitchell <dustin@zmanda.com>, Ian Turner <ian@zmanda.com> */#include "amanda.h"#include "glib-util.h"#include "conffile.h" /* For find_multiplier. */typedef enum {    FLAG_STRING_NAME,    FLAG_STRING_SHORT_NAME,    FLAG_STRING_NICK} FlagString;static char ** g_flags_to_strv(int value, GType type, FlagString source);void_glib_util_foreach_glue(gpointer data, gpointer func){    void (*one_arg_fn)(gpointer) = (void (*)(gpointer))func;    one_arg_fn(data);}GValue* g_value_unset_init(GValue* value, GType type) {    g_return_val_if_fail(value != NULL, NULL);    if (G_IS_VALUE(value)) {        g_value_unset(value);    }    g_value_init(value, type);    return value;}GValue* g_value_unset_copy(const GValue * from, GValue * to) {    g_return_val_if_fail(from != NULL, NULL);    g_return_val_if_fail(to != NULL, NULL);    g_value_unset_init(to, G_VALUE_TYPE(from));    g_value_copy(from, to);    return to;}void g_list_free_full(GList * list) {    GList * cur = list;    while (cur != NULL) {        gpointer data = cur->data;        amfree(data);        cur = g_list_next(cur);    }    g_list_free(list);}void g_slist_free_full(GSList * list) {    GSList * cur = list;    while (cur != NULL) {        gpointer data = cur->data;        amfree(data);        cur = g_slist_next(cur);    }    g_slist_free(list);}void g_queue_free_full(GQueue * queue) {    while (!g_queue_is_empty(queue)) {        gpointer data;        data = g_queue_pop_head(queue);        amfree(data);    }    g_queue_free(queue);}void g_ptr_array_free_full(GPtrArray * array) {    size_t i;    for (i = 0; i < array->len; i ++) {        amfree(g_ptr_array_index(array, i));    }    g_ptr_array_free(array, TRUE);}gboolean g_value_compare(GValue * a, GValue * b) {    if (a == NULL && b == NULL)        return TRUE;    if (a == NULL || b == NULL)        return FALSE;    if (G_VALUE_TYPE(a) != G_VALUE_TYPE(b))        return FALSE;    if (g_value_fits_pointer(a) && g_value_fits_pointer(b)) {        return g_value_peek_pointer(a) == g_value_peek_pointer(b);    } else {        /* Since there is no builtin comparison function, we resort to           comparing serialized strings. Yuck. */        char * a_str;        char * b_str;        gboolean rval;        a_str = g_strdup_value_contents(a);        b_str = g_strdup_value_contents(b);        rval = (0 == strcmp(a_str, b_str));        amfree(a_str);        amfree(b_str);        return rval;    }        g_assert_not_reached();}static gboolean g_value_set_boolean_from_string(GValue * val, char * string) {    if (strcasecmp(string, "true") == 0 ||        strcasecmp(string, "yes") == 0 ||        strcmp(string, "1") == 0) {        g_value_set_boolean(val, TRUE);    } else if (strcasecmp(string, "false") == 0 ||               strcasecmp(string, "no") == 0 ||               strcmp(string, "0") == 0) {        g_value_set_boolean(val, FALSE);    } else {        return FALSE;    }    return TRUE;}static gboolean g_value_set_int_from_string(GValue * val, char * string) {    long int strto_result;    char * strto_end;    gint64 multiplier;    strto_result = strtol(string, &strto_end, 0);    multiplier = find_multiplier(strto_end);    if (multiplier == G_MAXINT64) {        if (strto_result >= 0) {            g_value_set_int(val, G_MAXINT);        } else {            g_value_set_int(val, G_MININT);        }        return TRUE;    } else if (*string == '\0' || multiplier == 0               || strto_result < G_MININT / multiplier               || strto_result > G_MAXINT / multiplier) {        return FALSE;    } else {         g_value_set_int(val, (int)(strto_result * multiplier));        return TRUE;    }}static gboolean g_value_set_uint_from_string(GValue * val, char * string) {    unsigned long int strto_result;    char * strto_end;    guint64 multiplier;    strto_result = strtoul(string, &strto_end, 0);    multiplier = find_multiplier(strto_end); /* casts */    if (multiplier == G_MAXINT64) {        g_value_set_uint(val, G_MAXUINT);        return TRUE;    } else if (multiplier == 0 || *string == '\0' ||               strto_result > G_MAXUINT / multiplier) {        return FALSE;    } else {        g_value_set_uint(val, (guint)(strto_result * multiplier));        return TRUE;    }}static gboolean g_value_set_uint64_from_string(GValue * val, char * string) {    unsigned long long int strto_result;    char * strto_end;    guint64 multiplier;    strto_result = strtoull(string, &strto_end, 0);    multiplier = find_multiplier(strto_end); /* casts */    if (multiplier == G_MAXINT64) {        g_value_set_uint64(val, G_MAXUINT64);        return TRUE;    } else if (multiplier == 0 || *string == '\0' ||        strto_result > G_MAXUINT64 / multiplier) {        return FALSE;    } else {        g_value_set_uint64(val, (guint64)(strto_result * multiplier));        return TRUE;    }}/* Flags can contain multiple values. We assume here that values are like * C identifiers (that is, they match /[A-Za-z_][A-Za-z0-9_]+/), although * that doesn't seem to be a requirement of GLib. With that assumption in * mind, we look for the format "FLAG_1 | FLAG_2 | ... | FLAG_N". */static gboolean g_value_set_flags_from_string(GValue * val, char * string) {    guint value = 0;    char * strtok_saveptr;    char * string_copy;    char * strtok_first_arg;    const char delim[] = " \t,|";    GFlagsClass * flags_class;        flags_class = (GFlagsClass*) g_type_class_ref(G_VALUE_TYPE(val));    g_return_val_if_fail(flags_class != NULL, FALSE);    g_return_val_if_fail(G_IS_FLAGS_CLASS(flags_class), FALSE);    /* Don't let strtok stop on original. */    strtok_first_arg = string_copy = strdup(string);        for (;;) {        GFlagsValue * flag_value;        char * token = strtok_r(strtok_first_arg, delim, &strtok_saveptr);        strtok_first_arg = NULL;        if (token == NULL) {            break;        }                flag_value = g_flags_get_value_by_name(flags_class, token);        if (flag_value == NULL) {            flag_value = g_flags_get_value_by_nick(flags_class, token);        }        if (flag_value == NULL) {            g_fprintf(stderr, _("Invalid flag %s for type %s\n"), token,                    g_type_name(G_VALUE_TYPE(val)));            continue;        }        value |= flag_value->value;    }        amfree(string_copy);        if (value == 0) {        g_fprintf(stderr, _("No valid flags for type %s in string %s\n"),                g_type_name(G_VALUE_TYPE(val)), string);        return FALSE;    }        g_value_set_flags(val, value);    return TRUE;}/* This function really ought not to be part of Amanda. In my (Ian's) opinion,   serialization and deserialization should be a part of the GValue   interface. But it's not, and here we are. */gboolean g_value_set_from_string(GValue * val, char * string) {    g_return_val_if_fail(val != NULL, FALSE);    g_return_val_if_fail(G_IS_VALUE(val), FALSE);    if (G_VALUE_HOLDS_BOOLEAN(val)) {        return g_value_set_boolean_from_string(val, string);    } else if (G_VALUE_HOLDS_INT(val)) {        return g_value_set_int_from_string(val, string);    } else if (G_VALUE_HOLDS_UINT(val)) {        return g_value_set_uint_from_string(val, string);    } else if (G_VALUE_HOLDS_UINT64(val)) {        return g_value_set_uint64_from_string(val, string);    } else if (G_VALUE_HOLDS_STRING(val)) {        g_value_set_string(val, string);        return TRUE;    } else if (G_VALUE_HOLDS_FLAGS(val)) {        return g_value_set_flags_from_string(val, string);    }    return TRUE;}gintg_compare_strings(    gconstpointer a,    gconstpointer b){    return strcmp((char *)a, (char *)b);}char * g_strjoinv_and_free(char ** strv, const char * seperator) {    char * rval = g_strjoinv(seperator, strv);    g_strfreev(strv);    return rval;}char ** g_flags_name_to_strv(int value, GType type) {    return g_flags_to_strv(value, type, FLAG_STRING_NAME);}char ** g_flags_short_name_to_strv(int value, GType type) {    return g_flags_to_strv(value, type, FLAG_STRING_SHORT_NAME);}char ** g_flags_nick_to_strv(int value, GType type) {    return g_flags_to_strv(value, type, FLAG_STRING_NICK);}static char * get_name_from_value(GFlagsValue * value, FlagString source) {    switch (source) {    case FLAG_STRING_NAME:    case FLAG_STRING_SHORT_NAME:        return strdup(value->value_name);    case FLAG_STRING_NICK:        return strdup(value->value_nick);    default:        return NULL;    }}/* If freed and notfreed have a common prefix that is different from freed,   then return that and free freed. Otherwise, return freed. */static char * find_common_prefix(char * freed, const char * notfreed) {    char * freed_ptr = freed;    const char * notfreed_ptr = notfreed;    if (freed == NULL) {        if (notfreed == NULL) {            return NULL;        } else {            return strdup(notfreed);        }    } else if (notfreed == NULL) {        amfree(freed);        return strdup("");    }    while (*freed_ptr == *notfreed_ptr) {        freed_ptr ++;        notfreed_ptr ++;    }    *freed_ptr = '\0';    return freed;}static char ** g_flags_to_strv(int value, GType type,                               FlagString source) {    GPtrArray * rval;    GFlagsValue * flagsvalue;    char * common_prefix = NULL;    int common_prefix_len;    GFlagsClass * class;    g_return_val_if_fail(G_TYPE_IS_FLAGS(type), NULL);    g_return_val_if_fail((class = g_type_class_ref(type)) != NULL, NULL);    g_return_val_if_fail(G_IS_FLAGS_CLASS(class), NULL);            rval = g_ptr_array_new();    for (flagsvalue = class->values;         flagsvalue->value_name != NULL;         flagsvalue ++) {        if (source == FLAG_STRING_SHORT_NAME) {            common_prefix = find_common_prefix(common_prefix,                                               flagsvalue->value_name);        }                                                       if ((flagsvalue->value == 0 && value == 0) ||            (flagsvalue->value != 0 && (value & flagsvalue->value))) {            g_ptr_array_add(rval, get_name_from_value(flagsvalue, source));        }    }    if (source == FLAG_STRING_SHORT_NAME && common_prefix != NULL &&        ((common_prefix_len = strlen(common_prefix))) > 0) {        char * old;        char * new;        guint i;        for (i = 0; i < rval->len; i ++) {            old = g_ptr_array_index(rval, i);            new = strdup(old + common_prefix_len);            g_ptr_array_index(rval, i) = new;            g_free(old);        }    }        g_ptr_array_add(rval, NULL);    amfree(common_prefix);    return (char**)g_ptr_array_free(rval, FALSE);}char * g_english_strjoinv(char ** strv, const char * conjunction) {    int length;    char * last;    char * joined;    char * rval;    strv = g_strdupv(strv);    length = g_strv_length(strv);    last = strv[length - 1];    strv[length - 1] = NULL;        joined = g_strjoinv(", ", strv);    rval = g_strdup_printf("%s, %s %s", joined, conjunction, last);    g_free(joined);    g_free(last);    g_strfreev(strv);    return rval;}char * g_english_strjoinv_and_free(char ** strv, const char * conjunction) {    char * rval = g_english_strjoinv(strv, conjunction);    g_strfreev(strv);    return rval;   }#if !(GLIB_CHECK_VERSION(2,6,0))guint g_strv_length(gchar ** strv) {    int rval = 0;    if (G_UNLIKELY(strv == NULL))        return 0;    while (*strv != NULL) {        rval ++;        strv ++;    }    return rval;}#endif /* GLIB_CHECK_VERSION(2.6.0) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -