Mercurial > freewnn
diff Wnn/etc/msg.c @ 0:bbc77ca4def5
initial import
author | Yoshiki Yazawa <yaz@cc.rim.or.jp> |
---|---|
date | Thu, 13 Dec 2007 04:30:14 +0900 |
parents | |
children | ed4bb01eb317 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Wnn/etc/msg.c Thu Dec 13 04:30:14 2007 +0900 @@ -0,0 +1,423 @@ +/* + * $Id: msg.c,v 1.13 2005/04/10 15:26:37 aonoto Exp $ + */ + +/* + * FreeWnn is a network-extensible Kana-to-Kanji conversion system. + * This file is part of FreeWnn. + * + * Copyright Kyoto University Research Institute for Mathematical Sciences + * 1987, 1988, 1989, 1990, 1991, 1992 + * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999 + * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992 + * Copyright FreeWnn Project 1999, 2000, 2002 + * + * Maintainer: FreeWnn Project <freewnn@tomo.gr.jp> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + struct msg_cat msg_open(name, nlspath, lang) + char *name; + char *nlspath; + char *lang; + + char * msg_get(cd, id, s, lang) + struct msg_cat cd; + int id; + char *s; + + void msg_close(cd) + struct msg_cat cd; + + format of message file + <message id>\t<message> +*/ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#if STDC_HEADERS +# include <stdlib.h> +# include <string.h> +#else +# if HAVE_MALLOC_H +# include <malloc.h> +# endif +# if HAVE_STRINGS_H +# include <strings.h> +# endif +#endif /* STDC_HEADERS */ + +#include "commonhd.h" +#include "wnn_os.h" +#include "msg.h" + +static char * +getlang (lang) + char *lang; +{ + static char tmp[32]; + char *p; + int i; + + if (lang == NULL || *lang == '\0') + { +#ifdef HAS_SETLOCALE + lang = setlocale (LC_ALL, NULL); + if (lang == NULL || *lang == '\0') +#endif + { + lang = getenv ("LC_MESSAGES"); + if (lang == NULL || *lang == '\0') + { + lang = getenv ("LANG"); + if (lang == NULL || *lang == '\0') + { + lang = DEF_LANG; + } + } + } + } + for (i = 0, p = lang; *p && *p != '.'; i++, p++) + { + tmp[i] = *p; + } + tmp[i] = '\0'; + return (tmp); + /* + return(lang); + */ +} + +static int +_search (id, bd) + int *id; + struct msg_bd *bd; +{ + return (*id - bd->msg_id); +} + +static void +_escape (op, ip) + register char *op, *ip; +{ + for (; *ip != 0; ip++, op++) + { + if (*ip == '\\') + { + switch (*++ip) + { + case 'n': + *op = '\n'; + break; + case 't': + *op = '\t'; + break; + case 'b': + *op = '\b'; + break; + case 'r': + *op = '\r'; + break; + case 'f': + *op = '\f'; + break; + case 'v': + *op = '\v'; + break; + case '0': + *op = 0; + break; + /* + case 'a': + *op = '\a'; + break; + case 'e': + case 'E': + case 'o': + case 'd': + case 'x': + break; + */ + default: + *op = *ip; + break; + } + } + else + { + if (*ip == '\n') + { + *op = '\0'; + } + else + { + *op = *ip; + } + } + } + *op = 0; +} + +static char * +get_msg_bd (cd, id) + struct msg_cat *cd; + int id; +{ + register struct msg_bd *bd; + if (cd->msg_bd == 0 || cd->msg_cnt == 0) + return (NULL); + bd = (struct msg_bd *) bsearch (&id, cd->msg_bd, cd->msg_cnt, sizeof (struct msg_bd), _search); + if (bd == NULL) + return (NULL); + return (bd->msg); +} + +/* expand + %N: the value of the name parameter passed to msg_open() + %L: the value of LANG + %l: the language element from LANG + %t: the territory element from LANG + %c: the codeset element from LANG + %%: a single % charctor +*/ +static int +expand (op, ip, name, lang) + register char *op, *ip, *name, *lang; +{ + if (!ip || !*ip) + return (-1); + for (; *ip != 0; ip++) + { + if (*ip == '%') + { + switch (*++ip) + { + case 'N': + if (!name || !*name) + return (-1); + strcpy (op, name); + op += strlen (name); + break; + case 'L': + if (!lang || !*lang) + return (-1); + strcpy (op, lang); + op += strlen (lang); + break; + /* + case 'l': + strcpy(op, language); + op += strlen(language); + break; + case 't': + strcpy(op, terr); + op += strlen(terr); + break; + case 'c': + strcpy(op, code); + op += strlen(code); + break; + case '%': + strcpy(op, "%"); + op += strlen("%"); + break; + */ + default: + break; + } + } + else + { + *op = *ip; + op++; + } + } + *op = '\0'; + return (0); +} + + +struct msg_cat * +msg_open (name, nlspath, lang) + char *name; + char *nlspath; + char *lang; +{ + struct msg_cat *cd; + + char fn[MAXPATHLEN]; + FILE *fp; + char data[1024]; + char save[1024]; + int msg_cnt = 0; + int msg_byte = 0; + register char *dp; + register struct msg_bd *bd; + register char *msg, *l; + + l = getlang (lang); + if (name && *name == '/') + { + strcpy (fn, name); + } + else + { + if (expand (fn, nlspath, name, l) == -1) + { + return (NULL); + } + } + + if (!(cd = (struct msg_cat *) malloc (sizeof (struct msg_cat)))) + return (NULL); + + strcpy (cd->name, name); + strcpy (cd->lang, l); + strcpy (cd->nlspath, nlspath); + cd->nextp = NULL; + cd->msg_cnt = 0; + + if ((fp = fopen (fn, "r")) == NULL) + { + /* message file not found */ + cd->msg_bd = 0; + return (cd); + } + for (;;) + { + /* first: count bytes */ + if (fgets (data, 1024, fp) == NULL) + break; + if (*data == '#') + continue; /* comment */ + for (dp = data; *dp && *dp != '\t'; dp++); /* msg_id:message\n */ + if (*dp == '\0') + continue; + dp++; + msg_byte += strlen (dp); + msg_cnt++; + } + rewind (fp); + + cd->msg_cnt = msg_cnt; + if (!(bd = cd->msg_bd = (struct msg_bd *) malloc ((sizeof (struct msg_bd)) * msg_cnt + msg_byte + 1))) + { + fclose (fp); + free (cd); + return (NULL); + } + msg = (char *) bd + (sizeof (struct msg_bd)) * msg_cnt; + + for (;;) + { + /* second : get message */ + if (fgets (data, 1024, fp) == NULL) + break; + if (*data == '#') + continue; /* comment */ + for (dp = data; *dp && *dp != '\t'; dp++); /* msg_id:message\n */ + if (*dp == '\0') + continue; + *dp = 0; + dp++; + bd->msg_id = atoi (data); + bd->msg = msg; + bd++; + _escape (save, dp); + strcpy (msg, save); + msg += strlen (save); + *msg = 0; + msg++; + } + fclose (fp); + return (cd); +} + +char * +msg_get (catd, id, msg, lang) + struct msg_cat *catd; + int id; + char *msg; + register char *lang; +{ + register struct msg_cat *cd; + register char *msg_bd; + + if (catd == 0) + goto error; + cd = catd; + if (lang == 0 || *lang == '\0') + { + lang = cd->lang; + } + else + { + for (;; cd = cd->nextp) + { + if (strcmp (lang, cd->lang) == 0) + break; + if (cd->nextp == 0) + { + cd->nextp = msg_open (cd->name, cd->nlspath, lang); + cd = cd->nextp; + break; + } + } + } + + if (msg_bd = get_msg_bd (cd, id)) + return (msg_bd); +error: + if (msg != 0 && *msg != '\0') + return (msg); + { + static char ret[128]; + sprintf (ret, "mes_id = %d: %s", id, DEF_MSG); + return (ret); + } +} + +void +msg_close (cd) + register struct msg_cat *cd; +{ + if (cd->nextp) + msg_close (cd->nextp); + if (cd->msg_bd) + free (cd->msg_bd); + if (cd) + free (cd); +} + +#ifdef not_use +/* test */ +main () +{ + struct msg_cat *cd; + + cd = msg_open ("msg", "%L", "ja_JP"); + + printf (msg_get (cd, 5, "message not found\n", "ja_JP"), 555); + printf (msg_get (cd, 6, "message not found\n", "zh_CN")); + printf (msg_get (cd, -1, "", "ja_JP"), 555); + printf (msg_get (cd, 2, "message not found\n", "ja_JP"), "abc"); + printf (msg_get (cd, 100, "message not found\n", "zh_CN"), "abc"); +} +#endif /* not_use */