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