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} 318c3cf1a827807d11b07bce9d6941342c68808aab1Eric Laurent 319c3cf1a827807d11b07bce9d6941342c68808aab1Eric Laurentvoid config_free(cnode *root) 320c3cf1a827807d11b07bce9d6941342c68808aab1Eric Laurent{ 321c3cf1a827807d11b07bce9d6941342c68808aab1Eric Laurent cnode *cur = root->first_child; 322c3cf1a827807d11b07bce9d6941342c68808aab1Eric Laurent 323c3cf1a827807d11b07bce9d6941342c68808aab1Eric Laurent while (cur) { 324c3cf1a827807d11b07bce9d6941342c68808aab1Eric Laurent cnode *prev = cur; 325c3cf1a827807d11b07bce9d6941342c68808aab1Eric Laurent config_free(cur); 326c3cf1a827807d11b07bce9d6941342c68808aab1Eric Laurent cur = cur->next; 327c3cf1a827807d11b07bce9d6941342c68808aab1Eric Laurent free(prev); 328c3cf1a827807d11b07bce9d6941342c68808aab1Eric Laurent } 329c3cf1a827807d11b07bce9d6941342c68808aab1Eric Laurent} 330