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