Julius 4.2
|
00001 00043 /* 00044 * Copyright (c) 1991-2011 Kawahara Lab., Kyoto University 00045 * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology 00046 * Copyright (c) 2005-2011 Julius project team, Nagoya Institute of Technology 00047 * All rights reserved 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') ///< Determine token characters 00057 #define BUFLEN 512 00058 00086 /* added by H.Banno for Windows & Mac */ 00087 static char * 00088 fgets_jconf(char *buf, int size, FILE *fp) 00089 { 00090 int c, prev_c; 00091 int pos; 00092 00093 if (fp == NULL) return NULL; 00094 00095 pos = 0; 00096 c = '\0'; 00097 prev_c = '\0'; 00098 while (1) { 00099 if (pos >= size) { 00100 pos--; 00101 break; 00102 } 00103 00104 c = fgetc(fp); 00105 if (c == EOF) { 00106 buf[pos] = '\0'; 00107 if (pos <= 0) { 00108 return NULL; 00109 } else { 00110 return buf; 00111 } 00112 } else if (c == '\n' || c == '\r') { 00113 if (c == '\r' && (c = fgetc(fp)) != '\n') { /* for Mac */ 00114 ungetc(c, fp); 00115 } 00116 if (prev_c == '\\') { 00117 pos--; 00118 } else { 00119 break; 00120 } 00121 } else { 00122 buf[pos] = c; 00123 pos++; 00124 00125 #if defined(_WIN32) && !defined(__CYGWIN32__) 00126 if (c == '\\' && (_ismbblead(prev_c) && _ismbbtrail(c))) { 00127 c = '\0'; 00128 } 00129 #endif 00130 } 00131 prev_c = c; 00132 } 00133 buf[pos] = '\0'; 00134 00135 return buf; 00136 } 00137 00154 void 00155 get_dirname(char *path) 00156 { 00157 char *p; 00158 /* /path/file -> /path/ */ 00159 /* path/file -> path/ */ 00160 /* /file -> / */ 00161 /* file -> */ 00162 /* ../file -> ../ */ 00163 p = path + strlen(path) - 1; 00164 while (*p != '/' 00165 #if defined(_WIN32) && !defined(__CYGWIN32__) 00166 && *p != '\\' 00167 #endif 00168 && p != path) p--; 00169 if (p == path && *p != '/') *p = '\0'; 00170 else *(p+1) = '\0'; 00171 } 00172 00207 static char * 00208 expand_env(char *str) 00209 { 00210 char *p, *q; 00211 char *bgn; 00212 char eb; 00213 char *target; 00214 char *envval; 00215 int target_malloclen; 00216 int len, n; 00217 boolean inbrace; 00218 char env[256]; 00219 00220 /* check if string contains '$' and return immediately if not */ 00221 /* '$' = 36, '\'' = 39 */ 00222 p = str; 00223 inbrace = FALSE; 00224 while (*p != '\0') { 00225 if (*p == 39) { 00226 if (inbrace == FALSE) { 00227 inbrace = TRUE; 00228 } else { 00229 inbrace = FALSE; 00230 } 00231 p++; 00232 continue; 00233 } 00234 if (! inbrace) { 00235 if (*p == '\\') { 00236 p++; 00237 if (*p == '\0') break; 00238 } else { 00239 if (*p == 36) break; 00240 } 00241 } 00242 p++; 00243 } 00244 if (*p == '\0') return str; 00245 00246 /* prepare result buffer */ 00247 target_malloclen = strlen(str) * 2; 00248 target = (char *)mymalloc(target_malloclen); 00249 00250 p = str; 00251 q = target; 00252 00253 /* parsing */ 00254 inbrace = FALSE; 00255 while (*p != '\0') { 00256 00257 /* look for next '$' */ 00258 while (*p != '\0') { 00259 if (*p == 39) { 00260 if (inbrace == FALSE) { 00261 inbrace = TRUE; 00262 } else { 00263 inbrace = FALSE; 00264 } 00265 p++; 00266 continue; 00267 } 00268 if (! inbrace) { 00269 if (*p == '\\') { 00270 p++; 00271 if (*p == '\0') break; 00272 } else { 00273 if (*p == 36) break; 00274 } 00275 } 00276 *q = *p; 00277 p++; 00278 q++; 00279 n = q - target; 00280 if (n >= target_malloclen) { 00281 target_malloclen *= 2; 00282 target = myrealloc(target, target_malloclen); 00283 q = target + n; 00284 } 00285 } 00286 if (*p == '\0') { /* reached end of string */ 00287 *q = '\0'; 00288 break; 00289 } 00290 00291 /* move to next */ 00292 p++; 00293 00294 /* check for brace */ 00295 eb = 0; 00296 if (*p == '(') { 00297 eb = ')'; 00298 } else if (*p == '{') { 00299 eb = '}'; 00300 } 00301 00302 /* proceed to find env end point and set the env string to env[] */ 00303 if (eb != 0) { 00304 p++; 00305 bgn = p; 00306 while (*p != '\0' && *p != eb) p++; 00307 if (*p == '\0') { 00308 jlog("ERROR: failed to expand variable: no end brace: \"%s\"\n", str); 00309 free(target); 00310 return str; 00311 } 00312 } else { 00313 bgn = p; 00314 while (*p == '_' 00315 || (*p >= '0' && *p <= '9') 00316 || (*p >= 'a' && *p <= 'z') 00317 || (*p >= 'A' && *p <= 'Z')) p++; 00318 } 00319 len = p - bgn; 00320 if (len >= 256 - 1) { 00321 jlog("ERROR: failed to expand variable: too long env name: \"%s\"\n", str); 00322 free(target); 00323 return str; 00324 } 00325 strncpy(env, bgn, len); 00326 env[len] = '\0'; 00327 00328 /* get value */ 00329 if ((envval = getenv(env)) == NULL) { 00330 jlog("ERROR: failed to expand variable: no such variable \"%s\"\n", env); 00331 free(target); 00332 return str; 00333 } 00334 00335 if (debug2_flag) { /* for debug */ 00336 jlog("DEBUG: expand $%s to %s\n", env, envval); 00337 } 00338 00339 /* paste value to target */ 00340 while(*envval != '\0') { 00341 *q = *envval; 00342 q++; 00343 envval++; 00344 n = q - target; 00345 if (n >= target_malloclen) { 00346 target_malloclen *= 2; 00347 target = myrealloc(target, target_malloclen); 00348 q = target + n; 00349 } 00350 } 00351 00352 /* go on to next */ 00353 if (eb != 0) p++; 00354 } 00355 00356 free(str); 00357 return target; 00358 } 00359 00360 /* read-in and parse jconf file and process those using m_options */ 00379 static void 00380 add_to_arglist(char *buf, char ***argv_ret, int *argc_ret, int *maxnum_ret) 00381 { 00382 char *p = buf; 00383 char cpy[BUFLEN]; 00384 char *dst, *dst_from; 00385 char **argv = *argv_ret; 00386 int argc = *argc_ret; 00387 int maxnum = *maxnum_ret; 00388 00389 dst = cpy; 00390 while (1) { 00391 while (*p != '\0' && ISTOKEN(*p)) p++; 00392 if (*p == '\0') break; 00393 00394 dst_from = dst; 00395 00396 while (*p != '\0' && (!ISTOKEN(*p))) { 00397 if (*p == '\\') { /* escape by '\' */ 00398 if (*(++p) == '\0') break; 00399 *(dst++) = *(p++); 00400 } else { 00401 if (*p == '"') { /* quote by "" */ 00402 p++; 00403 while (*p != '\0' && *p != '"') *(dst++) = *(p++); 00404 if (*p == '\0') break; 00405 p++; 00406 } else if (*p == '\'') { /* quote by '' */ 00407 p++; 00408 while (*p != '\0' && *p != '\'') *(dst++) = *(p++); 00409 if (*p == '\0') break; 00410 p++; 00411 } else if (*p == '#') { /* comment out by '#' */ 00412 *p = '\0'; 00413 break; 00414 } else { /* other */ 00415 *(dst++) = *(p++); 00416 } 00417 } 00418 } 00419 if (dst != dst_from) { 00420 *dst = '\0'; dst++; 00421 if ( argc >= maxnum) { 00422 maxnum += 20; 00423 argv = (char **)myrealloc(argv, sizeof(char *) * maxnum); 00424 } 00425 argv[argc++] = strcpy((char*)mymalloc(strlen(dst_from)+1), dst_from); 00426 } 00427 } 00428 *argv_ret = argv; 00429 *argc_ret = argc; 00430 *maxnum_ret = maxnum; 00431 } 00432 00452 boolean 00453 config_string_parse(char *str, Jconf *jconf) 00454 { 00455 int c_argc; 00456 char **c_argv; 00457 int maxnum; 00458 char buf[BUFLEN]; 00459 char *cdir; 00460 int i; 00461 boolean ret; 00462 00463 jlog("STAT: parsing option string: \"%s\"\n", str); 00464 00465 /* set the content of jconf file into argument list c_argv[1..c_argc-1] */ 00466 maxnum = 20; 00467 c_argv = (char **)mymalloc(sizeof(char *) * maxnum); 00468 c_argv[0] = strcpy((char *)mymalloc(7), "string"); 00469 c_argc = 1; 00470 add_to_arglist(str, &c_argv, &c_argc, &maxnum); 00471 /* env expansion */ 00472 for (i=1;i<c_argc;i++) { 00473 c_argv[i] = expand_env(c_argv[i]); 00474 } 00475 /* now that options are in c_argv[][], call opt_parse() to process them */ 00476 /* relative paths in string are relative to current */ 00477 ret = opt_parse(c_argc, c_argv, NULL, jconf); 00478 00479 /* free arguments */ 00480 while (c_argc-- > 0) { 00481 free(c_argv[c_argc]); 00482 } 00483 free(c_argv); 00484 00485 return(ret); 00486 } 00487 00508 boolean 00509 config_file_parse(char *conffile, Jconf *jconf) 00510 { 00511 int c_argc; 00512 char **c_argv; 00513 FILE *fp; 00514 int maxnum; 00515 char buf[BUFLEN]; 00516 char *cdir; 00517 int i; 00518 boolean ret; 00519 00520 jlog("STAT: include config: %s\n", conffile); 00521 00522 /* set the content of jconf file into argument list c_argv[1..c_argc-1] */ 00523 /* c_argv[0] will be the original conffile name */ 00524 /* inside jconf file, quoting by ", ' and escape by '\' is supported */ 00525 if ((fp = fopen(conffile, "r")) == NULL) { 00526 jlog("ERROR: m_jconf: failed to open jconf file: %s\n", conffile); 00527 return FALSE; 00528 } 00529 maxnum = 20; 00530 c_argv = (char **)mymalloc(sizeof(char *) * maxnum); 00531 c_argv[0] = strcpy((char *)mymalloc(strlen(conffile)+1), conffile); 00532 c_argc = 1; 00533 while (fgets_jconf(buf, BUFLEN, fp) != NULL) { 00534 if (buf[0] == '\0') continue; 00535 add_to_arglist(buf, &c_argv, &c_argc, &maxnum); 00536 } 00537 if (fclose(fp) == -1) { 00538 jlog("ERROR: m_jconf: cannot close jconf file\n"); 00539 return FALSE; 00540 } 00541 00542 /* env expansion */ 00543 for (i=1;i<c_argc;i++) { 00544 c_argv[i] = expand_env(c_argv[i]); 00545 } 00546 00547 if (debug2_flag) { /* for debug */ 00548 jlog("DEBUG: args:"); 00549 for (i=1;i<c_argc;i++) jlog(" %s",c_argv[i]); 00550 jlog("\n"); 00551 } 00552 00553 /* now that options are in c_argv[][], call opt_parse() to process them */ 00554 /* relative paths in jconf file are relative to the jconf file (not current) */ 00555 cdir = strcpy((char *)mymalloc(strlen(conffile)+1), conffile); 00556 get_dirname(cdir); 00557 ret = opt_parse(c_argc, c_argv, (cdir[0] == '\0') ? NULL : cdir, jconf); 00558 free(cdir); 00559 00560 /* free arguments */ 00561 while (c_argc-- > 0) { 00562 free(c_argv[c_argc]); 00563 } 00564 free(c_argv); 00565 00566 return(ret); 00567 } 00568 00569 /* end of file */