Fix RPMLINT error
[platform/core/uifw/anthy.git] / src-diclib / ruleparser.c
1 /*
2  * ÀßÄê¥Õ¥¡¥¤¥ë¤Ê¤É¤Î¤¿¤á¤Î
3  * ÈÆÍѤΥե¡¥¤¥ëÆɤ߹þ¤ß¥â¥¸¥å¡¼¥ë
4  *
5  * Copyright (C) 2000-2006 TABATA Yusuke
6  *
7  */
8 /*
9   This library is free software; you can redistribute it and/or
10   modify it under the terms of the GNU Lesser General Public
11   License as published by the Free Software Foundation; either
12   version 2 of the License, or (at your option) any later version.
13
14   This library is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   Lesser General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public
20   License along with this library; if not, write to the Free Software
21   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
22  */
23 #include <ctype.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27
28 #include <anthy/conf.h>
29 #include <anthy/ruleparser.h>
30 #include <anthy/logger.h>
31
32 /* Ê¸Ë¡¥Õ¥¡¥¤¥ë¤Î¥Ñ¡¼¥¶ÍѤÎÄêµÁ */
33 #define MAX_TOKEN_LEN 256
34 /* ºÇÂç¤Î¥¤¥ó¥¯¥ë¡¼¥É¤Î¿¼¤µ */
35 #define MAX_INCLUDE_DEPTH 4
36
37 #define PS_INIT 0
38 #define PS_TOKEN 1
39 #define PS_EOF 2
40 #define PS_RET 3
41
42 static const char *NL = "NL";
43
44 static struct parser_stat {
45   FILE *fp_stack[MAX_INCLUDE_DEPTH];
46   FILE *fp;
47   int cur_fpp;/* ¥¹¥¿¥Ã¥¯¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹ */
48   int line_num;
49   char **tokens;
50   int nr_token;
51 } g_ps;
52
53 struct line_stat{
54   int stat;
55   char buf[MAX_TOKEN_LEN];
56   int buf_index;
57 };
58
59 static FILE *
60 open_file_in_confdir(const char *fn)
61 {
62   const char *dn;
63   char *full;
64   size_t dname_len;
65
66   if (!fn) {
67     return stdin;
68   }
69
70   if (fn[0] == '/' ||
71       (fn[0] == '.' && fn[1] == '/')) {
72     /* ÀäÂХѥ¹¤â¤·¤¯¤Ï¥«¥ì¥ó¥È¥Ç¥£¥ì¥¯¥È¥ê¤Ê¤Î¤Ç¤½¤Î¤Þ¤Þfopen */
73     return fopen(fn, "r");
74   }
75
76   dn = anthy_conf_get_str("ANTHYDIR");
77   if (!dn) {
78     return 0;
79   }
80   dname_len =  strlen(dn);
81   full = alloca(dname_len + strlen(fn) + 2);
82   sprintf(full, "%s/%s", dn, fn);
83
84   return fopen(full, "r");
85 }
86
87 /** ¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤Ë¤è¤ë¥¨¥¹¥±¡¼¥×¤â½èÍý¤¹¤ëgetc
88  * ¥¨¥¹¥±¡¼¥×¤µ¤ì¤¿Ê¸»ú¤Ê¤é¤ÐÊÖ¤êÃͤÏ1¤Ë¤Ê¤ë¡£
89  */
90 static int
91 mygetc (int *cc)
92 {
93   *cc = fgetc(g_ps.fp);
94   if (*cc == '\\') {
95     int c2 = fgetc(g_ps.fp);
96     switch(c2) {
97     case '\\':
98       *cc = '\\';
99       return 1;
100     case '\n':
101       *cc = ' ';
102       return 1;
103     case '\"':
104       *cc = '\"';
105       return 1;
106     default:;
107       /* go through */
108     }
109   }
110   return 0;
111 }
112
113 #define myisblank(c)    ((c) == ' ' || (c) == '\t')
114
115 /* ¹Ô¤Ë°ìʸ»úÄɲ乤ë */
116 static void
117 pushchar(struct line_stat *ls, int cc)
118 {
119   if (ls->buf_index == MAX_TOKEN_LEN - 1) {
120     ls->buf[MAX_TOKEN_LEN - 1] = 0;
121   } else {
122     ls->buf[ls->buf_index] = cc;
123     ls->buf_index ++;
124   }
125 }
126
127 static const char *
128 get_token_in(struct line_stat *ls)
129 {
130   int cc, esc;
131   int in_quote = 0;
132   if (ls->stat == PS_EOF) {
133     return NULL;
134   }
135   if (ls->stat == PS_RET) {
136     return NL;
137   }
138   /* ¥È¡¼¥¯¥ó¤¬»Ï¤Þ¤ë¤Þ¤Ç¶õÇò¤òÆɤßÈô¤Ð¤¹ */
139   do {
140     esc = mygetc(&cc);
141   } while (cc > 0 && myisblank(cc) && esc == 0);
142   if (cc == -1) {
143     return NULL;
144   }
145   if (cc == '\n'){
146     return NL;
147   }
148
149   /**/
150   if (cc == '\"' && !esc) {
151     in_quote = 1;
152   }
153   /**/
154   do {
155     pushchar(ls, cc);
156     esc = mygetc(&cc);
157     if (cc < 0){
158       /* EOF */
159       pushchar(ls, 0);
160       ls->stat = PS_EOF;
161       return ls->buf;
162     }
163     if (cc == '\n' && !esc) {
164       /* ²þ¹Ô */
165       pushchar(ls, 0);
166       ls->stat = PS_RET;
167       return ls->buf;
168     }
169     if (!in_quote && myisblank(cc)) {
170       break;
171     }
172     if (in_quote && cc == '\"' && !esc) {
173       pushchar(ls, '\"');
174       break;
175     }
176   } while (1);
177   pushchar(ls, 0);
178   return ls->buf;
179 }
180
181 /* °ì¹ÔÆɤà */
182 static int
183 get_line_in(void)
184 {
185   const char *t;
186   struct line_stat ls;
187
188   ls.stat = PS_INIT;
189   do{
190     ls.buf_index = 0;
191     t = get_token_in(&ls);
192     if (!t) {
193       return -1;
194     }
195     if (t == NL) {
196       return 0;
197     }
198     g_ps.nr_token++;
199     g_ps.tokens = realloc(g_ps.tokens, sizeof(char *)*g_ps.nr_token);
200     g_ps.tokens[g_ps.nr_token-1] = strdup(t);
201   } while(1);
202 }
203
204 static void
205 proc_include(void)
206 {
207   FILE *fp;
208   if (g_ps.nr_token != 2) {
209     anthy_log(0, "Syntax error in include directive.\n");
210     return ;
211   }
212   if (g_ps.cur_fpp > MAX_INCLUDE_DEPTH - 1) {
213     anthy_log(0, "Too deep include.\n");
214     return ;
215   }
216   fp = open_file_in_confdir(g_ps.tokens[1]);
217   if (!fp) {
218     anthy_log(0, "Failed to open %s.\n", g_ps.tokens[1]);
219     return ;
220   }
221   g_ps.cur_fpp++;
222   g_ps.fp_stack[g_ps.cur_fpp] = fp;
223   g_ps.fp = fp;
224 }
225
226 /* ¥¤¥ó¥¯¥ë¡¼¥É¤Î¥Í¥¹¥È¤ò²¼¤²¤ë */
227 static void
228 pop_file(void)
229 {
230   fclose(g_ps.fp);
231   g_ps.cur_fpp --;
232   g_ps.fp = g_ps.fp_stack[g_ps.cur_fpp];
233 }
234
235 static void
236 get_line(void)
237 {
238   int r;
239   
240  again:
241   anthy_free_line();
242   g_ps.line_num ++;
243
244   r = get_line_in();
245   if (r == -1){
246     /* EOFÅù¤Ç¤³¤ì°Ê¾åÆɤá¤ó */
247     if (g_ps.cur_fpp > 0) {
248       pop_file();
249       goto again;
250     }else{
251       return ;
252     }
253   }
254   if (g_ps.nr_token < 1) {
255     goto again;
256   }
257   if (!strcmp(g_ps.tokens[0], "\\include")) {
258     proc_include();
259     goto again;
260   }else if (!strcmp(g_ps.tokens[0], "\\eof")) {
261     if (g_ps.cur_fpp > 0) {
262       pop_file();
263       goto again;
264     }else{
265       anthy_free_line();
266       return ;
267     }
268   }
269   if (g_ps.tokens[0][0] == '#'){
270     goto again;
271   }
272 }
273
274 void
275 anthy_free_line(void)
276 {
277   int i;
278   if (g_ps.tokens) {        /* ÉÔÀµ¤Ê¥á¥â¥ê¥¢¥¯¥»¥¹¤ÎËɻߠ*/
279     for (i = 0; i < g_ps.nr_token; i++) {
280       free(g_ps.tokens[i]);
281     }
282     free(g_ps.tokens);
283     g_ps.tokens = 0;
284   }
285   g_ps.nr_token = 0;
286 }
287
288 int
289 anthy_open_file(const char *fn)
290 {
291   g_ps.fp_stack[0] = open_file_in_confdir(fn);
292   if (!g_ps.fp_stack[0]) {
293     return -1;
294   }
295   /* ¥Ñ¡¼¥¶¤Î¾õÂÖ¤ò½é´ü²½¤¹¤ë */
296   g_ps.cur_fpp = 0;
297   g_ps.fp = g_ps.fp_stack[0];
298   g_ps.line_num = 0;
299   g_ps.nr_token = 0;        /* ½é´ü²½Ëº¤ì¤Î½¤Àµ */
300   g_ps.tokens = NULL;       /* ½é´ü²½Ëº¤ì¤Î½¤Àµ */
301   return 0;
302 }
303
304 void
305 anthy_close_file(void)
306 {
307   if (g_ps.fp != stdin) {
308     fclose(g_ps.fp);
309   }
310   anthy_free_line();        /* ¸å»ÏËö˺¤ì¤ÎËɻߠ*/
311 }
312
313 int
314 anthy_read_line(char ***tokens, int *nr)
315 {
316   get_line();
317   *tokens = g_ps.tokens;
318   *nr = g_ps.nr_token;
319   if (!*nr) {
320     return -1;
321   }
322   return 0;
323 }
324
325 int
326 anthy_get_line_number(void)
327 {
328   return g_ps.line_num;
329 }