lcDB.c revision 6cc2b21f
11ab64890Smrg/* 21ab64890Smrg * 31ab64890Smrg * Copyright IBM Corporation 1993 41ab64890Smrg * 51ab64890Smrg * All Rights Reserved 61ab64890Smrg * 71ab64890Smrg * License to use, copy, modify, and distribute this software and its 81ab64890Smrg * documentation for any purpose and without fee is hereby granted, 91ab64890Smrg * provided that the above copyright notice appear in all copies and that 101ab64890Smrg * both that copyright notice and this permission notice appear in 111ab64890Smrg * supporting documentation, and that the name of IBM not be 121ab64890Smrg * used in advertising or publicity pertaining to distribution of the 131ab64890Smrg * software without specific, written prior permission. 141ab64890Smrg * 151ab64890Smrg * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 1661b2299dSmrg * ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND 171ab64890Smrg * NONINFRINGEMENT OF THIRD PARTY RIGHTS, IN NO EVENT SHALL 181ab64890Smrg * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 191ab64890Smrg * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 201ab64890Smrg * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 211ab64890Smrg * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 221ab64890Smrg * SOFTWARE. 231ab64890Smrg * 241ab64890Smrg*/ 251ab64890Smrg/* 261ab64890Smrg * (c) Copyright 1995 FUJITSU LIMITED 271ab64890Smrg * This is source code modified by FUJITSU LIMITED under the Joint 281ab64890Smrg * Development Agreement for the CDE/Motif PST. 291ab64890Smrg */ 301ab64890Smrg 311ab64890Smrg 321ab64890Smrg 331ab64890Smrg#ifndef NOT_X_ENV 341ab64890Smrg 351ab64890Smrg#ifdef HAVE_CONFIG_H 361ab64890Smrg#include <config.h> 371ab64890Smrg#endif 381ab64890Smrg#include <X11/Xlib.h> 391ab64890Smrg#include <X11/Xresource.h> 401ab64890Smrg#include "Xlibint.h" 411ab64890Smrg#include "XlcPubI.h" 421ab64890Smrg 431ab64890Smrg#else /* NOT_X_ENV */ 441ab64890Smrg 451ab64890Smrg#define Xmalloc malloc 461ab64890Smrg#define Xrealloc realloc 471ab64890Smrg#define Xfree free 481ab64890Smrg 491ab64890Smrg#endif /* NOT_X_ENV */ 501ab64890Smrg 511ab64890Smrg/* specifying NOT_X_ENV allows users to just use 521ab64890Smrg the database parsing routine. */ 531ab64890Smrg/* For UDC/VW */ 541ab64890Smrg#ifndef BUFSIZE 551ab64890Smrg#define BUFSIZE 2048 561ab64890Smrg#endif 571ab64890Smrg 581ab64890Smrg#ifdef COMMENT 591ab64890Smrg#ifdef BUFSIZE 601ab64890Smrg#undef BUFSIZE 611ab64890Smrg#endif 621ab64890Smrg#define BUFSIZE 6144 /* 2048*3 */ 631ab64890Smrg#endif 641ab64890Smrg 651ab64890Smrg#include <stdio.h> 661ab64890Smrg 671ab64890Smrgtypedef struct _DatabaseRec { 681ab64890Smrg char *category; 691ab64890Smrg char *name; 701ab64890Smrg char **value; 711ab64890Smrg int value_num; 721ab64890Smrg struct _DatabaseRec *next; 731ab64890Smrg} DatabaseRec, *Database; 741ab64890Smrg 751ab64890Smrgtypedef enum { 761ab64890Smrg S_NULL, /* outside category */ 771ab64890Smrg S_CATEGORY, /* inside category */ 781ab64890Smrg S_NAME, /* has name, expecting values */ 791ab64890Smrg S_VALUE 801ab64890Smrg} ParseState; 811ab64890Smrg 821ab64890Smrgtypedef enum { 831ab64890Smrg T_NEWLINE, 841ab64890Smrg T_COMMENT, 851ab64890Smrg T_SEMICOLON, 861ab64890Smrg T_DOUBLE_QUOTE, 871ab64890Smrg T_LEFT_BRACE, 881ab64890Smrg T_RIGHT_BRACE, 891ab64890Smrg T_SPACE, 901ab64890Smrg T_TAB, 911ab64890Smrg T_BACKSLASH, 921ab64890Smrg T_NUMERIC_HEX, 931ab64890Smrg T_NUMERIC_DEC, 941ab64890Smrg T_NUMERIC_OCT, 951ab64890Smrg T_DEFAULT 961ab64890Smrg} Token; 971ab64890Smrg 981ab64890Smrgtypedef struct { 991ab64890Smrg Token token; /* token id */ 1001ab64890Smrg int len; /* length of token sequence */ 1011ab64890Smrg} TokenTable; 1021ab64890Smrg 1031ab64890Smrgstatic int f_newline (const char *str, Token token, Database *db); 1041ab64890Smrgstatic int f_comment (const char *str, Token token, Database *db); 1051ab64890Smrgstatic int f_semicolon (const char *str, Token token, Database *db); 1061ab64890Smrgstatic int f_double_quote (const char *str, Token token, Database *db); 1071ab64890Smrgstatic int f_left_brace (const char *str, Token token, Database *db); 1081ab64890Smrgstatic int f_right_brace (const char *str, Token token, Database *db); 1091ab64890Smrgstatic int f_white (const char *str, Token token, Database *db); 1101ab64890Smrgstatic int f_backslash (const char *str, Token token, Database *db); 1111ab64890Smrgstatic int f_numeric (const char *str, Token token, Database *db); 1121ab64890Smrgstatic int f_default (const char *str, Token token, Database *db); 1131ab64890Smrg 1141ab64890Smrgstatic const TokenTable token_tbl[] = { 1151ab64890Smrg { T_NEWLINE, 1 }, 1161ab64890Smrg { T_COMMENT, 1 }, 1171ab64890Smrg { T_SEMICOLON, 1 }, 1181ab64890Smrg { T_DOUBLE_QUOTE, 1 }, 1191ab64890Smrg { T_LEFT_BRACE, 1 }, 1201ab64890Smrg { T_RIGHT_BRACE, 1 }, 1211ab64890Smrg { T_SPACE, 1 }, 1221ab64890Smrg { T_TAB, 1 }, 1231ab64890Smrg { T_BACKSLASH, 1 }, 1241ab64890Smrg { T_NUMERIC_HEX, 2 }, 1251ab64890Smrg { T_NUMERIC_DEC, 2 }, 1261ab64890Smrg { T_NUMERIC_OCT, 2 }, 1271ab64890Smrg { T_DEFAULT, 1 } /* any character */ 1281ab64890Smrg}; 1291ab64890Smrg 1301ab64890Smrg#define SYM_CR '\r' 1311ab64890Smrg#define SYM_NEWLINE '\n' 1321ab64890Smrg#define SYM_COMMENT '#' 1331ab64890Smrg#define SYM_SEMICOLON ';' 1341ab64890Smrg#define SYM_DOUBLE_QUOTE '"' 1351ab64890Smrg#define SYM_LEFT_BRACE '{' 1361ab64890Smrg#define SYM_RIGHT_BRACE '}' 1371ab64890Smrg#define SYM_SPACE ' ' 1381ab64890Smrg#define SYM_TAB '\t' 1391ab64890Smrg#define SYM_BACKSLASH '\\' 1401ab64890Smrg 1411ab64890Smrg/************************************************************************/ 1421ab64890Smrg 1431ab64890Smrg#define MAX_NAME_NEST 64 1441ab64890Smrg 1451ab64890Smrgtypedef struct { 1461ab64890Smrg ParseState pre_state; 1471ab64890Smrg char *category; 1481ab64890Smrg char *name[MAX_NAME_NEST]; 1491ab64890Smrg int nest_depth; 1501ab64890Smrg char **value; 1511ab64890Smrg int value_len; 1521ab64890Smrg int value_num; 1531ab64890Smrg int bufsize; /* bufMaxSize >= bufsize >= 0 */ 1541ab64890Smrg int bufMaxSize; /* default : BUFSIZE */ 1551ab64890Smrg char *buf; 1561ab64890Smrg} DBParseInfo; 1571ab64890Smrg 1581ab64890Smrgstatic DBParseInfo parse_info; 1591ab64890Smrg 1601ab64890Smrgstatic void 1611ab64890Smrginit_parse_info (void) 1621ab64890Smrg{ 1631ab64890Smrg static int allocated /* = 0 */; 1641ab64890Smrg char *ptr; 1651ab64890Smrg int size; 1661ab64890Smrg if (!allocated) { 1671ab64890Smrg bzero(&parse_info, sizeof(DBParseInfo)); 1681ab64890Smrg parse_info.buf = (char *)Xmalloc(BUFSIZE); 1691ab64890Smrg parse_info.bufMaxSize = BUFSIZE; 1701ab64890Smrg allocated = 1; 1711ab64890Smrg return; 1721ab64890Smrg } 1731ab64890Smrg ptr = parse_info.buf; 1741ab64890Smrg size = parse_info.bufMaxSize; 1751ab64890Smrg bzero(&parse_info, sizeof(DBParseInfo)); 1761ab64890Smrg parse_info.buf = ptr; 1771ab64890Smrg parse_info.bufMaxSize = size; 1781ab64890Smrg} 1791ab64890Smrg 1801ab64890Smrgstatic void 1811ab64890Smrgclear_parse_info (void) 1821ab64890Smrg{ 1831ab64890Smrg int i; 1841ab64890Smrg char *ptr; 1851ab64890Smrg int size; 1861ab64890Smrg parse_info.pre_state = S_NULL; 1871ab64890Smrg if (parse_info.category != NULL) { 1881ab64890Smrg Xfree(parse_info.category); 1891ab64890Smrg } 1901ab64890Smrg for (i = 0; i <= parse_info.nest_depth; ++i) { 1911ab64890Smrg if (parse_info.name[i]) { 1921ab64890Smrg Xfree(parse_info.name[i]); 1931ab64890Smrg } 1941ab64890Smrg } 1951ab64890Smrg if (parse_info.value) { 1961ab64890Smrg if (*parse_info.value) { 1971ab64890Smrg Xfree(*parse_info.value); 1981ab64890Smrg } 1991ab64890Smrg Xfree((char *)parse_info.value); 2001ab64890Smrg } 2011ab64890Smrg ptr = parse_info.buf; 2021ab64890Smrg size = parse_info.bufMaxSize; 2031ab64890Smrg bzero(&parse_info, sizeof(DBParseInfo)); 2041ab64890Smrg parse_info.buf = ptr; 2051ab64890Smrg parse_info.bufMaxSize = size; 2061ab64890Smrg} 2071ab64890Smrg 2081ab64890Smrgstatic Bool 2091ab64890Smrgrealloc_parse_info( 2101ab64890Smrg int len) 2111ab64890Smrg{ 2121ab64890Smrg char *p; 2131ab64890Smrg 2141ab64890Smrg parse_info.bufMaxSize = BUFSIZE * ((parse_info.bufsize + len)/BUFSIZE + 1); 2151ab64890Smrg p = (char *)Xrealloc(parse_info.buf, parse_info.bufMaxSize); 2161ab64890Smrg if (p == NULL) 2171ab64890Smrg return False; 2181ab64890Smrg parse_info.buf = p; 2191ab64890Smrg 2201ab64890Smrg return True; 2211ab64890Smrg} 2221ab64890Smrg 2231ab64890Smrg/************************************************************************/ 2241ab64890Smrg 2251ab64890Smrgtypedef struct _Line { 2261ab64890Smrg char *str; 2271ab64890Smrg int cursize; 2281ab64890Smrg int maxsize; 2291ab64890Smrg int seq; 2301ab64890Smrg} Line; 2311ab64890Smrg 2321ab64890Smrgstatic void 2331ab64890Smrgfree_line( 2341ab64890Smrg Line *line) 2351ab64890Smrg{ 2361ab64890Smrg if (line->str != NULL) { 2371ab64890Smrg Xfree(line->str); 2381ab64890Smrg } 2391ab64890Smrg bzero(line, sizeof(Line)); 2401ab64890Smrg} 2411ab64890Smrg 2421ab64890Smrgstatic int 2431ab64890Smrgrealloc_line( 2441ab64890Smrg Line *line, 2451ab64890Smrg int size) 2461ab64890Smrg{ 2471ab64890Smrg char *str = line->str; 2481ab64890Smrg 2491ab64890Smrg if (str != NULL) { 2501ab64890Smrg str = (char *)Xrealloc(str, size); 2511ab64890Smrg } else { 2521ab64890Smrg str = (char *)Xmalloc(size); 2531ab64890Smrg } 2541ab64890Smrg if (str == NULL) { 2551ab64890Smrg /* malloc error */ 2561ab64890Smrg if (line->str != NULL) { 2571ab64890Smrg Xfree(line->str); 2581ab64890Smrg } 2591ab64890Smrg bzero(line, sizeof(Line)); 2601ab64890Smrg return 0; 2611ab64890Smrg } 2621ab64890Smrg line->str = str; 2631ab64890Smrg line->maxsize = size; 2641ab64890Smrg return 1; 2651ab64890Smrg} 2661ab64890Smrg 2671ab64890Smrg#define iswhite(ch) ((ch) == SYM_SPACE || (ch) == SYM_TAB) 2681ab64890Smrg 2691ab64890Smrgstatic void 2701ab64890Smrgzap_comment( 2711ab64890Smrg char *str, 2721ab64890Smrg int *quoted) 2731ab64890Smrg{ 2741ab64890Smrg char *p = str; 2751ab64890Smrg#ifdef never 2761ab64890Smrg *quoted = 0; 2771ab64890Smrg if (*p == SYM_COMMENT) { 2781ab64890Smrg int len = strlen(str); 2791ab64890Smrg if (p[len - 1] == SYM_NEWLINE || p[len - 1] == SYM_CR) { 2801ab64890Smrg *p++ = SYM_NEWLINE; 2811ab64890Smrg } 2821ab64890Smrg *p = '\0'; 2831ab64890Smrg } 2841ab64890Smrg#else 2851ab64890Smrg while (*p) { 2861ab64890Smrg if (*p == SYM_DOUBLE_QUOTE) { 2871ab64890Smrg if (p == str || p[-1] != SYM_BACKSLASH) { 2881ab64890Smrg /* unescaped double quote changes quoted state. */ 2891ab64890Smrg *quoted = *quoted ? 0 : 1; 2901ab64890Smrg } 2911ab64890Smrg } 2921ab64890Smrg if (*p == SYM_COMMENT && !*quoted) { 2931ab64890Smrg int pos = p - str; 2941ab64890Smrg if (pos == 0 || 2951ab64890Smrg (iswhite(p[-1]) && (pos == 1 || p[-2] != SYM_BACKSLASH))) { 2961ab64890Smrg int len = strlen(p); 2971ab64890Smrg if (len > 0 && (p[len - 1] == SYM_NEWLINE || p[len-1] == SYM_CR)) { 2981ab64890Smrg /* newline is the identifier for finding end of value. 2991ab64890Smrg therefore, it should not be removed. */ 3001ab64890Smrg *p++ = SYM_NEWLINE; 3011ab64890Smrg } 3021ab64890Smrg *p = '\0'; 3031ab64890Smrg break; 3041ab64890Smrg } 3051ab64890Smrg } 3061ab64890Smrg ++p; 3071ab64890Smrg } 3081ab64890Smrg#endif 3091ab64890Smrg} 3101ab64890Smrg 3111ab64890Smrgstatic int 3121ab64890Smrgread_line( 3131ab64890Smrg FILE *fd, 3141ab64890Smrg Line *line) 3151ab64890Smrg{ 3161ab64890Smrg char buf[BUFSIZE], *p; 3171ab64890Smrg int len; 3181ab64890Smrg int quoted = 0; /* quoted by double quote? */ 3191ab64890Smrg char *str; 3201ab64890Smrg int cur; 3211ab64890Smrg 3221ab64890Smrg str = line->str; 3231ab64890Smrg cur = line->cursize = 0; 3241ab64890Smrg 3251ab64890Smrg while ((p = fgets(buf, BUFSIZE, fd)) != NULL) { 3261ab64890Smrg ++line->seq; 3271ab64890Smrg zap_comment(p, "ed); /* remove comment line */ 3281ab64890Smrg len = strlen(p); 3291ab64890Smrg if (len == 0) { 3301ab64890Smrg if (cur > 0) { 3311ab64890Smrg break; 3321ab64890Smrg } 3331ab64890Smrg continue; 3341ab64890Smrg } 3351ab64890Smrg if (cur + len + 1 > line->maxsize) { 3361ab64890Smrg /* need to reallocate buffer. */ 3371ab64890Smrg if (! realloc_line(line, line->maxsize + BUFSIZE)) { 3381ab64890Smrg return -1; /* realloc error. */ 3391ab64890Smrg } 3401ab64890Smrg str = line->str; 3411ab64890Smrg } 3421ab64890Smrg strncpy(str + cur, p, len); 3431ab64890Smrg 3441ab64890Smrg cur += len; 3451ab64890Smrg str[cur] = '\0'; 3461ab64890Smrg#ifdef __UNIXOS2__ /* Take out carriage returns under OS/2 */ 3471ab64890Smrg if (cur>1) { 3481ab64890Smrg if (str[cur-2] == '\r' && str[cur-1] == '\n') { 3491ab64890Smrg str[cur-2] = '\n'; 3501ab64890Smrg str[cur-1] = '\0'; 3511ab64890Smrg cur--; 3521ab64890Smrg } 3531ab64890Smrg } 3541ab64890Smrg#endif 3551ab64890Smrg if (!quoted && cur > 1 && str[cur - 2] == SYM_BACKSLASH && 3561ab64890Smrg (str[cur - 1] == SYM_NEWLINE || str[cur-1] == SYM_CR)) { 3571ab64890Smrg /* the line is ended backslash followed by newline. 3581ab64890Smrg need to concatinate the next line. */ 3591ab64890Smrg cur -= 2; 3601ab64890Smrg str[cur] = '\0'; 3611ab64890Smrg } else if (len < BUFSIZE - 1 || buf[len - 1] == SYM_NEWLINE || 3621ab64890Smrg buf[len - 1] == SYM_CR) { 3631ab64890Smrg /* the line is shorter than BUFSIZE. */ 3641ab64890Smrg break; 3651ab64890Smrg } 3661ab64890Smrg } 3671ab64890Smrg if (quoted) { 3681ab64890Smrg /* error. still in quoted state. */ 3691ab64890Smrg return -1; 3701ab64890Smrg } 3711ab64890Smrg return line->cursize = cur; 3721ab64890Smrg} 3731ab64890Smrg 3741ab64890Smrg/************************************************************************/ 3751ab64890Smrg 3761ab64890Smrgstatic Token 3771ab64890Smrgget_token( 3781ab64890Smrg const char *str) 3791ab64890Smrg{ 3801ab64890Smrg switch (*str) { 3811ab64890Smrg case SYM_NEWLINE: 3821ab64890Smrg case SYM_CR: return T_NEWLINE; 3831ab64890Smrg case SYM_COMMENT: return T_COMMENT; 3841ab64890Smrg case SYM_SEMICOLON: return T_SEMICOLON; 3851ab64890Smrg case SYM_DOUBLE_QUOTE: return T_DOUBLE_QUOTE; 3861ab64890Smrg case SYM_LEFT_BRACE: return T_LEFT_BRACE; 3871ab64890Smrg case SYM_RIGHT_BRACE: return T_RIGHT_BRACE; 3881ab64890Smrg case SYM_SPACE: return T_SPACE; 3891ab64890Smrg case SYM_TAB: return T_TAB; 3901ab64890Smrg case SYM_BACKSLASH: 3911ab64890Smrg switch (str[1]) { 3921ab64890Smrg case 'x': return T_NUMERIC_HEX; 3931ab64890Smrg case 'd': return T_NUMERIC_DEC; 3941ab64890Smrg case 'o': return T_NUMERIC_OCT; 3951ab64890Smrg } 3961ab64890Smrg return T_BACKSLASH; 3971ab64890Smrg default: 3981ab64890Smrg return T_DEFAULT; 3991ab64890Smrg } 4001ab64890Smrg} 4011ab64890Smrg 4021ab64890Smrgstatic int 4031ab64890Smrgget_word( 4041ab64890Smrg const char *str, 4051ab64890Smrg char *word) 4061ab64890Smrg{ 4071ab64890Smrg const char *p = str; 4081ab64890Smrg char *w = word; 4091ab64890Smrg Token token; 4101ab64890Smrg int token_len; 4111ab64890Smrg 4121ab64890Smrg while (*p != '\0') { 4131ab64890Smrg token = get_token(p); 4141ab64890Smrg token_len = token_tbl[token].len; 4151ab64890Smrg if (token == T_BACKSLASH) { 4161ab64890Smrg p += token_len; 4171ab64890Smrg if (*p == '\0') 4181ab64890Smrg break; 4191ab64890Smrg token = get_token(p); 4201ab64890Smrg token_len = token_tbl[token].len; 4211ab64890Smrg } else if (token != T_COMMENT && token != T_DEFAULT) { 4221ab64890Smrg break; 4231ab64890Smrg } 4241ab64890Smrg strncpy(w, p, token_len); 4251ab64890Smrg p += token_len; w += token_len; 4261ab64890Smrg } 4271ab64890Smrg *w = '\0'; 4281ab64890Smrg return p - str; /* return number of scanned chars */ 4291ab64890Smrg} 4301ab64890Smrg 4311ab64890Smrgstatic int 4321ab64890Smrgget_quoted_word( 4331ab64890Smrg const char *str, 4341ab64890Smrg char *word) 4351ab64890Smrg{ 4361ab64890Smrg const char *p = str; 4371ab64890Smrg char *w = word; 4381ab64890Smrg Token token; 4391ab64890Smrg int token_len; 4401ab64890Smrg 4411ab64890Smrg if (*p == SYM_DOUBLE_QUOTE) { 4421ab64890Smrg ++p; 4431ab64890Smrg } 4441ab64890Smrg while (*p != '\0') { 4451ab64890Smrg token = get_token(p); 4461ab64890Smrg token_len = token_tbl[token].len; 4471ab64890Smrg if (token == T_DOUBLE_QUOTE) { 4481ab64890Smrg p += token_len; 4491ab64890Smrg goto found; 4501ab64890Smrg } 4511ab64890Smrg if (token == T_BACKSLASH) { 4521ab64890Smrg p += token_len; 4531ab64890Smrg if (*p == '\0') { 4541ab64890Smrg break; 4551ab64890Smrg } 4561ab64890Smrg token = get_token(p); 4571ab64890Smrg token_len = token_tbl[token].len; 4581ab64890Smrg } 4591ab64890Smrg strncpy(w, p, token_len); 4601ab64890Smrg p += token_len; w += token_len; 4611ab64890Smrg } 4621ab64890Smrg /* error. cannot detect next double quote */ 4631ab64890Smrg return 0; 4641ab64890Smrg 4651ab64890Smrg found:; 4661ab64890Smrg *w = '\0'; 4671ab64890Smrg return p - str; 4681ab64890Smrg} 4691ab64890Smrg 4701ab64890Smrg/************************************************************************/ 4711ab64890Smrg 4721ab64890Smrgstatic int 4731ab64890Smrgappend_value_list (void) 4741ab64890Smrg{ 4751ab64890Smrg char **value_list = parse_info.value; 4761ab64890Smrg char *value; 4771ab64890Smrg int value_num = parse_info.value_num; 4781ab64890Smrg int value_len = parse_info.value_len; 4791ab64890Smrg char *str = parse_info.buf; 4801ab64890Smrg int len = parse_info.bufsize; 4811ab64890Smrg char *p; 4821ab64890Smrg 4831ab64890Smrg if (len < 1) { 4841ab64890Smrg return 1; /* return with no error */ 4851ab64890Smrg } 4861ab64890Smrg 4871ab64890Smrg if (value_list == (char **)NULL) { 4881ab64890Smrg value_list = (char **)Xmalloc(sizeof(char *) * 2); 4891ab64890Smrg *value_list = NULL; 4901ab64890Smrg } else { 4911ab64890Smrg char **prev_list = value_list; 4921ab64890Smrg 4931ab64890Smrg value_list = (char **) 4941ab64890Smrg Xrealloc(value_list, sizeof(char *) * (value_num + 2)); 4951ab64890Smrg if (value_list == NULL) { 4961ab64890Smrg Xfree(prev_list); 4971ab64890Smrg } 4981ab64890Smrg } 4991ab64890Smrg if (value_list == (char **)NULL) 5001ab64890Smrg goto err2; 5011ab64890Smrg 5021ab64890Smrg value = *value_list; 5031ab64890Smrg if (value == NULL) { 5041ab64890Smrg value = (char *)Xmalloc(value_len + len + 1); 5051ab64890Smrg } else { 5061ab64890Smrg char *prev_value = value; 5071ab64890Smrg 5081ab64890Smrg value = (char *)Xrealloc(value, value_len + len + 1); 5091ab64890Smrg if (value == NULL) { 5101ab64890Smrg Xfree(prev_value); 5111ab64890Smrg } 5121ab64890Smrg } 5131ab64890Smrg if (value == NULL) { 5141ab64890Smrg goto err1; 5151ab64890Smrg } 5161ab64890Smrg if (value != *value_list) { 5171ab64890Smrg int i; 5181ab64890Smrg ssize_t delta; 5191ab64890Smrg delta = value - *value_list; 5201ab64890Smrg *value_list = value; 5211ab64890Smrg for (i = 1; i < value_num; ++i) { 5221ab64890Smrg value_list[i] += delta; 5231ab64890Smrg } 5241ab64890Smrg } 5251ab64890Smrg 5261ab64890Smrg value_list[value_num] = p = &value[value_len]; 5271ab64890Smrg value_list[value_num + 1] = NULL; 5281ab64890Smrg strncpy(p, str, len); 5291ab64890Smrg p[len] = 0; 5301ab64890Smrg 5311ab64890Smrg parse_info.value = value_list; 5321ab64890Smrg parse_info.value_num = value_num + 1; 5331ab64890Smrg parse_info.value_len = value_len + len + 1; 5341ab64890Smrg parse_info.bufsize = 0; 5351ab64890Smrg return 1; 5361ab64890Smrg 5371ab64890Smrg err1: 5381ab64890Smrg if (value_list) { 5391ab64890Smrg Xfree((char **)value_list); 5401ab64890Smrg } 5411ab64890Smrg if (value) { 5421ab64890Smrg Xfree(value); 5431ab64890Smrg } 5441ab64890Smrg err2: 5451ab64890Smrg parse_info.value = (char **)NULL; 5461ab64890Smrg parse_info.value_num = 0; 5471ab64890Smrg parse_info.value_len = 0; 5481ab64890Smrg parse_info.bufsize = 0; 5491ab64890Smrg return 0; 5501ab64890Smrg} 5511ab64890Smrg 55261b2299dSmrgstatic int 5531ab64890Smrgconstruct_name( 5541ab64890Smrg char *name, 5551ab64890Smrg int size) 5561ab64890Smrg{ 5571ab64890Smrg int i; 5581ab64890Smrg int len = 0; 5591ab64890Smrg char *p = name; 5601ab64890Smrg 5611ab64890Smrg for (i = 0; i <= parse_info.nest_depth; ++i) { 5621ab64890Smrg len += strlen(parse_info.name[i]) + 1; 5631ab64890Smrg } 5641ab64890Smrg if (len >= size) 5651ab64890Smrg return 0; 5661ab64890Smrg 5671ab64890Smrg strcpy(p, parse_info.name[0]); 5681ab64890Smrg p += strlen(parse_info.name[0]); 5691ab64890Smrg for (i = 1; i <= parse_info.nest_depth; ++i) { 5701ab64890Smrg *p++ = '.'; 5711ab64890Smrg strcpy(p, parse_info.name[i]); 5721ab64890Smrg p += strlen(parse_info.name[i]); 5731ab64890Smrg } 5741ab64890Smrg return *name != '\0'; 5751ab64890Smrg} 5761ab64890Smrg 5771ab64890Smrgstatic int 5781ab64890Smrgstore_to_database( 5791ab64890Smrg Database *db) 5801ab64890Smrg{ 5811ab64890Smrg Database new = (Database)NULL; 5821ab64890Smrg char name[BUFSIZE]; 5831ab64890Smrg 5841ab64890Smrg if (parse_info.pre_state == S_VALUE) { 5851ab64890Smrg if (! append_value_list()) { 5861ab64890Smrg goto err; 5871ab64890Smrg } 5881ab64890Smrg } 5891ab64890Smrg 5901ab64890Smrg if (parse_info.name[parse_info.nest_depth] == NULL) { 5911ab64890Smrg goto err; 5921ab64890Smrg } 5931ab64890Smrg 5946cc2b21fSmrg new = Xcalloc(1, sizeof(DatabaseRec)); 5951ab64890Smrg if (new == (Database)NULL) { 5961ab64890Smrg goto err; 5971ab64890Smrg } 5981ab64890Smrg 5996cc2b21fSmrg new->category = strdup(parse_info.category); 6001ab64890Smrg if (new->category == NULL) { 6011ab64890Smrg goto err; 6021ab64890Smrg } 6031ab64890Smrg 6041ab64890Smrg if (! construct_name(name, sizeof(name))) { 6051ab64890Smrg goto err; 6061ab64890Smrg } 6076cc2b21fSmrg new->name = strdup(name); 6081ab64890Smrg if (new->name == NULL) { 6091ab64890Smrg goto err; 6101ab64890Smrg } 6111ab64890Smrg new->next = *db; 6121ab64890Smrg new->value = parse_info.value; 6131ab64890Smrg new->value_num = parse_info.value_num; 6141ab64890Smrg *db = new; 6151ab64890Smrg 6161ab64890Smrg Xfree(parse_info.name[parse_info.nest_depth]); 6171ab64890Smrg parse_info.name[parse_info.nest_depth] = NULL; 6181ab64890Smrg 6191ab64890Smrg parse_info.value = (char **)NULL; 6201ab64890Smrg parse_info.value_num = 0; 6211ab64890Smrg parse_info.value_len = 0; 6221ab64890Smrg 6231ab64890Smrg return 1; 6241ab64890Smrg 6251ab64890Smrg err: 6261ab64890Smrg if (new) { 6271ab64890Smrg if (new->category) { 6281ab64890Smrg Xfree(new->category); 6291ab64890Smrg } 6301ab64890Smrg if (new->name) { 6311ab64890Smrg Xfree(new->name); 6321ab64890Smrg } 6331ab64890Smrg Xfree(new); 6341ab64890Smrg } 6351ab64890Smrg if (parse_info.value) { 6361ab64890Smrg if (*parse_info.value) { 6371ab64890Smrg Xfree(*parse_info.value); 6381ab64890Smrg } 6391ab64890Smrg Xfree((char **)parse_info.value); 6401ab64890Smrg parse_info.value = (char **)NULL; 6411ab64890Smrg parse_info.value_num = 0; 6421ab64890Smrg parse_info.value_len = 0; 6431ab64890Smrg } 6441ab64890Smrg return 0; 6451ab64890Smrg} 6461ab64890Smrg 6471ab64890Smrg#define END_MARK "END" 6481ab64890Smrg#define END_MARK_LEN 3 /*strlen(END_MARK)*/ 6491ab64890Smrg 6501ab64890Smrgstatic int 6511ab64890Smrgcheck_category_end( 6521ab64890Smrg const char *str) 6531ab64890Smrg{ 6541ab64890Smrg const char *p; 6551ab64890Smrg int len; 6561ab64890Smrg 6571ab64890Smrg p = str; 6581ab64890Smrg if (strncmp(p, END_MARK, END_MARK_LEN)) { 6591ab64890Smrg return 0; 6601ab64890Smrg } 6611ab64890Smrg p += END_MARK_LEN; 6621ab64890Smrg 6631ab64890Smrg while (iswhite(*p)) { 6641ab64890Smrg ++p; 6651ab64890Smrg } 6661ab64890Smrg len = strlen(parse_info.category); 6671ab64890Smrg if (strncmp(p, parse_info.category, len)) { 6681ab64890Smrg return 0; 6691ab64890Smrg } 6701ab64890Smrg p += len; 6711ab64890Smrg return p - str; 6721ab64890Smrg} 6731ab64890Smrg 6741ab64890Smrg/************************************************************************/ 6751ab64890Smrg 6761ab64890Smrgstatic int 6771ab64890Smrgf_newline( 6781ab64890Smrg const char *str, 6791ab64890Smrg Token token, 6801ab64890Smrg Database *db) 6811ab64890Smrg{ 6821ab64890Smrg switch (parse_info.pre_state) { 6831ab64890Smrg case S_NULL: 6841ab64890Smrg case S_CATEGORY: 6851ab64890Smrg break; 6861ab64890Smrg case S_NAME: 6871ab64890Smrg return 0; /* no value */ 6881ab64890Smrg case S_VALUE: 6891ab64890Smrg if (!store_to_database(db)) 6901ab64890Smrg return 0; 6911ab64890Smrg parse_info.pre_state = S_CATEGORY; 6921ab64890Smrg break; 6931ab64890Smrg default: 6941ab64890Smrg return 0; 6951ab64890Smrg } 6961ab64890Smrg return token_tbl[token].len; 6971ab64890Smrg} 6981ab64890Smrg 6991ab64890Smrgstatic int 7001ab64890Smrgf_comment( 7011ab64890Smrg const char *str, 7021ab64890Smrg Token token, 7031ab64890Smrg Database *db) 7041ab64890Smrg{ 7051ab64890Smrg /* NOTE: comment is already handled in read_line(), 7061ab64890Smrg so this function is not necessary. */ 7071ab64890Smrg 7081ab64890Smrg const char *p = str; 7091ab64890Smrg 7101ab64890Smrg while (*p != SYM_NEWLINE && *p != SYM_CR && *p != '\0') { 7111ab64890Smrg ++p; /* zap to the end of line */ 7121ab64890Smrg } 7131ab64890Smrg return p - str; 7141ab64890Smrg} 7151ab64890Smrg 7161ab64890Smrgstatic int 7171ab64890Smrgf_white( 7181ab64890Smrg const char *str, 7191ab64890Smrg Token token, 7201ab64890Smrg Database *db) 7211ab64890Smrg{ 7221ab64890Smrg const char *p = str; 7231ab64890Smrg 7241ab64890Smrg while (iswhite(*p)) { 7251ab64890Smrg ++p; 7261ab64890Smrg } 7271ab64890Smrg return p - str; 7281ab64890Smrg} 7291ab64890Smrg 7301ab64890Smrgstatic int 7311ab64890Smrgf_semicolon( 7321ab64890Smrg const char *str, 7331ab64890Smrg Token token, 7341ab64890Smrg Database *db) 7351ab64890Smrg{ 7361ab64890Smrg switch (parse_info.pre_state) { 7371ab64890Smrg case S_NULL: 7381ab64890Smrg case S_CATEGORY: 7391ab64890Smrg case S_NAME: 7401ab64890Smrg return 0; 7411ab64890Smrg case S_VALUE: 7421ab64890Smrg if (! append_value_list()) 7431ab64890Smrg return 0; 7441ab64890Smrg parse_info.pre_state = S_VALUE; 7451ab64890Smrg break; 7461ab64890Smrg default: 7471ab64890Smrg return 0; 7481ab64890Smrg } 7491ab64890Smrg return token_tbl[token].len; 7501ab64890Smrg} 7511ab64890Smrg 7521ab64890Smrgstatic int 7531ab64890Smrgf_left_brace( 7541ab64890Smrg const char *str, 7551ab64890Smrg Token token, 7561ab64890Smrg Database *db) 7571ab64890Smrg{ 7581ab64890Smrg switch (parse_info.pre_state) { 7591ab64890Smrg case S_NULL: 7601ab64890Smrg case S_CATEGORY: 7611ab64890Smrg case S_VALUE: 7621ab64890Smrg return 0; 7631ab64890Smrg case S_NAME: 7641ab64890Smrg if (parse_info.name[parse_info.nest_depth] == NULL 7651ab64890Smrg || parse_info.nest_depth + 1 > MAX_NAME_NEST) 7661ab64890Smrg return 0; 7671ab64890Smrg ++parse_info.nest_depth; 7681ab64890Smrg parse_info.pre_state = S_CATEGORY; 7691ab64890Smrg break; 7701ab64890Smrg default: 7711ab64890Smrg return 0; 7721ab64890Smrg } 7731ab64890Smrg return token_tbl[token].len; 7741ab64890Smrg} 7751ab64890Smrg 7761ab64890Smrgstatic int 7771ab64890Smrgf_right_brace( 7781ab64890Smrg const char *str, 7791ab64890Smrg Token token, 7801ab64890Smrg Database *db) 7811ab64890Smrg{ 7821ab64890Smrg if (parse_info.nest_depth < 1) 7831ab64890Smrg return 0; 7841ab64890Smrg 7851ab64890Smrg switch (parse_info.pre_state) { 7861ab64890Smrg case S_NULL: 7871ab64890Smrg case S_NAME: 7881ab64890Smrg return 0; 7891ab64890Smrg case S_VALUE: 7901ab64890Smrg if (! store_to_database(db)) 7911ab64890Smrg return 0; 7921ab64890Smrg /* fall into next case */ 7931ab64890Smrg case S_CATEGORY: 7941ab64890Smrg if (parse_info.name[parse_info.nest_depth] != NULL) { 7951ab64890Smrg Xfree(parse_info.name[parse_info.nest_depth]); 7961ab64890Smrg parse_info.name[parse_info.nest_depth] = NULL; 7971ab64890Smrg } 7981ab64890Smrg --parse_info.nest_depth; 7991ab64890Smrg parse_info.pre_state = S_CATEGORY; 8001ab64890Smrg break; 8011ab64890Smrg default: 8021ab64890Smrg return 0; 8031ab64890Smrg } 8041ab64890Smrg return token_tbl[token].len; 8051ab64890Smrg} 8061ab64890Smrg 8071ab64890Smrgstatic int 8081ab64890Smrgf_double_quote( 8091ab64890Smrg const char *str, 8101ab64890Smrg Token token, 8111ab64890Smrg Database *db) 8121ab64890Smrg{ 8131ab64890Smrg char word[BUFSIZE]; 8141ab64890Smrg char* wordp; 8151ab64890Smrg int len; 8161ab64890Smrg 8171ab64890Smrg if ((len = strlen (str)) < sizeof word) 8181ab64890Smrg wordp = word; 8191ab64890Smrg else 8201ab64890Smrg wordp = Xmalloc (len + 1); 8211ab64890Smrg if (wordp == NULL) 8221ab64890Smrg return 0; 8231ab64890Smrg 8241ab64890Smrg len = 0; 8251ab64890Smrg switch (parse_info.pre_state) { 8261ab64890Smrg case S_NULL: 8271ab64890Smrg case S_CATEGORY: 8281ab64890Smrg goto err; 8291ab64890Smrg case S_NAME: 8301ab64890Smrg case S_VALUE: 8311ab64890Smrg len = get_quoted_word(str, wordp); 8321ab64890Smrg if (len < 1) 8331ab64890Smrg goto err; 83461b2299dSmrg if ((parse_info.bufsize + (int)strlen(wordp) + 1) 8351ab64890Smrg >= parse_info.bufMaxSize) { 8361ab64890Smrg if (realloc_parse_info(strlen(wordp)+1) == False) { 8371ab64890Smrg goto err; 8381ab64890Smrg } 8391ab64890Smrg } 8401ab64890Smrg strcpy(&parse_info.buf[parse_info.bufsize], wordp); 8411ab64890Smrg parse_info.bufsize += strlen(wordp); 8421ab64890Smrg parse_info.pre_state = S_VALUE; 8431ab64890Smrg break; 8441ab64890Smrg default: 8451ab64890Smrg goto err; 8461ab64890Smrg } 8471ab64890Smrg if (wordp != word) 8481ab64890Smrg Xfree (wordp); 8491ab64890Smrg return len; /* including length of token */ 8501ab64890Smrg 8511ab64890Smrgerr: 8521ab64890Smrg if (wordp != word) 8531ab64890Smrg Xfree (wordp); 8541ab64890Smrg return 0; 8551ab64890Smrg} 8561ab64890Smrg 8571ab64890Smrgstatic int 8581ab64890Smrgf_backslash( 8591ab64890Smrg const char *str, 8601ab64890Smrg Token token, 8611ab64890Smrg Database *db) 8621ab64890Smrg{ 8631ab64890Smrg return f_default(str, token, db); 8641ab64890Smrg} 8651ab64890Smrg 8661ab64890Smrgstatic int 8671ab64890Smrgf_numeric( 8681ab64890Smrg const char *str, 8691ab64890Smrg Token token, 8701ab64890Smrg Database *db) 8711ab64890Smrg{ 8721ab64890Smrg char word[BUFSIZE]; 8731ab64890Smrg const char *p; 8741ab64890Smrg char* wordp; 8751ab64890Smrg int len; 8761ab64890Smrg int token_len; 8771ab64890Smrg 8781ab64890Smrg if ((len = strlen (str)) < sizeof word) 8791ab64890Smrg wordp = word; 8801ab64890Smrg else 8811ab64890Smrg wordp = Xmalloc (len + 1); 8821ab64890Smrg if (wordp == NULL) 8831ab64890Smrg return 0; 8841ab64890Smrg 8851ab64890Smrg switch (parse_info.pre_state) { 8861ab64890Smrg case S_NULL: 8871ab64890Smrg case S_CATEGORY: 8881ab64890Smrg goto err; 8891ab64890Smrg case S_NAME: 8901ab64890Smrg case S_VALUE: 8911ab64890Smrg token_len = token_tbl[token].len; 8921ab64890Smrg p = str + token_len; 8931ab64890Smrg len = get_word(p, wordp); 8941ab64890Smrg if (len < 1) 8951ab64890Smrg goto err; 89661b2299dSmrg if ((parse_info.bufsize + token_len + (int)strlen(wordp) + 1) 8971ab64890Smrg >= parse_info.bufMaxSize) { 8981ab64890Smrg if (realloc_parse_info(token_len + strlen(wordp) + 1) == False) 8991ab64890Smrg goto err; 9001ab64890Smrg } 9011ab64890Smrg strncpy(&parse_info.buf[parse_info.bufsize], str, token_len); 9021ab64890Smrg strcpy(&parse_info.buf[parse_info.bufsize + token_len], wordp); 9031ab64890Smrg parse_info.bufsize += token_len + strlen(wordp); 9041ab64890Smrg parse_info.pre_state = S_VALUE; 9051ab64890Smrg break; 9061ab64890Smrg default: 9071ab64890Smrg goto err; 9081ab64890Smrg } 9091ab64890Smrg if (wordp != word) 9101ab64890Smrg Xfree (wordp); 9111ab64890Smrg return len + token_len; 9121ab64890Smrg 9131ab64890Smrgerr: 9141ab64890Smrg if (wordp != word) 9151ab64890Smrg Xfree (wordp); 9161ab64890Smrg return 0; 9171ab64890Smrg} 9181ab64890Smrg 9191ab64890Smrgstatic int 9201ab64890Smrgf_default( 9211ab64890Smrg const char *str, 9221ab64890Smrg Token token, 9231ab64890Smrg Database *db) 9241ab64890Smrg{ 9251ab64890Smrg char word[BUFSIZE], *p; 9261ab64890Smrg char* wordp; 9271ab64890Smrg int len; 9281ab64890Smrg 9291ab64890Smrg if ((len = strlen (str)) < sizeof word) 9301ab64890Smrg wordp = word; 9311ab64890Smrg else 9321ab64890Smrg wordp = Xmalloc (len + 1); 9331ab64890Smrg if (wordp == NULL) 9341ab64890Smrg return 0; 9351ab64890Smrg 9361ab64890Smrg len = get_word(str, wordp); 9371ab64890Smrg if (len < 1) 9381ab64890Smrg goto err; 9391ab64890Smrg 9401ab64890Smrg switch (parse_info.pre_state) { 9411ab64890Smrg case S_NULL: 9421ab64890Smrg if (parse_info.category != NULL) 9431ab64890Smrg goto err; 9446cc2b21fSmrg p = strdup(wordp); 9451ab64890Smrg if (p == NULL) 9461ab64890Smrg goto err; 9471ab64890Smrg parse_info.category = p; 9481ab64890Smrg parse_info.pre_state = S_CATEGORY; 9491ab64890Smrg break; 9501ab64890Smrg case S_CATEGORY: 9511ab64890Smrg if (parse_info.nest_depth == 0) { 9521ab64890Smrg if (check_category_end(str)) { 9531ab64890Smrg /* end of category is detected. 9541ab64890Smrg clear context and zap to end of this line */ 9551ab64890Smrg clear_parse_info(); 9561ab64890Smrg len = strlen(str); 9571ab64890Smrg break; 9581ab64890Smrg } 9591ab64890Smrg } 9606cc2b21fSmrg p = strdup(wordp); 9611ab64890Smrg if (p == NULL) 9621ab64890Smrg goto err; 9631ab64890Smrg if (parse_info.name[parse_info.nest_depth] != NULL) { 9641ab64890Smrg Xfree(parse_info.name[parse_info.nest_depth]); 9651ab64890Smrg } 9661ab64890Smrg parse_info.name[parse_info.nest_depth] = p; 9671ab64890Smrg parse_info.pre_state = S_NAME; 9681ab64890Smrg break; 9691ab64890Smrg case S_NAME: 9701ab64890Smrg case S_VALUE: 97161b2299dSmrg if ((parse_info.bufsize + (int)strlen(wordp) + 1) 9721ab64890Smrg >= parse_info.bufMaxSize) { 9731ab64890Smrg if (realloc_parse_info(strlen(wordp) + 1) == False) 9741ab64890Smrg goto err; 9751ab64890Smrg } 9761ab64890Smrg strcpy(&parse_info.buf[parse_info.bufsize], wordp); 9771ab64890Smrg parse_info.bufsize += strlen(wordp); 9781ab64890Smrg parse_info.pre_state = S_VALUE; 9791ab64890Smrg break; 9801ab64890Smrg default: 9811ab64890Smrg goto err; 9821ab64890Smrg } 9831ab64890Smrg if (wordp != word) 9841ab64890Smrg Xfree (wordp); 9851ab64890Smrg return len; 9861ab64890Smrg 9871ab64890Smrgerr: 9881ab64890Smrg if (wordp != word) 9891ab64890Smrg Xfree (wordp); 9901ab64890Smrg return 0; 9911ab64890Smrg} 9921ab64890Smrg 9931ab64890Smrg/************************************************************************/ 9941ab64890Smrg 9951ab64890Smrg#ifdef DEBUG 9961ab64890Smrgstatic void 9971ab64890SmrgPrintDatabase( 9981ab64890Smrg Database db) 9991ab64890Smrg{ 10001ab64890Smrg Database p = db; 10011ab64890Smrg int i = 0, j; 10021ab64890Smrg 10031ab64890Smrg printf("***\n*** BEGIN Database\n***\n"); 10041ab64890Smrg while (p) { 10051ab64890Smrg printf("%3d: ", i++); 10061ab64890Smrg printf("%s, %s, ", p->category, p->name); 10071ab64890Smrg printf("\t[%d: ", p->value_num); 10081ab64890Smrg for (j = 0; j < p->value_num; ++j) { 10091ab64890Smrg printf("%s, ", p->value[j]); 10101ab64890Smrg } 10111ab64890Smrg printf("]\n"); 10121ab64890Smrg p = p->next; 10131ab64890Smrg } 10141ab64890Smrg printf("***\n*** END Database\n***\n"); 10151ab64890Smrg} 10161ab64890Smrg#endif 10171ab64890Smrg 10181ab64890Smrgstatic void 10191ab64890SmrgDestroyDatabase( 10201ab64890Smrg Database db) 10211ab64890Smrg{ 10221ab64890Smrg Database p = db; 10231ab64890Smrg 10241ab64890Smrg while (p) { 10251ab64890Smrg if (p->category != NULL) { 10261ab64890Smrg Xfree(p->category); 10271ab64890Smrg } 10281ab64890Smrg if (p->name != NULL) { 10291ab64890Smrg Xfree(p->name); 10301ab64890Smrg } 10311ab64890Smrg if (p->value != (char **)NULL) { 10321ab64890Smrg if (*p->value != NULL) { 10331ab64890Smrg Xfree(*p->value); 10341ab64890Smrg } 10351ab64890Smrg Xfree((char *)p->value); 10361ab64890Smrg } 10371ab64890Smrg db = p->next; 10381ab64890Smrg Xfree((char *)p); 10391ab64890Smrg p = db; 10401ab64890Smrg } 10411ab64890Smrg} 10421ab64890Smrg 10431ab64890Smrgstatic int 10441ab64890SmrgCountDatabase( 10451ab64890Smrg Database db) 10461ab64890Smrg{ 10471ab64890Smrg Database p = db; 10481ab64890Smrg int cnt = 0; 10491ab64890Smrg 10501ab64890Smrg while (p) { 10511ab64890Smrg ++cnt; 10521ab64890Smrg p = p->next; 10531ab64890Smrg } 10541ab64890Smrg return cnt; 10551ab64890Smrg} 10561ab64890Smrg 10571ab64890Smrgstatic Database 10581ab64890SmrgCreateDatabase( 10591ab64890Smrg char *dbfile) 10601ab64890Smrg{ 10611ab64890Smrg Database db = (Database)NULL; 10621ab64890Smrg FILE *fd; 10631ab64890Smrg Line line; 10641ab64890Smrg char *p; 10651ab64890Smrg Token token; 10661ab64890Smrg int len; 10671ab64890Smrg int error = 0; 10681ab64890Smrg 10691ab64890Smrg fd = _XFopenFile(dbfile, "r"); 10701ab64890Smrg if (fd == (FILE *)NULL) 10711ab64890Smrg return NULL; 10721ab64890Smrg 10731ab64890Smrg bzero(&line, sizeof(Line)); 10741ab64890Smrg init_parse_info(); 10751ab64890Smrg 10761ab64890Smrg do { 10771ab64890Smrg int rc = read_line(fd, &line); 10781ab64890Smrg if (rc < 0) { 10791ab64890Smrg error = 1; 10801ab64890Smrg break; 10811ab64890Smrg } else if (rc == 0) { 10821ab64890Smrg break; 10831ab64890Smrg } 10841ab64890Smrg p = line.str; 10851ab64890Smrg while (*p) { 10861ab64890Smrg int (*parse_proc)(const char *str, Token token, Database *db) = NULL; 10871ab64890Smrg 10881ab64890Smrg token = get_token(p); 10891ab64890Smrg 10901ab64890Smrg switch (token_tbl[token].token) { 10911ab64890Smrg case T_NEWLINE: 10921ab64890Smrg parse_proc = f_newline; 10931ab64890Smrg break; 10941ab64890Smrg case T_COMMENT: 10951ab64890Smrg parse_proc = f_comment; 10961ab64890Smrg break; 10971ab64890Smrg case T_SEMICOLON: 10981ab64890Smrg parse_proc = f_semicolon; 10991ab64890Smrg break; 11001ab64890Smrg case T_DOUBLE_QUOTE: 11011ab64890Smrg parse_proc = f_double_quote; 11021ab64890Smrg break; 11031ab64890Smrg case T_LEFT_BRACE: 11041ab64890Smrg parse_proc = f_left_brace; 11051ab64890Smrg break; 11061ab64890Smrg case T_RIGHT_BRACE: 11071ab64890Smrg parse_proc = f_right_brace; 11081ab64890Smrg break; 11091ab64890Smrg case T_SPACE: 11101ab64890Smrg case T_TAB: 11111ab64890Smrg parse_proc = f_white; 11121ab64890Smrg break; 11131ab64890Smrg case T_BACKSLASH: 11141ab64890Smrg parse_proc = f_backslash; 11151ab64890Smrg break; 11161ab64890Smrg case T_NUMERIC_HEX: 11171ab64890Smrg case T_NUMERIC_DEC: 11181ab64890Smrg case T_NUMERIC_OCT: 11191ab64890Smrg parse_proc = f_numeric; 11201ab64890Smrg break; 11211ab64890Smrg case T_DEFAULT: 11221ab64890Smrg parse_proc = f_default; 11231ab64890Smrg break; 11241ab64890Smrg } 11251ab64890Smrg 11261ab64890Smrg len = parse_proc(p, token, &db); 11271ab64890Smrg 11281ab64890Smrg if (len < 1) { 11291ab64890Smrg error = 1; 11301ab64890Smrg break; 11311ab64890Smrg } 11321ab64890Smrg p += len; 11331ab64890Smrg } 11341ab64890Smrg } while (!error); 11351ab64890Smrg 11361ab64890Smrg if (parse_info.pre_state != S_NULL) { 11371ab64890Smrg clear_parse_info(); 11381ab64890Smrg error = 1; 11391ab64890Smrg } 11401ab64890Smrg if (error) { 11411ab64890Smrg#ifdef DEBUG 11421ab64890Smrg fprintf(stderr, "database format error at line %d.\n", line.seq); 11431ab64890Smrg#endif 11441ab64890Smrg DestroyDatabase(db); 11451ab64890Smrg db = (Database)NULL; 11461ab64890Smrg } 11471ab64890Smrg 11481ab64890Smrg fclose(fd); 11491ab64890Smrg free_line(&line); 11501ab64890Smrg 11511ab64890Smrg#ifdef DEBUG 11521ab64890Smrg PrintDatabase(db); 11531ab64890Smrg#endif 11541ab64890Smrg 11551ab64890Smrg return db; 11561ab64890Smrg} 11571ab64890Smrg 11581ab64890Smrg/************************************************************************/ 11591ab64890Smrg 11601ab64890Smrg#ifndef NOT_X_ENV 11611ab64890Smrg 11621ab64890Smrg/* locale framework functions */ 11631ab64890Smrg 11641ab64890Smrgtypedef struct _XlcDatabaseRec { 11651ab64890Smrg XrmQuark category_q; 11661ab64890Smrg XrmQuark name_q; 11671ab64890Smrg Database db; 11681ab64890Smrg struct _XlcDatabaseRec *next; 11691ab64890Smrg} XlcDatabaseRec, *XlcDatabase; 11701ab64890Smrg 11711ab64890Smrgtypedef struct _XlcDatabaseListRec { 11721ab64890Smrg XrmQuark name_q; 11731ab64890Smrg XlcDatabase lc_db; 11741ab64890Smrg Database database; 11751ab64890Smrg int ref_count; 11761ab64890Smrg struct _XlcDatabaseListRec *next; 11771ab64890Smrg} XlcDatabaseListRec, *XlcDatabaseList; 11781ab64890Smrg 11791ab64890Smrg/* database cache list (per file) */ 11801ab64890Smrgstatic XlcDatabaseList _db_list = (XlcDatabaseList)NULL; 11811ab64890Smrg 11821ab64890Smrg/************************************************************************/ 11831ab64890Smrg/* _XlcGetResource(lcd, category, class, value, count) */ 11841ab64890Smrg/*----------------------------------------------------------------------*/ 11851ab64890Smrg/* This function retrieves XLocale database information. */ 11861ab64890Smrg/************************************************************************/ 11871ab64890Smrgvoid 11881ab64890Smrg_XlcGetResource( 11891ab64890Smrg XLCd lcd, 11901ab64890Smrg const char *category, 11911ab64890Smrg const char *class, 11921ab64890Smrg char ***value, 11931ab64890Smrg int *count) 11941ab64890Smrg{ 11951ab64890Smrg XLCdPublicMethodsPart *methods = XLC_PUBLIC_METHODS(lcd); 11961ab64890Smrg 11971ab64890Smrg (*methods->get_resource)(lcd, category, class, value, count); 11981ab64890Smrg return; 11991ab64890Smrg} 12001ab64890Smrg 12011ab64890Smrg/************************************************************************/ 12021ab64890Smrg/* _XlcGetLocaleDataBase(lcd, category, class, value, count) */ 12031ab64890Smrg/*----------------------------------------------------------------------*/ 12041ab64890Smrg/* This function retrieves XLocale database information. */ 12051ab64890Smrg/************************************************************************/ 12061ab64890Smrgvoid 12071ab64890Smrg_XlcGetLocaleDataBase( 12081ab64890Smrg XLCd lcd, 12091ab64890Smrg const char *category, 12101ab64890Smrg const char *name, 12111ab64890Smrg char ***value, 12121ab64890Smrg int *count) 12131ab64890Smrg{ 12141ab64890Smrg XlcDatabase lc_db = (XlcDatabase)XLC_PUBLIC(lcd, xlocale_db); 12151ab64890Smrg XrmQuark category_q, name_q; 12161ab64890Smrg 12171ab64890Smrg category_q = XrmStringToQuark(category); 12181ab64890Smrg name_q = XrmStringToQuark(name); 12191ab64890Smrg for (; lc_db->db; ++lc_db) { 12201ab64890Smrg if (category_q == lc_db->category_q && name_q == lc_db->name_q) { 12211ab64890Smrg *value = lc_db->db->value; 12221ab64890Smrg *count = lc_db->db->value_num; 12231ab64890Smrg return; 12241ab64890Smrg } 12251ab64890Smrg } 12261ab64890Smrg *value = (char **)NULL; 12271ab64890Smrg *count = 0; 12281ab64890Smrg} 12291ab64890Smrg 12301ab64890Smrg/************************************************************************/ 12311ab64890Smrg/* _XlcDestroyLocaleDataBase(lcd) */ 12321ab64890Smrg/*----------------------------------------------------------------------*/ 12331ab64890Smrg/* This function destroy the XLocale Database that bound to the */ 12341ab64890Smrg/* specified lcd. If the XLocale Database is refered from some */ 12351ab64890Smrg/* other lcd, this function just decreases reference count of */ 12361ab64890Smrg/* the database. If no locale refers the database, this function */ 12371ab64890Smrg/* remove it from the cache list and free work area. */ 12381ab64890Smrg/************************************************************************/ 12391ab64890Smrgvoid 12401ab64890Smrg_XlcDestroyLocaleDataBase( 12411ab64890Smrg XLCd lcd) 12421ab64890Smrg{ 12431ab64890Smrg XlcDatabase lc_db = (XlcDatabase)XLC_PUBLIC(lcd, xlocale_db); 12441ab64890Smrg XlcDatabaseList p, prev; 12451ab64890Smrg 12461ab64890Smrg for (p = _db_list, prev = (XlcDatabaseList)NULL; p; 12471ab64890Smrg prev = p, p = p->next) { 12481ab64890Smrg if (p->lc_db == lc_db) { 12491ab64890Smrg if ((-- p->ref_count) < 1) { 12501ab64890Smrg if (p->lc_db != (XlcDatabase)NULL) { 12511ab64890Smrg Xfree((char *)p->lc_db); 12521ab64890Smrg } 12531ab64890Smrg DestroyDatabase(p->database); 12541ab64890Smrg if (prev == (XlcDatabaseList)NULL) { 12551ab64890Smrg _db_list = p->next; 12561ab64890Smrg } else { 12571ab64890Smrg prev->next = p->next; 12581ab64890Smrg } 12591ab64890Smrg Xfree((char*)p); 12601ab64890Smrg } 12611ab64890Smrg break; 12621ab64890Smrg } 12631ab64890Smrg } 12641ab64890Smrg XLC_PUBLIC(lcd, xlocale_db) = (XPointer)NULL; 12651ab64890Smrg} 12661ab64890Smrg 12671ab64890Smrg/************************************************************************/ 12681ab64890Smrg/* _XlcCreateLocaleDataBase(lcd) */ 12691ab64890Smrg/*----------------------------------------------------------------------*/ 12701ab64890Smrg/* This function create an XLocale database which correspond to */ 12711ab64890Smrg/* the specified XLCd. */ 12721ab64890Smrg/************************************************************************/ 12731ab64890SmrgXPointer 12741ab64890Smrg_XlcCreateLocaleDataBase( 12751ab64890Smrg XLCd lcd) 12761ab64890Smrg{ 12771ab64890Smrg XlcDatabaseList list, new; 12781ab64890Smrg Database p, database = (Database)NULL; 12791ab64890Smrg XlcDatabase lc_db = (XlcDatabase)NULL; 12801ab64890Smrg XrmQuark name_q; 12811ab64890Smrg char *name; 12821ab64890Smrg int i, n; 12831ab64890Smrg 12841ab64890Smrg name = _XlcFileName(lcd, "locale"); 12851ab64890Smrg if (name == NULL) 12861ab64890Smrg return (XPointer)NULL; 12871ab64890Smrg 12881ab64890Smrg#ifndef __UNIXOS2__ 12891ab64890Smrg name_q = XrmStringToQuark(name); 12901ab64890Smrg#else 12911ab64890Smrg name_q = XrmStringToQuark((char*)__XOS2RedirRoot(name)); 12921ab64890Smrg#endif 12931ab64890Smrg for (list = _db_list; list; list = list->next) { 12941ab64890Smrg if (name_q == list->name_q) { 12951ab64890Smrg list->ref_count++; 12961ab64890Smrg Xfree (name); 12971ab64890Smrg return XLC_PUBLIC(lcd, xlocale_db) = (XPointer)list->lc_db; 12981ab64890Smrg } 12991ab64890Smrg } 13001ab64890Smrg 13011ab64890Smrg database = CreateDatabase(name); 13021ab64890Smrg if (database == (Database)NULL) { 13031ab64890Smrg Xfree (name); 13041ab64890Smrg return (XPointer)NULL; 13051ab64890Smrg } 13061ab64890Smrg n = CountDatabase(database); 13076cc2b21fSmrg lc_db = Xcalloc(n + 1, sizeof(XlcDatabaseRec)); 13081ab64890Smrg if (lc_db == (XlcDatabase)NULL) 13091ab64890Smrg goto err; 13101ab64890Smrg for (p = database, i = 0; p && i < n; p = p->next, ++i) { 13111ab64890Smrg lc_db[i].category_q = XrmStringToQuark(p->category); 13121ab64890Smrg lc_db[i].name_q = XrmStringToQuark(p->name); 13131ab64890Smrg lc_db[i].db = p; 13141ab64890Smrg } 13151ab64890Smrg 13161ab64890Smrg new = (XlcDatabaseList)Xmalloc(sizeof(XlcDatabaseListRec)); 13171ab64890Smrg if (new == (XlcDatabaseList)NULL) { 13181ab64890Smrg goto err; 13191ab64890Smrg } 13201ab64890Smrg new->name_q = name_q; 13211ab64890Smrg new->lc_db = lc_db; 13221ab64890Smrg new->database = database; 13231ab64890Smrg new->ref_count = 1; 13241ab64890Smrg new->next = _db_list; 13251ab64890Smrg _db_list = new; 13261ab64890Smrg 13271ab64890Smrg Xfree (name); 13281ab64890Smrg return XLC_PUBLIC(lcd, xlocale_db) = (XPointer)lc_db; 13291ab64890Smrg 13301ab64890Smrg err: 13311ab64890Smrg DestroyDatabase(database); 13321ab64890Smrg if (lc_db != (XlcDatabase)NULL) { 13331ab64890Smrg Xfree((char *)lc_db); 13341ab64890Smrg } 13351ab64890Smrg Xfree (name); 13361ab64890Smrg return (XPointer)NULL; 13371ab64890Smrg} 13381ab64890Smrg 13391ab64890Smrg#endif /* NOT_X_ENV */ 1340