00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <stdbool.h>
00033 #include <string.h>
00034 #include <stdarg.h>
00035 #include <libgen.h>
00036 #include "qDecoder.h"
00037 #include "qInternal.h"
00038
00039 #define _INCLUDE_DIRECTIVE "@INCLUDE "
00040
00041 static char *_parseVariable(Q_ENTRY *config, char *value);
00042
00067 Q_ENTRY *qConfigParseFile(Q_ENTRY *config, const char *filepath, char sepchar) {
00068 char *str = qFileLoad(filepath, NULL);
00069 if (str == NULL) return NULL;
00070
00071
00072 char *strp = str;;
00073 while ((strp = strstr(strp, _INCLUDE_DIRECTIVE)) != NULL) {
00074 if (strp == str || strp[-1] == '\n') {
00075 char buf[MAX_PATHLEN];
00076
00077
00078 char *tmpp;
00079 for (tmpp = strp + CONST_STRLEN(_INCLUDE_DIRECTIVE); *tmpp != '\n' && *tmpp != '\0'; tmpp++);
00080 int len = tmpp - (strp + CONST_STRLEN(_INCLUDE_DIRECTIVE));
00081 if (len >= sizeof(buf)) {
00082 DEBUG("Can't process %s directive.", _INCLUDE_DIRECTIVE);
00083 free(str);
00084 return NULL;
00085 }
00086
00087 qStrCpy(buf, sizeof(buf), strp + CONST_STRLEN(_INCLUDE_DIRECTIVE), len);
00088 qStrTrim(buf);
00089
00090
00091 if (!(buf[0] == '/' || buf[0] == '\\')) {
00092 char tmp[MAX_PATHLEN];
00093 char *dir = qFileGetDir(filepath);
00094 if (strlen(dir) + 1 + strlen(buf) >= sizeof(buf)) {
00095 DEBUG("Can't process %s directive.", _INCLUDE_DIRECTIVE);
00096 free(dir);
00097 free(str);
00098 return NULL;
00099 }
00100 snprintf(tmp, sizeof(tmp), "%s/%s", dir, buf);
00101 free(dir);
00102
00103 strcpy(buf, tmp);
00104 }
00105
00106
00107 char *incdata;
00108 if (strlen(buf) == 0 || (incdata = qFileLoad(buf, NULL)) == NULL) {
00109 DEBUG("Can't process '%s%s' directive.", _INCLUDE_DIRECTIVE, buf);
00110 free(str);
00111 return NULL;
00112 }
00113
00114
00115 qStrCpy(buf, sizeof(buf), strp, CONST_STRLEN(_INCLUDE_DIRECTIVE) + len);
00116 strp = qStrReplace("sn", str, buf, incdata);
00117 free(incdata);
00118 free(str);
00119 str = strp;
00120 } else {
00121 strp += CONST_STRLEN(_INCLUDE_DIRECTIVE);
00122 }
00123 }
00124
00125
00126 config = qConfigParseStr(config, str, sepchar);
00127 free(str);
00128
00129 return config;
00130 }
00131
00147 Q_ENTRY *qConfigParseStr(Q_ENTRY *config, const char *str, char sepchar) {
00148 if (str == NULL) return NULL;
00149
00150 if(config == NULL) {
00151 config = qEntryInit();
00152 if(config == NULL) return NULL;
00153 }
00154
00155 char *org, *buf, *offset;
00156 for (org = buf = offset = strdup(str); *offset != '\0'; ) {
00157
00158 for (buf = offset; *offset != '\n' && *offset != '\0'; offset++);
00159 if (*offset != '\0') {
00160 *offset = '\0';
00161 offset++;
00162 }
00163 qStrTrim(buf);
00164
00165
00166 if ((buf[0] == '#') || (buf[0] == '\0')) continue;
00167
00168
00169 char *value = strdup(buf);
00170 char *name = _q_makeword(value, sepchar);
00171 qStrTrim(value);
00172 qStrTrim(name);
00173
00174 qEntryPutStr(config, name, value, true);
00175
00176 free(name);
00177 free(value);
00178 }
00179 free(org);
00180
00181
00182 Q_NLOBJ *obj;
00183 for(obj = (Q_NLOBJ*)qEntryFirst(config); obj; obj = (Q_NLOBJ*)qEntryNext(config)) {
00184 obj->object = _parseVariable(config, obj->object);
00185 }
00186
00187 return config;
00188 }
00189
00190 #define _VAR '$'
00191 #define _VAR_OPEN '{'
00192 #define _VAR_CLOSE '}'
00193 #define _VAR_CMD '!'
00194 #define _VAR_ENV '%'
00195 static char *_parseVariable(Q_ENTRY *config, char *value) {
00196 int loop;
00197
00198 do {
00199 char *s, *e;
00200 int bcnt;
00201
00202 loop = 0;
00203
00204
00205 for(s = value; *s != '\0'; s++) {
00206 if(!(*s == _VAR && *(s+1) == _VAR_OPEN)) continue;
00207
00208
00209 bcnt = 1;
00210 for(e = s + 2; *e != '\0'; e++) {
00211 if(*e == _VAR && *(e+1) == _VAR_OPEN) {
00212 s = e - 1;
00213 break;
00214 }
00215 else if(*e == _VAR_OPEN) bcnt++;
00216 else if(*e == _VAR_CLOSE) bcnt--;
00217 else continue;
00218
00219 if(bcnt == 0) break;
00220 }
00221 if(*e == '\0') break;
00222 if(bcnt > 0) continue;
00223
00224
00225 char buf[MAX_LINEBUF];
00226 int len;
00227
00228 len = e - s - 2;
00229 if (len >= (sizeof(buf) - 1)) continue;
00230 qStrCpy(buf, sizeof(buf), s + 2, len);
00231 qStrTrim(buf);
00232
00233
00234 char *t;
00235 int freet = 0;
00236 switch (buf[0]) {
00237 case _VAR_CMD : {
00238 if ((t = qStrTrim(qSysCmd(buf + 1))) == NULL) t = "";
00239 else freet = 1;
00240 break;
00241 }
00242 case _VAR_ENV : {
00243 t = (char*)qSysGetEnv(buf + 1, "");
00244 break;
00245 }
00246 default : {
00247 if ((t = (char *)qEntryGetStr(config, buf)) == NULL) {
00248 s = e;
00249 continue;
00250 }
00251 break;
00252 }
00253 }
00254
00255
00256 qStrCpy(buf, sizeof(buf), s, len + 3);
00257
00258 s = qStrReplace("sn", value, buf, t);
00259 if (freet == 1) free(t);
00260 free(value);
00261 value = s;
00262
00263 loop = 1;
00264 break;
00265 }
00266 } while(loop == 1);
00267
00268 return value;
00269 }