18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 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 "android/utils/ini.h"
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h>
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <limits.h>
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <errno.h>
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/debug.h"
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/system.h" /* for ASTRDUP */
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/bufprint.h"
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "osdep.h"
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* W() is used to print warnings, D() to print debugging info */
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  W(...)   dwarning(__VA_ARGS__)
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  D(...)   VERBOSE_PRINT(avd_config,__VA_ARGS__)
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* a simple .ini file parser and container for Android
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * no sections support. see android/utils/ini.h for
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * more details on the supported file format.
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct {
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*  key;
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*  value;
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} IniPair;
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct IniFile {
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int       numPairs;
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int       maxPairs;
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    IniPair*  pairs;
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectiniFile_free( IniFile*  i )
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn;
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; nn < i->numPairs; nn++) {
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        AFREE(i->pairs[nn].key);
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        i->pairs[nn].key   = NULL;
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        i->pairs[nn].value = NULL;
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    AFREE(i->pairs);
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    AFREE(i);
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic IniFile*
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectiniFile_alloc( void )
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    IniFile*  i;
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ANEW0(i);
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return i;
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
65622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' TurneriniPair_init( IniPair* pair, const char* key, int keyLen,
66622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner                             const char* value, int valueLen )
67622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner{
68622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    AARRAY_NEW(pair->key, keyLen + valueLen + 2);
69622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    memcpy(pair->key, key, keyLen);
70622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    pair->key[keyLen] = 0;
71622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
72622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    pair->value = pair->key + keyLen + 1;
73622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    memcpy(pair->value, value, valueLen);
74622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    pair->value[valueLen] = 0;
75622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner}
76622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
77622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turnerstatic void
78622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' TurneriniPair_replaceValue( IniPair* pair, const char* value )
79622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner{
80622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    char* key      = pair->key;
81622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    int   keyLen   = strlen(key);
82622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    int   valueLen = strlen(value);
83622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
84622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    iniPair_init(pair, key, keyLen, value, valueLen);
85622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    AFREE(key);
86622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner}
87622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
88622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turnerstatic void
89622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' TurneriniFile_addPair( IniFile*  i,
90622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner                 const char*  key,   int  keyLen,
91622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner                 const char*  value, int  valueLen )
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    IniPair*  pair;
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (i->numPairs >= i->maxPairs) {
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int       oldMax = i->maxPairs;
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int       newMax = oldMax + (oldMax >> 1) + 4;
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        AARRAY_RENEW(i->pairs, newMax);
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        i->maxPairs = newMax;
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pair = i->pairs + i->numPairs;
104622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    iniPair_init(pair, key, keyLen, value, valueLen);
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    i->numPairs += 1;
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
109622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turnerstatic IniPair*
110622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' TurneriniFile_getPair( IniFile* i, const char* key )
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (i && key) {
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  nn;
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (nn = 0; nn < i->numPairs; nn++) {
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!strcmp(i->pairs[nn].key,key))
117622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner                return &i->pairs[nn];
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return NULL;
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
123622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turnerconst char*
124622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' TurneriniFile_getValue( IniFile*  i, const char*  key )
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
126622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    IniPair* pair = iniFile_getPair(i, key);
127622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    if (pair)
128622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        return pair->value;
129622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    else
130622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        return NULL;
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
133622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turnerint
134622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' TurneriniFile_getPairCount( IniFile*  i )
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
136622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    return i ? i->numPairs : 0;
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* NOTE: we avoid using <ctype.h> functions to avoid locale-specific
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *       behaviour that can be the source of strange bugs.
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const char*
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectskipSpaces( const char* p )
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (*p == ' ' || *p == '\t')
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p ++;
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return p;
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const char*
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectskipToEOL( const char*  p )
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (*p && (*p != '\n' && *p != '\r'))
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p ++;
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (*p) {
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p ++;
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (p[-1] == '\r' && p[0] == '\n')
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p ++;
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return p;
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectisKeyStartChar( int  c )
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ((unsigned)(c-'a') < 26 ||
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            (unsigned)(c-'A') < 26 ||
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            c == '_');
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectisKeyChar( int  c )
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return isKeyStartChar(c) || ((unsigned)(c-'0') < 10) || (c == '.') || (c == '-');
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectIniFile*
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectiniFile_newFromMemory( const char*  text, const char*  fileName )
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*  p      = text;
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    IniFile*     ini    = iniFile_alloc();
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int          lineno = 0;
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!fileName)
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fileName = "<memoryFile>";
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    D("%s: parsing as .ini file", fileName);
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (*p) {
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const char*  key;
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int          keyLen;
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        const char*  value;
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int          valueLen;
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        lineno += 1;
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* skip leading whitespace */
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p = skipSpaces(p);
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* skip comments and empty lines */
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (*p == 0 || *p == ';' || *p == '#' || *p == '\n' || *p == '\r') {
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = skipToEOL(p);
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            continue;
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* check the key name */
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        key = p++;
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!isKeyStartChar(*key)) {
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = skipToEOL(p);
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            W("%4d: key name doesn't start with valid character. line ignored",
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              lineno);
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            continue;
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (isKeyChar(*p))
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p++;
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        keyLen = p - key;
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p      = skipSpaces(p);
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* check the equal */
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (*p != '=') {
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            W("%4d: missing expected assignment operator (=). line ignored",
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              lineno);
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = skipToEOL(p);
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            continue;
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p += 1;
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* skip spaces before the value */
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p     = skipSpaces(p);
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        value = p;
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* find the value */
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (*p && (*p != '\n' && *p != '\r'))
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p += 1;
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* remove trailing spaces */
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (p > value && (p[-1] == ' ' || p[-1] == '\t'))
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p --;
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        valueLen = p - value;
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        iniFile_addPair(ini, key, keyLen, value, valueLen);
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D("%4d: KEY='%.*s' VALUE='%.*s'", lineno,
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          keyLen, key, valueLen, value);
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p = skipToEOL(p);
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    D("%s: parsing finished", fileName);
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ini;
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectIniFile*
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectiniFile_newFromFile( const char*  filepath )
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    FILE*        fp = fopen(filepath, "rt");
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*        text;
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    long         size;
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    IniFile*     ini = NULL;
2654e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner    size_t       len;
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (fp == NULL) {
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D("could not open .ini file: %s: %s",
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          filepath, strerror(errno));
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fseek(fp, 0, SEEK_END);
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    size = ftell(fp);
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fseek(fp, 0, SEEK_SET);
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* avoid reading a very large file that was passed by mistake
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * this threshold is quite liberal.
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     */
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  MAX_INI_FILE_SIZE  655360
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (size < 0 || size > MAX_INI_FILE_SIZE) {
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        W("hardware configuration file '%s' too large (%ld bytes)",
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          filepath, size);
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto EXIT;
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* read the file, add a sentinel at the end of it */
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    AARRAY_NEW(text, size+1);
2904e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner    len = fread(text, 1, size, fp);
2914e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner    text[len] = 0;
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ini = iniFile_newFromMemory(text, filepath);
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    AFREE(text);
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectEXIT:
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fclose(fp);
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ini;
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
301db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine/* Common routine for saving IniFile instance to the given file.
302db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine * Param:
303db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine *  f - IniFile instance to save.
304db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine *  filepath - Path to a file where to save the instance.
305db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine *  strip - If 1, ignore (don't save) pairs with empty values. If 0, save all
306db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine *      pairs found in the IniFile instance, including the ones that contain
307db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine *      empty values.
308db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine * Returns:
309db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine *  0 on success, -1 on error (see errno for error code)
310db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine */
311db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkinestatic int
312db450d73092add519efddcd6d55c7a0e7541ec70Vladimir ChtchetkineiniFile_saveToFileCommon( IniFile*  f, const char*  filepath, int strip )
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    FILE*  fp = fopen(filepath, "wt");
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    IniPair*  pair    = f->pairs;
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    IniPair*  pairEnd = pair + f->numPairs;
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int       result  = 0;
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (fp == NULL) {
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D("could not create .ini file: %s: %s",
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          filepath, strerror(errno));
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for ( ; pair < pairEnd; pair++ ) {
326db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine        if ((pair->value && *pair->value) || !strip) {
327db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine            char  temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
328db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine            p = bufprint(temp, end, "%s = %s\n", pair->key, pair->value);
329db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine            if (fwrite(temp, p - temp, 1, fp) != 1) {
330db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine                result = -1;
331db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine                break;
332db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine            }
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fclose(fp);
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
340db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkineint
341db450d73092add519efddcd6d55c7a0e7541ec70Vladimir ChtchetkineiniFile_saveToFile( IniFile*  f, const char*  filepath )
342db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine{
343db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine    return iniFile_saveToFileCommon(f, filepath, 0);
344db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine}
345db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine
346db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkineint
347db450d73092add519efddcd6d55c7a0e7541ec70Vladimir ChtchetkineiniFile_saveToFileClean( IniFile*  f, const char*  filepath )
348db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine{
349db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine    return iniFile_saveToFileCommon(f, filepath, 1);
350db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine}
351db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine
352db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkineint
353db450d73092add519efddcd6d55c7a0e7541ec70Vladimir ChtchetkineiniFile_getEntry(IniFile* f, int index, char** key, char** value)
354db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine{
355db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine    if (index >= f->numPairs) {
356db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine        D("Index %d exceeds the number of ini file entries %d",
357db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine          index, f->numPairs);
358db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine        return -1;
359db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine    }
360db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine
361db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine    *key = ASTRDUP(f->pairs[index].key);
362db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine    *value = ASTRDUP(f->pairs[index].value);
363db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine
364db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine    return 0;
365db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine}
366db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar*
36859e8e1969c6543cc9375b1a4372ef2e3e8afa183David 'Digit' TurneriniFile_getString( IniFile*  f, const char*  key, const char* defaultValue )
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*  val = iniFile_getValue(f, key);
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37259e8e1969c6543cc9375b1a4372ef2e3e8afa183David 'Digit' Turner    if (!val) {
37359e8e1969c6543cc9375b1a4372ef2e3e8afa183David 'Digit' Turner        if (!defaultValue)
37459e8e1969c6543cc9375b1a4372ef2e3e8afa183David 'Digit' Turner            return NULL;
37559e8e1969c6543cc9375b1a4372ef2e3e8afa183David 'Digit' Turner        val= defaultValue;
37659e8e1969c6543cc9375b1a4372ef2e3e8afa183David 'Digit' Turner    }
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ASTRDUP(val);
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectiniFile_getInteger( IniFile*  f, const char*  key, int  defaultValue )
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*  valueStr = iniFile_getValue(f, key);
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int          value    = defaultValue;
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (valueStr != NULL) {
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char*  end;
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        long   l = strtol(valueStr, &end, 10);
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (end != NULL && end[0] == 0 && (int)l == l)
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            value = l;
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return value;
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdouble
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectiniFile_getDouble( IniFile*  f, const char*  key, double  defaultValue )
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*  valueStr = iniFile_getValue(f, key);
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    double       value    = defaultValue;
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (valueStr != NULL) {
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char*   end;
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        double  d = strtod(valueStr, &end);
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (end != NULL && end[0] == 0)
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            value = d;
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return value;
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectiniFile_getBoolean( IniFile*  f, const char*  key, const char*  defaultValue )
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*  value  = iniFile_getValue(f, key);
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!value)
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        value = defaultValue;
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!strcmp(value,"1")    ||
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        !strcmp(value,"yes")  ||
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        !strcmp(value,"YES")  ||
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        !strcmp(value,"true") ||
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        !strcmp(value,"TRUE"))
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint64_t
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectiniFile_getDiskSize( IniFile*  f, const char*  key, const char*  defaultValue )
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*  valStr = iniFile_getValue(f, key);
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t      value  = 0;
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!valStr)
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        valStr = defaultValue;
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (valStr != NULL) {
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char*  end;
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        value = strtoll(valStr, &end, 10);
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (*end == 'k' || *end == 'K')
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            value *= 1024ULL;
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else if (*end == 'm' || *end == 'M')
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            value *= 1024*1024ULL;
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else if (*end == 'g' || *end == 'G')
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            value *= 1024*1024*1024ULL;
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return value;
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint64_t
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectiniFile_getInt64( IniFile*  f, const char*  key, int64_t  defaultValue )
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*  valStr = iniFile_getValue(f, key);
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t      value  = defaultValue;
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (valStr != NULL) {
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char*    end;
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int64_t  d;
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        d = strtoll(valStr, &end, 10);
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (end != NULL && end[0] == 0)
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            value = d;
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return value;
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
471622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turnervoid
472622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' TurneriniFile_setValue( IniFile* f, const char* key, const char* value )
473622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner{
474622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    IniPair* pair;
475622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
476622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    if (f == NULL || key == NULL || value == NULL)
477622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        return;
478622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
479622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    pair = iniFile_getPair(f, key);
480622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    if (pair != NULL) {
481622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        iniPair_replaceValue(pair, value);
482622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    } else {
483622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        iniFile_addPair(f, key, strlen(key), value, strlen(value));
484622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    }
485622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner}
486622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
487622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turnervoid
488622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' TurneriniFile_setInteger( IniFile* f, const char* key, int value )
489622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner{
490622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    char temp[16];
491622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    snprintf(temp, sizeof temp, "%d", value);
492622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    iniFile_setValue(f, key, temp);
493622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner}
494622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
495622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turnervoid
496622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' TurneriniFile_setInt64( IniFile* f, const char* key, int64_t value )
497622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner{
498622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    char temp[32];
499622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    snprintf(temp, sizeof temp, "%" PRId64, value);
500622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    iniFile_setValue(f, key, temp);
501622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner}
502622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
503622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turnervoid
504622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' TurneriniFile_setDouble( IniFile* f, const char* key, double value )
505622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner{
506622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    char temp[32];
507622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    snprintf(temp, sizeof temp, "%g", value);
508622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    iniFile_setValue(f, key, temp);
509622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner}
510622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
511622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turnervoid
512622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' TurneriniFile_setBoolean( IniFile* f, const char* key, int value )
513622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner{
514622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    iniFile_setValue(f, key, value ? "yes" : "no");
515622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner}
516622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
517622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turnervoid
518622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' TurneriniFile_setDiskSize( IniFile* f, const char* key, int64_t size )
519622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner{
520622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    char     temp[32];
521622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    int64_t  divisor = 0;
522e85871f98fe50edd8135e5ce8aff04c3ad518d1aDavid 'Digit' Turner    const int64_t  kilo = 1024;
523e85871f98fe50edd8135e5ce8aff04c3ad518d1aDavid 'Digit' Turner    const int64_t  mega = 1024*kilo;
524e85871f98fe50edd8135e5ce8aff04c3ad518d1aDavid 'Digit' Turner    const int64_t  giga = 1024*mega;
525622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    char     suffix = '\0';
526622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
527e85871f98fe50edd8135e5ce8aff04c3ad518d1aDavid 'Digit' Turner    if (size >= giga && !(size % giga)) {
528e85871f98fe50edd8135e5ce8aff04c3ad518d1aDavid 'Digit' Turner        divisor = giga;
529e85871f98fe50edd8135e5ce8aff04c3ad518d1aDavid 'Digit' Turner        suffix = 'g';
530e85871f98fe50edd8135e5ce8aff04c3ad518d1aDavid 'Digit' Turner    }
531e85871f98fe50edd8135e5ce8aff04c3ad518d1aDavid 'Digit' Turner    else if (size >= mega && !(size % mega)) {
532e85871f98fe50edd8135e5ce8aff04c3ad518d1aDavid 'Digit' Turner        divisor = mega;
533e85871f98fe50edd8135e5ce8aff04c3ad518d1aDavid 'Digit' Turner        suffix  = 'm';
534e85871f98fe50edd8135e5ce8aff04c3ad518d1aDavid 'Digit' Turner    }
535e85871f98fe50edd8135e5ce8aff04c3ad518d1aDavid 'Digit' Turner    else if (size >= kilo && !(size % kilo)) {
536e85871f98fe50edd8135e5ce8aff04c3ad518d1aDavid 'Digit' Turner        divisor = kilo;
537e85871f98fe50edd8135e5ce8aff04c3ad518d1aDavid 'Digit' Turner        suffix = 'k';
538622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    }
539622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    if (divisor) {
540622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        snprintf(temp, sizeof temp, "%" PRId64 "%c", size/divisor, suffix);
541622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    } else {
542622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        snprintf(temp, sizeof temp, "%" PRId64, size);
543622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    }
544622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    iniFile_setValue(f, key, temp);
545622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner}
546