Julius 4.1.5
|
00001 00043 /* 00044 * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University 00045 * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology 00046 * Copyright (c) 2005-2007 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 00085 /* added by H.Banno for Windows & Mac */ 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') { /* for Mac */ 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 /* /path/file -> /path/ */ 00158 /* path/file -> path/ */ 00159 /* /file -> / */ 00160 /* file -> */ 00161 /* ../file -> ../ */ 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 /* check if string contains '$' and return immediately if not */ 00220 /* '$' = 36, '\'' = 39 */ 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 /* prepare result buffer */ 00246 target_malloclen = strlen(str) * 2; 00247 target = (char *)mymalloc(target_malloclen); 00248 00249 p = str; 00250 q = target; 00251 00252 /* parsing */ 00253 inbrace = FALSE; 00254 while (*p != '\0') { 00255 00256 /* look for next '$' */ 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') { /* reached end of string */ 00286 *q = '\0'; 00287 break; 00288 } 00289 00290 /* move to next */ 00291 p++; 00292 00293 /* check for brace */ 00294 eb = 0; 00295 if (*p == '(') { 00296 eb = ')'; 00297 } else if (*p == '{') { 00298 eb = '}'; 00299 } 00300 00301 /* proceed to find env end point and set the env string to env[] */ 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 /* get value */ 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) { /* for debug */ 00335 jlog("DEBUG: expand $%s to %s\n", env, envval); 00336 } 00337 00338 /* paste value to target */ 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 /* go on to next */ 00352 if (eb != 0) p++; 00353 } 00354 00355 free(str); 00356 return target; 00357 } 00358 00359 /* read-in and parse jconf file and process those using m_options */ 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 #define BUFLEN 512 00385 char buf[BUFLEN], cpy[BUFLEN]; 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 /* set the content of jconf file into argument list c_argv[1..c_argc-1] */ 00394 /* c_argv[0] will be the original conffile name */ 00395 /* inside jconf file, quoting by ", ' and escape by '\' is supported */ 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, BUFLEN, 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 == '\\') { /* escape by '\' */ 00416 if (*(++p) == '\0') break; 00417 *(dst++) = *(p++); 00418 } else { 00419 if (*p == '"') { /* quote by "" */ 00420 p++; 00421 while (*p != '\0' && *p != '"') *(dst++) = *(p++); 00422 if (*p == '\0') break; 00423 p++; 00424 } else if (*p == '\'') { /* quote by '' */ 00425 p++; 00426 while (*p != '\0' && *p != '\'') *(dst++) = *(p++); 00427 if (*p == '\0') break; 00428 p++; 00429 } else if (*p == '#') { /* comment out by '#' */ 00430 *p = '\0'; 00431 break; 00432 } else { /* other */ 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 /* env expansion */ 00453 for (i=1;i<c_argc;i++) { 00454 c_argv[i] = expand_env(c_argv[i]); 00455 } 00456 00457 if (debug2_flag) { /* for debug */ 00458 jlog("DEBUG: args:"); 00459 for (i=1;i<c_argc;i++) jlog(" %s",c_argv[i]); 00460 jlog("\n"); 00461 } 00462 00463 /* now that options are in c_argv[][], call opt_parse() to process them */ 00464 /* relative paths in jconf file are relative to the jconf file (not current) */ 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 /* free arguments */ 00471 while (c_argc-- > 0) { 00472 free(c_argv[c_argc]); 00473 } 00474 free(c_argv); 00475 00476 return(ret); 00477 } 00478 00479 /* end of file */