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