2 * Copyright (c) 2003 Nara Institute of Science and Technology
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name Nara Institute of Science and Technology may not be used to
15 * endorse or promote products derived from this software without
16 * specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY Nara Institute of Science and Technology
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE Nara Institute
22 * of Science and Technology BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * $Id: iotool.c,v 1.1.1.1 2007/03/13 07:40:10 masayu-a Exp $
44 #define RCFILE "\\chasenrc"
45 #define RC2FILE "\\chasen2rc"
47 #define RCFILE "/.chasenrc"
48 #define RC2FILE "/.chasen2rc"
51 #if defined HAVE_WINDOWS_H && !defined __CYGWIN__
52 #define REG_PATH "Software\\NAIST\\ChaSen"
53 #define REG_RC "chasenrc"
54 #define REG_GRAMMAR "grammar"
57 int Cha_lineno, Cha_lineno_error;
60 static FILE *cha_stderr = NULL;
61 static char progpath[PATH_MAX] = "chasen";
62 static char filepath[PATH_MAX];
63 static char grammar_dir[PATH_MAX];
64 static char chasenrc_path[PATH_MAX];
67 * cha_convert_escape - convert escape characters
69 /* XXX: not Shift-JIS safe */
71 cha_convert_escape(char *str, int ctrl_only)
75 for (s1 = s2 = str; *s1; s1++, s2++) {
100 * cha_set_progpath - set program pathname
102 * progpath is used in cha_exit() and cha_exit_file()
105 cha_set_progpath(char *path)
107 #if defined _WIN32 && ! defined __CYGWIN__
108 GetModuleFileName(GetModuleHandle(NULL), progpath, PATH_MAX);
109 #else /* not _WIN32 */
110 strncpy(progpath, path, PATH_MAX);
115 * cha_set_rcpath - set chasenrc file path
117 * this function is called when -r option is used.
120 cha_set_rcpath(char *filename)
122 strncpy(chasenrc_path, filename, PATH_MAX);
128 * called only from chasen.c
133 return chasenrc_path;
137 * cha_get_grammar_dir
139 * called only from chasen.c
142 cha_get_grammar_dir(void)
148 * cha_fopen - open file, or error end
151 * ret - exit code (don't exit if ret < 0)
154 cha_fopen(char *filename, char *mode, int ret)
158 if (filename[0] == '-' && filename[1] == '\0')
161 if ((fp = fopen(filename, mode)) != NULL) {
163 * filepath is used in cha_exit_file()
166 if (filename != filepath)
167 strncpy(filepath, filename, PATH_MAX);
168 Cha_lineno = Cha_lineno_error = 0;
171 cha_exit_perror(filename);
177 * cha_fopen_grammar - open file from current or grammar directory
180 * dir - 0: read from current directory
181 * 1: read from grammar directory
182 * 2: read from current directory or grammar directory
184 * ret - return the code when fopen() fails
187 * filepathp - file path string
190 cha_fopen_grammar(char *filename, char *mode, int ret, int dir,
195 *filepathp = filename;
199 * ¥«¥ì¥ó¥È¥Ç¥£¥ì¥¯¥È¥ê¤«¤éÆɤ߹þ¤à
201 return cha_fopen(filename, mode, ret);
204 * ¥«¥ì¥ó¥È¥Ç¥£¥ì¥¯¥È¥ê¤«¤éÆɤ߹þ¤à
206 if ((fp = cha_fopen(filename, mode, -1)) != NULL)
211 default: /* should be 1 */
213 * ʸˡ¥Ç¥£¥ì¥¯¥È¥ê¤«¤éÆɤ߹þ¤à
214 * ʸˡ¥Ç¥£¥ì¥¯¥È¥ê¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð .chasenrc ¤òÆɤ߹þ¤à
216 if (grammar_dir[0] == '\0')
217 cha_read_grammar_dir();
218 snprintf(filepath, PATH_MAX, "%s%s", grammar_dir, filename);
219 *filepathp = filepath;
220 return cha_fopen(filepath, mode, ret);
232 if ((p = malloc(n)) == NULL)
233 cha_exit_perror("malloc");
239 cha_realloc(void *ptr, size_t n)
243 if ((p = realloc(ptr, n)) == NULL)
244 cha_exit_perror("realloc");
249 #define CHA_MALLOC_SIZE (1024 * 64)
251 cha_malloc_char(int size)
253 static int idx = CHA_MALLOC_SIZE;
256 if (idx + size >= CHA_MALLOC_SIZE) {
257 ptr = (char *) cha_malloc(CHA_MALLOC_SIZE);
262 return ptr + idx - size;
266 cha_strdup(char *str)
270 newstr = cha_malloc_char(strlen(str) + 1);
277 * cha_exit() - print error messages on stderr and exit
280 cha_set_stderr(FILE * fp)
286 cha_exit(int status, char *format, ...)
295 else if (cha_stderr != stderr)
296 fputs("500 ", cha_stderr);
299 fprintf(cha_stderr, "%s: ", progpath);
300 va_start(ap, format);
301 vfprintf(cha_stderr, format, ap);
304 fputc('\n', cha_stderr);
305 if (cha_stderr == stderr)
312 cha_exit_file(int status, char *format, ...)
321 else if (cha_stderr != stderr)
322 fputs("500 ", cha_stderr);
325 fprintf(cha_stderr, "%s: ", progpath);
329 else if (Cha_lineno == Cha_lineno_error)
330 fprintf(cha_stderr, "%s:%d: ", filepath, Cha_lineno);
332 fprintf(cha_stderr, "%s:%d-%d: ", filepath, Cha_lineno_error,
335 va_start(ap, format);
336 vfprintf(cha_stderr, format, ap);
340 fputc('\n', cha_stderr);
341 if (cha_stderr == stderr)
355 cha_exit_perror(char *s)
362 cha_fopen_rcfile(void)
365 char *home_dir, *rc_env, *getenv();
368 * -R option (standard alone)
370 if (!strcmp(chasenrc_path, "*")) {
371 #if defined HAVE_WINDOWS_H && !defined __CYGWIN__
372 if ((cha_read_registry(REG_PATH, REG_RC, chasenrc_path) != NULL) &&
373 ((fp = cha_fopen(chasenrc_path, "r", -1)) != NULL)) {
377 strncpy(chasenrc_path, RCPATH, PATH_MAX);
378 if ((fp = cha_fopen(chasenrc_path, "r", -1)) != NULL)
380 cha_exit(1, "can't open %s", chasenrc_path);
386 if (chasenrc_path[0])
387 return cha_fopen(chasenrc_path, "r", 1);
390 * environment variable CHASENRC
392 if ((rc_env = getenv("CHASENRC")) != NULL) {
393 strncpy(chasenrc_path, rc_env, PATH_MAX);
394 return cha_fopen(chasenrc_path, "r", 1);
398 * .chasenrc in the home directory
400 if ((home_dir = getenv("HOME")) != NULL) {
404 snprintf(chasenrc_path, PATH_MAX, "%s%s", home_dir, RC2FILE);
405 if ((fp = cha_fopen(chasenrc_path, "r", -1)) != NULL)
407 snprintf(chasenrc_path, PATH_MAX, "%s%s", home_dir, RCFILE);
408 if ((fp = cha_fopen(chasenrc_path, "r", -1)) != NULL)
411 #ifdef PATHTYPE_MSDOS
412 else if ((home_dir = getenv("HOMEDRIVE")) != NULL) {
413 snprintf(chasenrc_path, PATH_MAX,
414 "%s%s%s", home_dir, getenv("HOMEPATH"), RC2FILE);
415 if ((fp = cha_fopen(chasenrc_path, "r", -1)) != NULL)
417 snprintf(chasenrc_path, PATH_MAX,
418 "%s%s%s", home_dir, getenv("HOMEPATH"), RCFILE);
419 if ((fp = cha_fopen(chasenrc_path, "r", -1)) != NULL)
422 #endif /* PATHTYPE_MSDOS */
424 #if defined HAVE_WINDOWS_H && !defined __CYGWIN__
425 if ((cha_read_registry(REG_PATH, REG_RC, chasenrc_path) != NULL) &&
426 ((fp = cha_fopen(chasenrc_path, "r", -1)) != NULL)) {
430 strncpy(chasenrc_path, RCPATH, PATH_MAX);
432 if ((fp = cha_fopen(chasenrc_path, "r", -1)) != NULL)
435 cha_exit(1, "can't open chasenrc or %s", chasenrc_path);
444 add_delimiter(char *string)
446 char *s = string + strlen(string);
448 if (s[-1] != PATH_DELIMITER) {
449 s[0] = PATH_DELIMITER;
455 * read .chasenrc and set grammar directory
458 cha_read_grammar_dir(void)
463 fp = cha_fopen_rcfile();
465 while (!cha_s_feof(fp)) {
467 cell = cha_s_read(fp);
468 s = cha_s_atom(cha_car(cell));
469 if (cha_litmatch(s, 1, STR_GRAM_FILE)) {
470 strncpy(grammar_dir, cha_s_atom(cha_car(cha_cdr(cell))), PATH_MAX);
471 add_delimiter(grammar_dir);
476 if (grammar_dir[0] == '\0') {
479 #if defined HAVE_WINDOWS_H && !defined __CYGWIN__
480 if (cha_read_registry(REG_PATH, REG_GRAMMAR,
481 grammar_dir) != NULL) {
482 if (grammar_dir[0] != '\0')
483 add_delimiter(grammar_dir);
486 strncpy(grammar_dir, chasenrc_path, PATH_MAX);
487 if ((s = strrchr(grammar_dir, PATH_DELIMITER)) != NULL)
490 grammar_dir[0] = '\0';
491 #if defined HAVE_WINDOWS_H && !defined __CYGWIN__
500 cha_read_registry(char *path, char *name, char *val)
502 #if defined HAVE_WINDOWS_H && !defined __CYGWIN__
504 DWORD size = PATH_MAX;
506 if ((RegOpenKeyEx(HKEY_CURRENT_USER, path, 0,
507 KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) &&
508 (RegQueryValueEx(hKey, name, NULL, NULL, (LPBYTE)val, &size) ==