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