00001
00043
00044
00045
00046
00047
00048
00049
00050 #include <julius/julius.h>
00051
00052 #if defined(_WIN32) && !defined(__CYGWIN32__)
00053 #include <mbstring.h>
00054 #endif
00055
00056 #define ISTOKEN(A) (A == ' ' || A == '\t' || A == '\n')
00057
00058
00085
00086 static char *
00087 fgets_jconf(char *buf, int size, FILE *fp)
00088 {
00089 int c, prev_c;
00090 int pos;
00091
00092 if (fp == NULL) return NULL;
00093
00094 pos = 0;
00095 c = '\0';
00096 prev_c = '\0';
00097 while (1) {
00098 if (pos >= size) {
00099 pos--;
00100 break;
00101 }
00102
00103 c = fgetc(fp);
00104 if (c == EOF) {
00105 buf[pos] = '\0';
00106 if (pos <= 0) {
00107 return NULL;
00108 } else {
00109 return buf;
00110 }
00111 } else if (c == '\n' || c == '\r') {
00112 if (c == '\r' && (c = fgetc(fp)) != '\n') {
00113 ungetc(c, fp);
00114 }
00115 if (prev_c == '\\') {
00116 pos--;
00117 } else {
00118 break;
00119 }
00120 } else {
00121 buf[pos] = c;
00122 pos++;
00123
00124 #if defined(_WIN32) && !defined(__CYGWIN32__)
00125 if (c == '\\' && (_ismbblead(prev_c) && _ismbbtrail(c))) {
00126 c = '\0';
00127 }
00128 #endif
00129 }
00130 prev_c = c;
00131 }
00132 buf[pos] = '\0';
00133
00134 return buf;
00135 }
00136
00153 void
00154 get_dirname(char *path)
00155 {
00156 char *p;
00157
00158
00159
00160
00161
00162 p = path + strlen(path) - 1;
00163 while (*p != '/'
00164 #if defined(_WIN32) && !defined(__CYGWIN32__)
00165 && *p != '\\'
00166 #endif
00167 && p != path) p--;
00168 if (p == path && *p != '/') *p = '\0';
00169 else *(p+1) = '\0';
00170 }
00171
00206 static char *
00207 expand_env(char *str)
00208 {
00209 char *p, *q;
00210 char *bgn;
00211 char eb;
00212 char *target;
00213 char *envval;
00214 int target_malloclen;
00215 int len, n;
00216 boolean inbrace;
00217 char env[256];
00218
00219
00220
00221 p = str;
00222 inbrace = FALSE;
00223 while (*p != '\0') {
00224 if (*p == 39) {
00225 if (inbrace == FALSE) {
00226 inbrace = TRUE;
00227 } else {
00228 inbrace = FALSE;
00229 }
00230 p++;
00231 continue;
00232 }
00233 if (! inbrace) {
00234 if (*p == '\\') {
00235 p++;
00236 if (*p == '\0') break;
00237 } else {
00238 if (*p == 36) break;
00239 }
00240 }
00241 p++;
00242 }
00243 if (*p == '\0') return str;
00244
00245
00246 target_malloclen = strlen(str) * 2;
00247 target = (char *)mymalloc(target_malloclen);
00248
00249 p = str;
00250 q = target;
00251
00252
00253 inbrace = FALSE;
00254 while (*p != '\0') {
00255
00256
00257 while (*p != '\0') {
00258 if (*p == 39) {
00259 if (inbrace == FALSE) {
00260 inbrace = TRUE;
00261 } else {
00262 inbrace = FALSE;
00263 }
00264 p++;
00265 continue;
00266 }
00267 if (! inbrace) {
00268 if (*p == '\\') {
00269 p++;
00270 if (*p == '\0') break;
00271 } else {
00272 if (*p == 36) break;
00273 }
00274 }
00275 *q = *p;
00276 p++;
00277 q++;
00278 n = q - target;
00279 if (n >= target_malloclen) {
00280 target_malloclen *= 2;
00281 target = myrealloc(target, target_malloclen);
00282 q = target + n;
00283 }
00284 }
00285 if (*p == '\0') {
00286 *q = '\0';
00287 break;
00288 }
00289
00290
00291 p++;
00292
00293
00294 eb = 0;
00295 if (*p == '(') {
00296 eb = ')';
00297 } else if (*p == '{') {
00298 eb = '}';
00299 }
00300
00301
00302 if (eb != 0) {
00303 p++;
00304 bgn = p;
00305 while (*p != '\0' && *p != eb) p++;
00306 if (*p == '\0') {
00307 jlog("ERROR: failed to expand variable: no end brace: \"%s\"\n", str);
00308 free(target);
00309 return str;
00310 }
00311 } else {
00312 bgn = p;
00313 while (*p == '_'
00314 || (*p >= '0' && *p <= '9')
00315 || (*p >= 'a' && *p <= 'z')
00316 || (*p >= 'A' && *p <= 'Z')) p++;
00317 }
00318 len = p - bgn;
00319 if (len >= 256 - 1) {
00320 jlog("ERROR: failed to expand variable: too long env name: \"%s\"\n", str);
00321 free(target);
00322 return str;
00323 }
00324 strncpy(env, bgn, len);
00325 env[len] = '\0';
00326
00327
00328 if ((envval = getenv(env)) == NULL) {
00329 jlog("ERROR: failed to expand variable: no such variable \"%s\"\n", env);
00330 free(target);
00331 return str;
00332 }
00333
00334 if (debug2_flag) {
00335 jlog("DEBUG: expand $%s to %s\n", env, envval);
00336 }
00337
00338
00339 while(*envval != '\0') {
00340 *q = *envval;
00341 q++;
00342 envval++;
00343 n = q - target;
00344 if (n >= target_malloclen) {
00345 target_malloclen *= 2;
00346 target = myrealloc(target, target_malloclen);
00347 q = target + n;
00348 }
00349 }
00350
00351
00352 if (eb != 0) p++;
00353 }
00354
00355 free(str);
00356 return target;
00357 }
00358
00359
00377 boolean
00378 config_file_parse(char *conffile, Jconf *jconf)
00379 {
00380 int c_argc;
00381 char **c_argv;
00382 FILE *fp;
00383 int maxnum, step;
00384 static const int len = 512;
00385 char buf[len], cpy[len];
00386 char *p, *dst, *dst_from;
00387 char *cdir;
00388 int i;
00389 boolean ret;
00390
00391 jlog("STAT: include config: %s\n", conffile);
00392
00393
00394
00395
00396 if ((fp = fopen(conffile, "r")) == NULL) {
00397 jlog("ERROR: m_jconf: failed to open jconf file: %s\n", conffile);
00398 return FALSE;
00399 }
00400 step = 20;
00401 maxnum = step;
00402 c_argv = (char **)mymalloc(sizeof(char *) * maxnum);
00403 c_argv[0] = strcpy((char *)mymalloc(strlen(conffile)+1), conffile);
00404 c_argc = 1;
00405 while (fgets_jconf(buf, len, fp) != NULL) {
00406 if (buf[0] == '\0') continue;
00407 p = buf; dst = cpy;
00408 while (1) {
00409 while (*p != '\0' && ISTOKEN(*p)) p++;
00410 if (*p == '\0') break;
00411
00412 dst_from = dst;
00413
00414 while (*p != '\0' && (!ISTOKEN(*p))) {
00415 if (*p == '\\') {
00416 if (*(++p) == '\0') break;
00417 *(dst++) = *(p++);
00418 } else {
00419 if (*p == '"') {
00420 p++;
00421 while (*p != '\0' && *p != '"') *(dst++) = *(p++);
00422 if (*p == '\0') break;
00423 p++;
00424 } else if (*p == '\'') {
00425 p++;
00426 while (*p != '\0' && *p != '\'') *(dst++) = *(p++);
00427 if (*p == '\0') break;
00428 p++;
00429 } else if (*p == '#') {
00430 *p = '\0';
00431 break;
00432 } else {
00433 *(dst++) = *(p++);
00434 }
00435 }
00436 }
00437 if (dst != dst_from) {
00438 *dst = '\0'; dst++;
00439 if (c_argc >= maxnum) {
00440 maxnum += step;
00441 c_argv = (char **)myrealloc(c_argv, sizeof(char *) * maxnum);
00442 }
00443 c_argv[c_argc++] = strcpy((char*)mymalloc(strlen(dst_from)+1), dst_from);
00444 }
00445 }
00446 }
00447 if (fclose(fp) == -1) {
00448 jlog("ERROR: m_jconf: cannot close jconf file\n");
00449 return FALSE;
00450 }
00451
00452
00453 for (i=1;i<c_argc;i++) {
00454 c_argv[i] = expand_env(c_argv[i]);
00455 }
00456
00457 if (debug2_flag) {
00458 jlog("DEBUG: args:");
00459 for (i=1;i<c_argc;i++) jlog(" %s",c_argv[i]);
00460 jlog("\n");
00461 }
00462
00463
00464
00465 cdir = strcpy((char *)mymalloc(strlen(conffile)+1), conffile);
00466 get_dirname(cdir);
00467 ret = opt_parse(c_argc, c_argv, (cdir[0] == '\0') ? NULL : cdir, jconf);
00468 free(cdir);
00469
00470
00471 while (c_argc-- > 0) {
00472 free(c_argv[c_argc]);
00473 }
00474 free(c_argv);
00475
00476 return(ret);
00477 }
00478
00479