chiark / gitweb /
Imported Upstream version 1.0.0
[e16] / dox / file.c
1 /*
2  * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3  * Copyright (C) 2008 Kim Woelders
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to
7  * deal in the Software without restriction, including without limitation the
8  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9  * sell copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies of the Software, its documentation and marketing & publicity
14  * materials, and acknowledgment shall be given in the documentation, materials
15  * and software packages that this Software was used.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 #include "dox.h"
25 #ifdef USE_WORD_MB
26 # include <wctype.h>
27 #endif
28
29 int
30 exists(char *s)
31 {
32    struct stat         st;
33
34    if ((!s) || (!*s))
35       return (0);
36    if (stat(s, &st) < 0)
37       return (0);
38    return (1);
39 }
40
41 void
42 freestrlist(char **l, int num)
43 {
44    if (!l)
45       return;
46    while (num--)
47       Efree(l[num]);
48    Efree(l);
49 }
50
51 void
52 word(char *s, int num, char *wd)
53 {
54    int                 cnt, i;
55    char               *start, *finish, *ss, *w;
56
57    if (!s)
58       return;
59    if (!wd)
60       return;
61    if (num <= 0)
62      {
63         *wd = 0;
64         return;
65      }
66    cnt = 0;
67    i = 0;
68    start = NULL;
69    finish = NULL;
70    ss = NULL;
71    w = wd;
72
73    while (s[i])
74      {
75         if ((cnt == num) && ((s[i] == ' ') || (s[i] == '\t')))
76           {
77              finish = &s[i];
78              break;
79           }
80         if ((s[i] != ' ') && (s[i] != '\t'))
81           {
82              if (i == 0)
83                {
84                   cnt++;
85                   if (cnt == num)
86                      start = &s[i];
87                }
88              else if ((s[i - 1] == ' ') || (s[i - 1] == '\t'))
89                {
90                   cnt++;
91                   if (cnt == num)
92                      start = &s[i];
93                }
94           }
95         i++;
96      }
97    if (cnt == num)
98      {
99         if ((start) && (finish))
100           {
101              for (ss = start; ss < finish; ss++)
102                 *wd++ = *ss;
103           }
104         else if (start)
105           {
106              for (ss = start; *ss != 0; ss++)
107                 *wd++ = *ss;
108           }
109         *wd = 0;
110      }
111 }
112
113 #ifdef USE_WORD_MB
114 void
115 word_mb(char *s, int num, char *wd, int *spaceflag)
116 {
117    int                 cnt, i;
118    char               *start, *finish, *ss, *w;
119
120    int                 wcflg, mbflg;
121    struct char_class {
122       const char         *name;
123       wctype_t            wt;
124    }                  *cc, char_class_tbl[] =
125    {
126 #ifdef linux
127       /* Will be supported on glibc 2.1.3 or later */
128       {
129       "jspace", 0},
130       {
131       "jhira", 0},
132       {
133       "jkata", 0},
134       {
135       "jkanji", 0},
136       {
137       "jdigit", 0},             /* Japanese */
138       {
139       "hangul", 0},
140       {
141       "hanja", 0},              /* Korean    */
142          /* {"?????"}, {"?????"}, *//* Chinese   */
143 #endif
144 #ifdef sgi
145          /* SGI IRIX (Japanese, Chinese, Korean, etc..) */
146       {
147       "special", 0},
148       {
149       "phonogram", 0},
150       {
151       "ideogram", 0},
152 #endif
153 #ifdef sun
154          /* {"?????"}, {"?????"}, */
155 #endif
156 #ifdef hpux
157          /* {"?????"}, {"?????"}, */
158 #endif
159       {
160       NULL, 0}
161    };
162
163    if (!s)
164       return;
165    if (!wd)
166       return;
167    if (num <= 0)
168      {
169         *wd = 0;
170         return;
171      }
172
173    /*  Check multibyte character class is available or not */
174    wcflg = 0;
175    for (cc = char_class_tbl; cc->name != NULL; cc++)
176      {
177         cc->wt = wctype(cc->name);
178         if (cc->wt != (wctype_t) 0)
179            wcflg = 1;
180      }
181
182    cnt = 0;
183    i = 0;
184    start = NULL;
185    finish = NULL;
186    ss = NULL;
187    w = wd;
188    *spaceflag = 0;
189
190    while (s[i])
191      {
192         int                 len, oldflg = 1;
193
194         len = mblen(s + i, MB_CUR_MAX);
195         if (len < 0)
196           {
197              i++;
198              continue;
199           }
200
201         /*  Check multibyte character class */
202         if (wcflg)
203           {
204              wchar_t             wc;
205
206              mbflg = 1;
207              if ((mbtowc(&wc, s + i, strlen(s + i))) != -1)
208                {
209                   for (cc = char_class_tbl; cc->name != NULL; cc++)
210                     {
211                        if (cc->wt == (wctype_t) 0)
212                           continue;
213
214                        if (iswctype(wc, cc->wt) != 0)
215                          {
216                             mbflg = 2;
217                             break;
218                          }
219                     }
220                }
221           }
222         else
223            mbflg = len;
224
225         if ((cnt == num) && ((s[i] == ' ') || (s[i] == '\t') ||
226                              (oldflg != mbflg) || (mbflg > 1)))
227           {
228              finish = &s[i];
229              break;
230           }
231
232         if ((s[i] != ' ') && (s[i] != '\t'))
233           {
234              if ((i == 0) ||
235                  (s[i - 1] == ' ') || (s[i - 1] == '\t') ||
236                  ((oldflg > 1) && (mbflg > 1)) || (oldflg != mbflg))
237                {
238                   cnt++;
239                   if (cnt == num)
240                     {
241                        start = &s[i];
242                        if ((s[i - 1] == ' ') || (s[i - 1] == '\t'))
243                           *spaceflag = 1;
244                     }
245                }
246           }
247         i += len;
248         oldflg = mbflg;
249      }
250    if (cnt == num)
251      {
252         if ((start) && (finish))
253           {
254              for (ss = start; ss < finish; ss++)
255                 *wd++ = *ss;
256           }
257         else if (start)
258           {
259              for (ss = start; *ss != 0; ss++)
260                 *wd++ = *ss;
261           }
262         *wd = 0;
263      }
264 }
265 #endif
266
267 int
268 findLocalizedFile(char *fname)
269 {
270    char               *tmp, *lang, *p[3];
271    int                 i;
272
273    if (!(lang = setlocale(LC_MESSAGES, NULL)))
274       return 0;
275
276    tmp = strdup(fname);
277    lang = strdup(lang);         /* lang may be in static space, thus it must
278                                  * be duplicated before we change it below */
279    p[0] = lang + strlen(lang);
280    p[1] = strchr(lang, '.');
281    p[2] = strchr(lang, '_');
282
283    for (i = 0; i < 3; i++)
284      {
285         if (p[i] == NULL)
286            continue;
287
288         *p[i] = '\0';
289         sprintf(fname, "%s.%s", tmp, lang);
290         if (exists(fname))
291           {
292              Efree(tmp);
293              Efree(lang);
294              return 1;
295           }
296      }
297    strcpy(fname, tmp);
298    Efree(tmp);
299    Efree(lang);
300
301    return 0;
302 }