18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms. 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful, 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details. 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h> 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <ctype.h> 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h> 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <fcntl.h> 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <unistd.h> 174e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner#include <errno.h> 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1973dd5fc7da33280597dc6302ad8116d3723ebf3eDavid 'Digit' Turner#include "android/config-file.h" 20af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner#include "android/utils/eintr_wrapper.h" 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/path.h" 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAConfig* 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectaconfig_node(const char *name, const char *value) 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AConfig *n; 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n = (AConfig*) calloc(sizeof(AConfig), 1); 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->name = name ? name : ""; 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->value = value ? value : ""; 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return n; 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic AConfig* 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_aconfig_find(AConfig *root, const char *name, int create) 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AConfig *node; 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(node = root->first_child; node; node = node->next) { 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(!strcmp(node->name, name)) return node; 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(create) { 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project node = (AConfig*) calloc(sizeof(AConfig), 1); 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project node->name = name; 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project node->value = ""; 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(root->last_child) { 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project root->last_child->next = node; 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project root->first_child = node; 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project root->last_child = node; 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return node; 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAConfig* 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectaconfig_find(AConfig *root, const char *name) 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return _aconfig_find(root, name, 0); 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectaconfig_bool(AConfig *root, const char *name, int _default) 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AConfig *n = _aconfig_find(root, name, 0); 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(n == 0) { 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return _default; 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(n->value[0]){ 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 'y': 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 'Y': 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case '1': 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectaconfig_unsigned(AConfig *root, const char *name, unsigned _default) 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AConfig *n = _aconfig_find(root, name, 0); 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(n == 0) { 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return _default; 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return strtoul(n->value, 0, 0); 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectaconfig_int(AConfig *root, const char *name, int _default) 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AConfig *n = _aconfig_find(root, name, 0); 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(n == 0) { 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return _default; 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return strtol(n->value, 0, 0); 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char* 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectaconfig_str(AConfig *root, const char *name, const char *_default) 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AConfig *n = _aconfig_find(root, name, 0); 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(n == 0) { 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return _default; 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return n->value; 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectaconfig_set(AConfig *root, const char *name, const char *value) 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AConfig *node = _aconfig_find(root, name, 1); 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project node->value = value; 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define T_EOF 0 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define T_TEXT 1 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define T_DOT 2 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define T_OBRACE 3 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define T_CBRACE 4 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *data; 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *text; 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char next; 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} cstate; 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int _lex(cstate *cs, int value) 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char c; 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *s; 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *data; 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data = cs->data; 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(cs->next != 0) { 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c = cs->next; 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs->next = 0; 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto got_c; 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectrestart: 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(;;) { 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c = *data++; 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project got_c: 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(isspace(c)) continue; 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(c) { 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return T_EOF; 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* a sharp sign (#) starts a line comment and everything 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * behind that is ignored until the end of line 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case '#': 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(;;) { 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(*data) { 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs->data = data; 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return T_EOF; 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case '\n': 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs->data = data + 1; 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto restart; 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data++; 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case '.': 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs->data = data; 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return T_DOT; 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case '{': 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs->data = data; 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return T_OBRACE; 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case '}': 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs->data = data; 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return T_CBRACE; 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s = data - 1; 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(value) { 1984e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner /* if we're looking for a value, then take anything 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * until the end of line. note that sharp signs do 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * not start comments then. the result will be stripped 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * from trailing whitespace. 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(;;) { 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(*data == 0) { 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs->data = data; 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(*data == '\n') { 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs->data = data + 1; 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *data-- = 0; 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data++; 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* strip trailing whitespace */ 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while(data > s){ 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(!isspace(*data)) break; 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *data-- = 0; 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto got_text; 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* looking for a key name. we stop at whitspace, 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * EOF, of T_DOT/T_OBRACE/T_CBRACE characters. 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * note that the name can include sharp signs 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(;;) { 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(isspace(*data)) { 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *data = 0; 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs->data = data + 1; 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto got_text; 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(*data) { 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs->data = data; 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto got_text; 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case '.': 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case '{': 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case '}': 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs->next = *data; 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *data = 0; 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs->data = data + 1; 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto got_text; 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data++; 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectgot_text: 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs->text = s; 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return T_TEXT; 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar *TOKENNAMES[] = { "EOF", "TEXT", "DOT", "OBRACE", "CBRACE" }; 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int lex(cstate *cs, int value) 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int tok = _lex(cs, value); 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project printf("TOKEN(%d) %s %s\n", value, TOKENNAMES[tok], 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tok == T_TEXT ? cs->text : ""); 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return tok; 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define lex(cs,v) _lex(cs,v) 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int parse_expr(cstate *cs, AConfig *node); 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectparse_block(cstate *cs, AConfig *node) 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(;;){ 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(lex(cs, 0)){ 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case T_TEXT: 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(parse_expr(cs, node)) return -1; 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case T_CBRACE: 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectparse_expr(cstate *cs, AConfig *node) 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* last token was T_TEXT */ 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project node = _aconfig_find(node, cs->text, 1); 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(;;) { 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(lex(cs, 1)) { 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case T_DOT: 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(lex(cs, 0) != T_TEXT) return -1; 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project node = _aconfig_find(node, cs->text, 1); 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case T_TEXT: 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project node->value = cs->text; 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case T_OBRACE: 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return parse_block(cs, node); 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectaconfig_load(AConfig *root, char *data) 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(data != 0) { 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cstate cs; 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs.data = data; 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cs.next = 0; 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for(;;) { 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(lex(&cs, 0)){ 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case T_TEXT: 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(parse_expr(&cs, root)) return; 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectaconfig_load_file(AConfig *root, const char *fn) 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *data; 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data = path_load_file(fn, NULL); 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (data == NULL) 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project aconfig_load(root, data); 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char buff[1024]; 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* p; 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* end; 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd; 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} Writer; 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwriter_init( Writer* w, const char* fn ) 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project w->p = w->buff; 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project w->end = w->buff + sizeof(w->buff); 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project w->fd = creat( fn, 0755 ); 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (w->fd < 0) 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project _setmode( w->fd, _O_BINARY ); 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwriter_write( Writer* w, const char* src, int len ) 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (len > 0) { 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int avail = w->end - w->p; 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (avail > len) 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project avail = len; 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy( w->p, src, avail ); 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project src += avail; 3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len -= avail; 3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project w->p += avail; 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (w->p == w->end) { 390af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner if (HANDLE_EINTR(write(w->fd, w->buff, w->p - w->buff)) < 0) 3914e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner break; 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project w->p = w->buff; 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwriter_done( Writer* w ) 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4004e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner if (w->p > w->buff) { 401af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner HANDLE_EINTR(write(w->fd, w->buff, w->p - w->buff)); 4024e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner } 403af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner IGNORE_EINTR(close( w->fd )); 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwriter_margin( Writer* w, int margin) 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static const char spaces[10] = " "; 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (margin >= 10) { 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_write(w,spaces,10); 4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project margin -= 10; 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (margin > 0) 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_write(w,spaces,margin); 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwriter_c(Writer* w, char c) 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_write(w, &c, 1); 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwriter_str(Writer* w, const char* str) 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_write(w, str, strlen(str)); 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwriter_node(Writer* w, AConfig* node, int margin) 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_margin(w,margin); 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_str(w, node->name); 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_c(w,' '); 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (node->value[0]) { 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_str(w, node->value); 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_c(w,'\n'); 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AConfig* child; 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_c(w, '{'); 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_c(w, '\n'); 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (child = node->first_child; child; child = child->next) 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_node(w,child,margin+4); 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_margin(w,margin); 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_c(w,'}'); 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_c(w,'\n'); 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectaconfig_save_file(AConfig *root, const char *fn) 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AConfig* child; 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Writer w[1]; 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (writer_init(w,fn) < 0) 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (child = root->first_child; child; child = child->next) 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_node(w,child,0); 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project writer_done(w); 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 472