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

📄 config_utils.c

📁 Android 一些工具
💻 C
字号:
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#include <string.h>#include <ctype.h>#include <stdlib.h>#include <fcntl.h>#include <unistd.h>#include <cutils/config_utils.h>#include <cutils/misc.h>cnode* config_node(const char *name, const char *value){    cnode *node;    node = calloc(sizeof(cnode), 1);    if(node) {        node->name = name ? name : "";        node->value = value ? value : "";    }    return node;}cnode* config_find(cnode *root, const char *name){    cnode *node, *match = NULL;    /* we walk the whole list, as we need to return the last (newest) entry */    for(node = root->first_child; node; node = node->next)        if(!strcmp(node->name, name))            match = node;    return match;}static cnode* _config_create(cnode *root, const char *name){    cnode *node;    node = config_node(name, NULL);    if(root->last_child)        root->last_child->next = node;    else        root->first_child = node;    root->last_child = node;    return node;}int config_bool(cnode *root, const char *name, int _default){    cnode *node;            node = config_find(root, name);    if(!node)        return _default;    switch(node->value[0]) {    case 'y':    case 'Y':    case '1':        return 1;    default:        return 0;    }}const char* config_str(cnode *root, const char *name, const char *_default){    cnode *node;    node = config_find(root, name);    if(!node)        return _default;    return node->value;}void config_set(cnode *root, const char *name, const char *value){    cnode *node;    node = config_find(root, name);    if(node)        node->value = value;    else {        node = _config_create(root, name);        node->value = value;    }}#define T_EOF 0#define T_TEXT 1#define T_DOT 2#define T_OBRACE 3#define T_CBRACE 4typedef struct{    char *data;    char *text;    int len;    char next;} cstate;static int _lex(cstate *cs, int value){    char c;    char *s;    char *data;    data = cs->data;    if(cs->next != 0) {        c = cs->next;        cs->next = 0;        goto got_c;    }restart:    for(;;) {        c = *data++;    got_c:        if(isspace(c))            continue;        switch(c) {        case 0:            return T_EOF;        case '#':            for(;;) {                switch(*data) {                case 0:                    cs->data = data;                    return T_EOF;                case '\n':                    cs->data = data + 1;                    goto restart;                default:                    data++;                }            }            break;                    case '.':            cs->data = data;            return T_DOT;        case '{':            cs->data = data;            return T_OBRACE;        case '}':            cs->data = data;            return T_CBRACE;        default:            s = data - 1;            if(value) {                for(;;) {                    if(*data == 0) {                        cs->data = data;                        break;                    }                    if(*data == '\n') {                        cs->data = data + 1;                        *data-- = 0;                        break;                    }                    data++;                }                    /* strip trailing whitespace */                while(data > s){                    if(!isspace(*data)) break;                    *data-- = 0;                }                goto got_text;                            } else {                for(;;) {                    if(isspace(*data)) {                        *data = 0;                        cs->data = data + 1;                        goto got_text;                    }                    switch(*data) {                    case 0:                        cs->data = data;                        goto got_text;                    case '.':                    case '{':                    case '}':                        cs->next = *data;                        *data = 0;                        cs->data = data + 1;                        goto got_text;                    default:                        data++;                    }                }            }        }    }got_text:    cs->text = s;    return T_TEXT;}#if 0char *TOKENNAMES[] = { "EOF", "TEXT", "DOT", "OBRACE", "CBRACE" };static int lex(cstate *cs, int value){    int tok = _lex(cs, value);    printf("TOKEN(%d) %s %s\n", value, TOKENNAMES[tok],           tok == T_TEXT ? cs->text : "");    return tok;}#else#define lex(cs,v) _lex(cs,v)#endifstatic int parse_expr(cstate *cs, cnode *node);static int parse_block(cstate *cs, cnode *node){    for(;;){        switch(lex(cs, 0)){        case T_TEXT:            if(parse_expr(cs, node)) return -1;            continue;        case T_CBRACE:            return 0;        default:            return -1;        }    }}static int parse_expr(cstate *cs, cnode *root){    cnode *node;        /* last token was T_TEXT */    node = config_find(root, cs->text);    if(!node || *node->value)        node = _config_create(root, cs->text);    for(;;) {        switch(lex(cs, 1)) {        case T_DOT:            if(lex(cs, 0) != T_TEXT)                return -1;            node = _config_create(node, cs->text);            continue;        case T_TEXT:            node->value = cs->text;            return 0;        case T_OBRACE:            return parse_block(cs, node);        default:            return -1;        }    }}void config_load(cnode *root, char *data){    if(data != 0) {        cstate cs;        cs.data = data;        cs.next = 0;        for(;;) {            switch(lex(&cs, 0)) {            case T_TEXT:                if(parse_expr(&cs, root))                    return;                break;            default:                return;            }        }    }}void config_load_file(cnode *root, const char *fn){    char *data;    data = load_file(fn, 0);    config_load(root, data);}

⌨️ 快捷键说明

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