4
* Time-stamp: "2010-12-16 14:03:06 bkorb"
4
* Time-stamp: "2011-04-06 09:31:24 bkorb"
6
6
* configuration/rc/ini file handling.
8
8
* This file is part of AutoOpts, a companion to AutoGen.
9
9
* AutoOpts is free software.
10
* AutoOpts is Copyright (c) 1992-2010 by Bruce Korb - all rights reserved
10
* AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved
12
12
* AutoOpts is available under any one of two licenses. The license
13
13
* in use must be one of these two and the choice is under the control
52
52
handle_section(tOptions * pOpts, char * pzText);
55
parse_xml_encoding(char ** ppz);
58
trim_xml_text(char * pztxt, char const * pznm, tOptionLoadMode mode);
61
cook_xml_text(char * pzData);
55
64
handle_struct(tOptions * pOpts, tOptState * pOS, char * pzText, int dir);
653
662
size_t name_len = strlen(pOpts->pzProgName);
655
664
memcpy(ttl, ttlfmt, sizeof(ttlfmt) - 1);
656
strcpy(ttl + sizeof(ttlfmt) - 1, zCfgProg);
665
memcpy(ttl + sizeof(ttlfmt) - 1, zCfgProg, ttl_len - (sizeof(ttlfmt) - 1));
659
668
while (IS_WHITESPACE_CHAR(*++pzText)) ;
722
* parse XML encodings
725
parse_xml_encoding(char ** ppz)
737
_xmlNm_(space, ' ') \
742
char const * const nm_str;
743
unsigned short nm_len;
745
} const xml_names[] = {
746
# define _xmlNm_(_n, _v) { #_n ";", sizeof(#_n), _v },
752
static int const nm_ct = sizeof(xml_names) / sizeof(xml_names[0]);
762
if (IS_DEC_DIGIT_CHAR(*pz)) {
769
* Some forms specify hex with: &#xNN;
777
*  is hex and  is decimal. Cool.
785
v = strtoul(pz, &pz, base);
786
if ((*pz != ';') || (v > 0x7F))
795
if (strncmp(pz, xml_names[ix].nm_str, xml_names[ix].nm_len)
797
*ppz = pz + xml_names[ix].nm_len;
798
return xml_names[ix].nm_val;
800
} while (++ix < nm_ct);
807
* Find the end marker for the named section of XML.
808
* Trim that text there, trimming trailing white space for all modes
809
* except for OPTION_LOAD_UNCOOKED.
812
trim_xml_text(char * pztxt, char const * pznm, tOptionLoadMode mode)
814
static char const fmt[] = "</%s>";
816
size_t len = strlen(pznm) + sizeof(fmt) - 2 /* for %s */;
819
pz = AGALOC(len, "scan name");
821
sprintf(pz, fmt, pznm);
823
pztxt = strstr(pztxt, pz);
824
if (pz != z) AGFREE(pz);
829
if (mode != OPTION_LOAD_UNCOOKED)
830
while (IS_WHITESPACE_CHAR(pztxt[-1])) len++, pztxt--;
833
return pztxt + len - 1 /* for NUL byte */;
839
cook_xml_text(char * pzData)
847
int ch = ((int)*(pzs++)) & 0xFF;
855
ch = parse_xml_encoding(&pzs);
863
if ((bf[0] == NUL) || (bf[1] == NUL)) {
868
ch = strtoul(bf, NULL, 16);
714
878
* "pzText" points to a '<' character, followed by an alpha.
764
928
*pcNulPoint = NUL;
765
929
pzData = ++pzText;
768
* Find the end of the option text and NUL terminate it
772
size_t len = strlen(pzName) + 4;
774
pz = AGALOC(len, "scan name");
776
sprintf(pz, "</%s>", pzName);
778
pzText = strstr(pzText, pz);
779
if (pz != z) AGFREE(pz);
930
pzText = trim_xml_text(pzText, pzName, mode);
790
935
* Rejoin the name and value for parsing by "loadOptionLine()".
793
938
memset(pcNulPoint, ' ', pzData - pcNulPoint);
796
* If we are getting a "string" value, the process the XML-ish
797
* %XX hex characters.
941
* If we are getting a "string" value that is to be cooked,
942
* then process the XML-ish &xx; XML-ish and %XX hex characters.
799
if (valu.valType == OPARG_TYPE_STRING) {
800
char * pzSrc = pzData;
801
char * pzDst = pzData;
806
int ch = ((int)*(pzSrc++)) & 0xFF;
808
case NUL: goto string_fixup_done;
813
if ((bf[0] == NUL) || (bf[1] == NUL))
814
goto string_fixup_done;
815
ch = strtoul(bf, NULL, 16);
821
} string_fixup_done:;
944
if ( (valu.valType == OPARG_TYPE_STRING)
945
&& (mode == OPTION_LOAD_COOKED))
946
cook_xml_text(pzData);
826
949
* "pzName" points to what looks like text for one option/configurable.
904
1027
if (S_ISDIR(StatBuf.st_mode)) {
905
1028
size_t len = strlen(zFileName);
1029
size_t nln = strlen(pOpts->pzRcName) + 1;
1030
char * pz = zFileName + len;
908
if (len + 1 + strlen(pOpts->pzRcName) >= sizeof(zFileName))
1032
if (len + 1 + nln >= sizeof(zFileName))
911
pz = zFileName + len;
912
1035
if (pz[-1] != DIRCH)
913
1036
*(pz++) = DIRCH;
914
strcpy(pz, pOpts->pzRcName);
1037
memcpy(pz, pOpts->pzRcName, nln);
917
1040
file_preset(pOpts, zFileName, inc);
1239
1362
&& ( (pOpts->structVersion > OPTIONS_STRUCT_VERSION )
1240
1363
|| (pOpts->structVersion < OPTIONS_MINIMUM_VERSION )
1365
static char const aover[] =
1366
__STR(AO_CURRENT)":"__STR(AO_REVISION)":"__STR(AO_AGE)"\n";
1243
1368
fprintf(stderr, zAO_Err, pzProgram, NUM_TO_VER(pOpts->structVersion));
1244
1369
if (pOpts->structVersion > OPTIONS_STRUCT_VERSION )
1247
1372
fputs(zAO_Sml, stderr);
1249
fputs(ShellAsString(AO_CURRENT) ":"
1250
ShellAsString(AO_REVISION) ":"
1251
ShellAsString(AO_AGE) "\n", stderr);
1374
fwrite(aover, sizeof(aover) - 1, 1, stderr);
1252
1375
return FAILURE;