config_utils.c revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License.
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License.
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h>
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h>
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/config_utils.h>
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/misc.h>
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcnode* config_node(const char *name, const char *value)
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cnode *node;
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node = calloc(sizeof(cnode), 1);
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(node) {
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        node->name = name ? name : "";
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        node->value = value ? value : "";
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return node;
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcnode* config_find(cnode *root, const char *name)
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cnode *node, *match = NULL;
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* we walk the whole list, as we need to return the last (newest) entry */
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(node = root->first_child; node; node = node->next)
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(!strcmp(node->name, name))
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            match = node;
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return match;
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic cnode* _config_create(cnode *root, const char *name)
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cnode *node;
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node = config_node(name, NULL);
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(root->last_child)
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        root->last_child->next = node;
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        root->first_child = node;
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    root->last_child = node;
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return node;
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint config_bool(cnode *root, const char *name, int _default)
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cnode *node;
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node = config_find(root, name);
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!node)
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return _default;
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch(node->value[0]) {
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'y':
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 'Y':
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case '1':
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    default:
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst char* config_str(cnode *root, const char *name, const char *_default)
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cnode *node;
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node = config_find(root, name);
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!node)
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return _default;
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return node->value;
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid config_set(cnode *root, const char *name, const char *value)
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cnode *node;
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node = config_find(root, name);
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(node)
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        node->value = value;
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else {
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        node = _config_create(root, name);
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        node->value = value;
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define T_EOF 0
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define T_TEXT 1
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define T_DOT 2
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define T_OBRACE 3
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define T_CBRACE 4
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *data;
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *text;
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len;
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char next;
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} cstate;
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int _lex(cstate *cs, int value)
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char c;
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *s;
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *data;
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    data = cs->data;
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(cs->next != 0) {
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c = cs->next;
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        cs->next = 0;
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto got_c;
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectrestart:
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c = *data++;
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    got_c:
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(isspace(c))
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        switch(c) {
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case 0:
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return T_EOF;
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '#':
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            for(;;) {
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                switch(*data) {
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                case 0:
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    cs->data = data;
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    return T_EOF;
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                case '\n':
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    cs->data = data + 1;
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    goto restart;
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                default:
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    data++;
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '.':
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            cs->data = data;
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return T_DOT;
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '{':
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            cs->data = data;
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return T_OBRACE;
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case '}':
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            cs->data = data;
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return T_CBRACE;
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        default:
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            s = data - 1;
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(value) {
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                for(;;) {
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    if(*data == 0) {
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        cs->data = data;
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        break;
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    }
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    if(*data == '\n') {
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        cs->data = data + 1;
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        *data-- = 0;
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        break;
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    }
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    data++;
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    /* strip trailing whitespace */
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                while(data > s){
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    if(!isspace(*data)) break;
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    *data-- = 0;
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                goto got_text;
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                for(;;) {
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    if(isspace(*data)) {
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        *data = 0;
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        cs->data = data + 1;
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        goto got_text;
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    }
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    switch(*data) {
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    case 0:
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        cs->data = data;
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        goto got_text;
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    case '.':
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    case '{':
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    case '}':
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        cs->next = *data;
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        *data = 0;
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        cs->data = data + 1;
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        goto got_text;
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    default:
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        data++;
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    }
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgot_text:
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cs->text = s;
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return T_TEXT;
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar *TOKENNAMES[] = { "EOF", "TEXT", "DOT", "OBRACE", "CBRACE" };
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int lex(cstate *cs, int value)
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int tok = _lex(cs, value);
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("TOKEN(%d) %s %s\n", value, TOKENNAMES[tok],
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project           tok == T_TEXT ? cs->text : "");
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return tok;
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define lex(cs,v) _lex(cs,v)
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int parse_expr(cstate *cs, cnode *node);
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int parse_block(cstate *cs, cnode *node)
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;){
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        switch(lex(cs, 0)){
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case T_TEXT:
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(parse_expr(cs, node)) return -1;
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case T_CBRACE:
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        default:
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int parse_expr(cstate *cs, cnode *root)
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cnode *node;
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* last token was T_TEXT */
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node = config_find(root, cs->text);
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!node || *node->value)
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        node = _config_create(root, cs->text);
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        switch(lex(cs, 1)) {
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case T_DOT:
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(lex(cs, 0) != T_TEXT)
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            node = _config_create(node, cs->text);
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case T_TEXT:
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            node->value = cs->text;
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case T_OBRACE:
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return parse_block(cs, node);
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        default:
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid config_load(cnode *root, char *data)
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(data != 0) {
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        cstate cs;
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        cs.data = data;
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        cs.next = 0;
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for(;;) {
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            switch(lex(&cs, 0)) {
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case T_TEXT:
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if(parse_expr(&cs, root))
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    return;
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                break;
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            default:
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return;
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid config_load_file(cnode *root, const char *fn)
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *data;
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    data = load_file(fn, 0);
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    config_load(root, data);
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
318