Massive indent of all codes:
[scilab.git] / scilab / modules / fileio / src / c / do_xxscanf.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) INRIA
4  * ...
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13 /*--------------------------------------------------------------------------*/
14 #if defined(__linux__)
15 #define _GNU_SOURCE             /* Bug 5673 fix: avoid dependency on GLIBC_2.7 */
16 #endif
17
18 #include <stdio.h>
19 #include <ctype.h>              /* isdigit */
20 #include <string.h>
21 #include "BOOL.h"
22 #include "MALLOC.h"
23 #include "do_xxscanf.h"
24 #include "Scierror.h"
25 #include "localization.h"
26 #include "do_xxprintf.h"
27 #include "core_math.h"
28 /*--------------------------------------------------------------------------*/
29 typedef int (*XXSCANF) (FILE *, char *, ...);
30 typedef int (*FLUSH) (FILE *);
31
32 /*--------------------------------------------------------------------------*/
33 static void set_xxscanf(FILE * fp, XXSCANF * xxscanf, char **target, char **strv)
34 {
35     if (fp == (FILE *) 0)
36     {
37         *target = *strv;
38         *xxscanf = (XXSCANF) sscanf;
39     }
40     else
41     {
42         *target = (char *)fp;
43         *xxscanf = (XXSCANF) fscanf;
44     }
45 }
46
47 /*--------------------------------------------------------------------------*/
48 int do_xxscanf(char *fname, FILE * fp, char *format, int *nargs, char *strv, int *retval, rec_entry * buf, sfdir * type)
49 {
50     int nc[MAXSCAN];
51     int n_directive_count = 0;
52     int i = 0;
53     int l_flag = 0;
54     int h_flag = 0;
55     int width_flag = 0;
56     int width_val = 0;
57     int ignore_flag = 0;
58     int str_width_flag = 0;
59     int num_conversion = -1;
60     void *ptrtab[MAXSCAN];
61     char sformat[MAX_STR];
62     char backupcurrrentchar;
63     char directive;
64     char *p1 = NULL;
65     char *target = NULL;
66     char *sval = NULL;
67     register char *currentchar = NULL;
68
69     XXSCANF xxscanf;
70
71     set_xxscanf(fp, &xxscanf, &target, &strv);
72     currentchar = format;
73     *retval = 0;
74
75     while (TRUE)
76     {
77         /* scanf */
78         while (*currentchar != '%' && *currentchar != '\0')
79         {
80             currentchar++;
81         }
82         if (*currentchar == '%' && *(currentchar + 1) == '%')
83         {
84             currentchar = currentchar + 2;
85             while (*currentchar != '%' && *currentchar != '\0')
86             {
87                 currentchar++;
88             }
89         }
90
91         if (*currentchar == 0)
92         {
93             break;
94         }
95
96         currentchar++;
97         p1 = currentchar - 1;
98
99         while (isdigit(((int)*currentchar)))
100         {
101             currentchar++;
102         }
103
104         width_flag = 0;
105
106         if (p1 + 1 != currentchar)
107         {
108             char w = *currentchar;
109
110             *currentchar = '\0';
111             width_flag = 1;
112             sscanf(p1 + 1, "%d", &width_val);
113             *currentchar = w;
114         }
115
116         ignore_flag = 0;
117
118         if (*currentchar == '*')
119         {
120             ignore_flag = 1;
121             currentchar++;
122         }
123         else
124         {
125             l_flag = h_flag = 0;
126         }
127
128         if (*currentchar == 'l')
129         {
130             currentchar++;
131             l_flag = 1;
132         }
133         else if (*currentchar == 'h')
134         {
135             currentchar++;
136             h_flag = 1;
137         }
138
139         /* directive points to the scan directive  */
140
141         directive = *currentchar++;
142
143         if (directive == '[')
144         {
145             char *currentchar1 = currentchar--;
146
147             while (*currentchar1 != '\0' && *currentchar1 != ']')
148             {
149                 currentchar1++;
150             }
151
152             if (*currentchar1 == '\0')
153             {
154                 Scierror(998, _("%s: An error occurred: %s\n"), fname, _("unclosed [ directive."));
155                 return RET_BUG;
156             }
157
158             if (currentchar1 == currentchar + 1 || strncmp(currentchar, "[^]", 3) == 0)
159             {
160                 currentchar1++;
161                 while (*currentchar1 != '\0' && *currentchar1 != ']')
162                 {
163                     currentchar1++;
164                 }
165
166                 if (*currentchar1 == '\0')
167                 {
168                     Scierror(998, _("%s: An error occurred: %s\n"), fname, _("unclosed [ directive."));
169                     return RET_BUG;
170                 }
171             }
172
173             directive = *currentchar1++;
174             currentchar = currentchar1;
175         }
176
177         backupcurrrentchar = *currentchar;
178
179         if (ignore_flag != 1)
180         {
181             num_conversion++;
182
183             if (num_conversion >= MAXSCAN)
184             {
185                 Scierror(998, _("%s: An error occurred: too many (> %d) conversion required.\n"), fname, MAXSCAN);
186                 return RET_BUG;
187             }
188
189             switch (directive)
190             {
191                 case ']':
192                     if (width_flag == 0)
193                     {
194                         str_width_flag = 1;
195                     }
196
197                     if (width_flag == 1 && width_val > MAX_STR - 1)
198                     {
199                         Scierror(998, _("%s: An error occurred: field %d is too long (> %d) for %%[ directive.\n"), fname, width_val, MAX_STR - 1);
200                         return RET_BUG;
201                     }
202
203                     if ((buf[num_conversion].c = MALLOC(MAX_STR)) == NULL)
204                     {
205                         return MEM_LACK;
206                     }
207                     ptrtab[num_conversion] = buf[num_conversion].c;
208                     type[num_conversion] = SF_S;
209                     break;
210
211                 case 's':
212                     if (l_flag + h_flag)
213                     {
214                         Scierror(998, _("%s: An error occurred: %s\n"), fname, _("Bad conversion."));
215                         return RET_BUG;
216                     }
217
218                     if (width_flag == 0)
219                     {
220                         str_width_flag = 1;
221                     }
222                     if (width_flag == 1 && width_val > MAX_STR - 1)
223                     {
224                         Scierror(998, _("%s: An error occurred: field %d is too long (< %d) for %%s directive.\n"), fname, width_val, MAX_STR - 1);
225                         return RET_BUG;
226                     }
227
228                     if ((buf[num_conversion].c = MALLOC(MAX_STR)) == NULL)
229                     {
230                         return MEM_LACK;
231                     }
232
233                     ptrtab[num_conversion] = buf[num_conversion].c;
234                     type[num_conversion] = SF_S;
235                     break;
236
237                 case 'c':
238                     if (l_flag + h_flag)
239                     {
240                         Scierror(998, _("%s: An error occurred: %s\n"), fname, _("Bad conversion."));
241                         return RET_BUG;
242                     }
243
244                     if (width_flag == 1)
245                     {
246                         nc[num_conversion] = width_val;
247                     }
248                     else
249                     {
250                         nc[num_conversion] = 1;
251                     }
252
253                     if (width_flag == 1 && width_val > MAX_STR - 1)
254                     {
255                         Scierror(998, _("%s: An error occurred: field %d is too long (< %d) for %%c directive.\n"), fname, width_val, MAX_STR - 1);
256                         return RET_BUG;
257                     }
258
259                     if ((buf[num_conversion].c = MALLOC(MAX_STR)) == NULL)
260                     {
261                         return MEM_LACK;
262                     }
263
264                     ptrtab[num_conversion] = buf[num_conversion].c;
265                     type[num_conversion] = SF_C;
266                     break;
267
268                 case 'o':
269                 case 'u':
270                 case 'x':
271                 case 'X':
272                     if (l_flag)
273                     {
274                         ptrtab[num_conversion] = &buf[num_conversion].lui;
275                         type[num_conversion] = SF_LUI;
276                     }
277                     else if (h_flag)
278                     {
279                         ptrtab[num_conversion] = &buf[num_conversion].sui;
280                         type[num_conversion] = SF_SUI;
281                     }
282                     else
283                     {
284                         ptrtab[num_conversion] = &buf[num_conversion].ui;
285                         type[num_conversion] = SF_UI;
286                     }
287                     break;
288
289                 case 'D':
290                     ptrtab[num_conversion] = &buf[num_conversion].li;
291                     type[num_conversion] = SF_LI;
292                     break;
293
294                 case 'n':
295                     n_directive_count++;
296
297                 case 'i':
298                 case 'd':
299                     if (l_flag)
300                     {
301                         ptrtab[num_conversion] = &buf[num_conversion].li;
302                         type[num_conversion] = SF_LI;
303                     }
304                     else if (h_flag)
305                     {
306                         ptrtab[num_conversion] = &buf[num_conversion].si;
307                         type[num_conversion] = SF_SI;
308                     }
309                     else
310                     {
311                         ptrtab[num_conversion] = &buf[num_conversion].i;
312                         type[num_conversion] = SF_I;
313                     }
314                     break;
315
316                 case 'e':
317                 case 'f':
318                 case 'g':
319                 case 'E':
320                 case 'G':
321                     if (h_flag)
322                     {
323                         Scierror(998, _("%s: An error occurred: %s\n"), fname, _("Bad conversion."));
324                         return RET_BUG;
325                     }
326                     else if (l_flag)
327                     {
328                         ptrtab[num_conversion] = &buf[num_conversion].lf;
329                         type[num_conversion] = SF_LF;
330                     }
331                     else
332                     {
333                         ptrtab[num_conversion] = &buf[num_conversion].f;
334                         type[num_conversion] = SF_F;
335                     }
336                     break;
337
338                 default:
339                     Scierror(998, _("%s: An error occurred: %s\n"), fname, _("Bad conversion."));
340                     return RET_BUG;
341             }
342             *currentchar = backupcurrrentchar;
343         }
344     }
345
346     if (str_width_flag == 1)
347     {
348         char *f1 = format;
349         char *f2 = sformat;
350         char *slast = sformat + MAX_STR - 1 - 4;
351
352         while (*f1 != '\0')
353         {
354             int n;
355
356             *f2++ = *f1++;
357
358             if (*(f1 - 1) == '%' && (*(f1) == 's' || *(f1) == '['))
359             {
360                 n = sprintf(f2, "%d", MAX_STR - 1);
361                 f2 += n;
362                 *f2++ = *f1++;
363             }
364
365             if (f2 == slast)
366             {
367                 Scierror(998, _("%s: An error occurred: format is too long (> %d).\n"), fname, MAX_STR - 1);
368                 return RET_BUG;
369             }
370         }
371
372         *f2 = '\0';
373         format = sformat;
374     }
375
376     *retval = (*xxscanf) ((VPTR) target, format,
377                           ptrtab[0], ptrtab[1], ptrtab[2], ptrtab[3], ptrtab[4], ptrtab[5], ptrtab[6], ptrtab[7], ptrtab[8], ptrtab[9],
378                           ptrtab[10], ptrtab[11], ptrtab[12], ptrtab[13], ptrtab[14], ptrtab[15], ptrtab[16], ptrtab[17], ptrtab[18], ptrtab[19],
379                           ptrtab[20], ptrtab[21], ptrtab[22], ptrtab[23], ptrtab[24], ptrtab[25], ptrtab[26], ptrtab[27], ptrtab[28], ptrtab[29],
380                           ptrtab[30], ptrtab[31], ptrtab[32], ptrtab[33], ptrtab[34], ptrtab[35], ptrtab[36], ptrtab[37], ptrtab[38], ptrtab[39],
381                           ptrtab[40], ptrtab[41], ptrtab[42], ptrtab[43], ptrtab[44], ptrtab[45], ptrtab[46], ptrtab[47], ptrtab[48], ptrtab[49],
382                           ptrtab[50], ptrtab[51], ptrtab[52], ptrtab[53], ptrtab[54], ptrtab[55], ptrtab[56], ptrtab[57], ptrtab[58], ptrtab[59],
383                           ptrtab[60], ptrtab[61], ptrtab[62], ptrtab[63], ptrtab[64], ptrtab[65], ptrtab[66], ptrtab[67], ptrtab[68], ptrtab[69],
384                           ptrtab[70], ptrtab[71], ptrtab[72], ptrtab[73], ptrtab[74], ptrtab[75], ptrtab[76], ptrtab[77], ptrtab[78], ptrtab[79],
385                           ptrtab[80], ptrtab[81], ptrtab[82], ptrtab[83], ptrtab[84], ptrtab[85], ptrtab[86], ptrtab[87], ptrtab[88], ptrtab[89],
386                           ptrtab[90], ptrtab[91], ptrtab[92], ptrtab[93], ptrtab[94], ptrtab[95], ptrtab[96], ptrtab[97], ptrtab[98],
387                           ptrtab[MAXSCAN - 1]);
388
389     *nargs = Min(num_conversion + 1, Max(*retval + n_directive_count, 0));
390
391     for (i = 1; i <= *nargs; i++)
392     {
393         if (type[i - 1] == SF_C)
394         {
395             sval = (char *)ptrtab[i - 1];
396             sval[nc[i - 1]] = '\0';
397         }
398     }
399
400     return 0;
401 }
402
403 /*--------------------------------------------------------------------------*/