fprintf, fscanf & sscanf: Clearly tag them as obsolete
[scilab.git] / scilab / modules / fileio / macros / sscanf.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) XXXX-2008 - INRIA
3 // Copyright (C) 2008 - DIGITEO - Allan CORNET
4 //
5 // This file must be used under the terms of the CeCILL.
6 // This source file is licensed as described in the file COPYING, which
7 // you should have received as part of this distribution.  The terms
8 // are also available at
9 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10
11
12 function varargout = sscanf(buf, frmt)
13
14   // sscanf - Emulator of C language sscanf
15
16   warnobsolete("msscanf","5.5.0");
17
18   [lhs,rhs]  = argn(0);
19   MAXLHS = 50;
20   if lhs > MAXLHS then
21     error(999, msprintf(gettext("%s: Wrong number of output argument(s).\n"),"sscanf"));x
22   end
23
24   hexdigits  = [string(0:9),'a','b','c','d','e','f','A','B','C','D','E','F']
25   hexvalues  = [0:15,10,11,12,13,14,15];
26   kbuf       = 1;
27
28   sbuf       = length(buf);
29   nv         = lhs;
30
31   if type(buf)<>10 then
32     error(999, msprintf(gettext("%s: Wrong type for input argument #%d: A String expected.\n"),"sscanf",1));
33   end
34
35   if size(buf,"*")<>1 then
36     error(999, msprintf(gettext("%s: Wrong size for input argument #%d: A String expected.\n"),"sscanf",1));
37   end
38
39   if type(frmt)<>10 then
40     error(999, msprintf(gettext("%s: Wrong type for input argument #%d: A String expected.\n"),"sscanf",2));
41   end
42
43   if size(frmt,"*")<>1 then
44     error(999, msprintf(gettext("%s: Wrong size for input argument #%d: A String expected.\n"),"sscanf",2));
45   end
46
47   lb          = 1;
48   lfmt        = length(frmt);
49   il          = 0;
50   count       = 0; // argument counter
51
52   while il <= lfmt do
53
54     [str, flags, width, typemod, scanfconversiontype, err] = next_scanf_format();
55
56     if err==1 then
57       error(msprintf(gettext("%s: Incorrect format.\n")),"sscanf");
58     end
59
60     str = strcat(str);
61     ns  = length(str);
62
63     if part(buf,lb:lb+ns-1)<>str then
64       error(msprintf(gettext("%s: Invalid conversion.\n")),"sscanf");
65     end
66
67     lb=lb+ns
68
69     if scanfconversiontype<>[] then
70       [v,nc,err] = next_scanf_value(part(buf,lb:sbuf),str,flags,width,typemod,scanfconversiontype)
71       if err==1 then
72         error(msprintf(gettext("%s: end of input reached before final conversion.\n")),"sscanf");
73       elseif err==2 then
74         error(msprintf(gettext("%s: Invalid conversion.\n")),"sscanf");
75       end
76       if v<>[] then
77         count=count+1;
78         execstr("v"+string(count)+"=v");
79       end
80       lb = lb+nc-1;
81     end
82   end
83
84   for k=count+1:lhs
85     execstr("v"+string(k)+"=[]");
86   end
87
88   v = 'v';
89   args = strcat( v(ones(count,1)) + string(1:count)',',');
90   execstr('varargout = list(' + args + ');');
91
92 endfunction
93
94
95 // =============================================================================
96 // next_scanf_value
97 // =============================================================================
98
99 function [v, lb, err] = next_scanf_value(buf, str, flags, width, typemod, scanfconversiontype)
100
101   intf   = ['d','i','o','u','x','X']
102   floatf = ['f','e','E','g','G']
103   strf   = ['c','s']
104   lbuf   = length(buf);
105
106   if width==[] | width==0 then
107     width=length(buf);
108   end
109
110   err = 0;
111   cc  = convstr(scanfconversiontype,'l');
112   lb  = 1;
113   x   = emptystr();
114
115   if cc<>"c" then //skip initial blanks
116     while %t do
117       ch = part(buf,lb);
118       if ch==' '&lb<=lbuf then
119         lb=lb+1
120       elseif ch=='\'&part(buf,lb+1)=='n' then
121         lb=lb+2
122       else
123         break;
124       end
125     end
126     if lb>lbuf then
127       err=1
128       v=[];
129       return;
130     end
131   end
132
133   if cc=="d"|cc=="i"|cc=="u" then
134     ll = 0;
135     ch = part(buf,lb);
136
137     if ch=="+" | ch=="-" then
138       if cc=='u'&ch=='-' then
139         err = 2;
140         v   = [];
141         return;
142       else
143         x   = x+ch;
144         lb  = lb+1;
145         ll  = ll+1;
146       end
147     end
148
149     while isdigit(part(buf,lb))&ll<width&lb<=lbuf do
150       x  = x+part(buf,lb);
151       lb = lb+1;
152       ll = ll+1;
153     end
154
155     if length(x)>0 then
156       v = evstr(x);
157     else
158       v = [];
159     end
160
161
162   elseif cc=="o" then
163
164     ll =0;
165     v  =0
166
167     while isdigit(part(buf,lb))&ll<width&lb<=lbuf do
168       v=8*v+evstr(part(buf,lb))
169       lb=lb+1
170       ll=ll+1
171     end
172
173
174
175   elseif cc=="x" then
176
177     ll = 0;
178     v  = 0;
179     c  = part(buf,lb);
180     k  = find(c==hexdigits);
181
182     while k<>[] & ll<width & lb<=lbuf do
183       v   = 16*v+hexvalues(k);
184       lb  = lb+1;
185       ll  = ll+1;
186       c   = part(buf,lb);
187       k   = find(c==hexdigits);
188     end
189
190
191   elseif cc=="f"|cc=="e"|cc=="g" then
192
193     ll = 0;
194     ch = part(buf,lb)
195
196     if ch=="+"|ch=="-" then
197       x  = x+ch;
198       lb = lb+1;
199       ll = ll+1;
200     end
201
202     if part(buf,lb:min(lb+2,lb+width-ll))=='INF' then
203       v  = %inf;
204       lb = lb+3;
205
206     elseif part(buf,lb:min(lb+2,lb+width-ll))=='NaN'
207       v  = %nan;
208       lb = lb+3;
209
210     else
211
212       while isdigit(part(buf,lb))&ll<width&lb<=lbuf do
213         x  = x  + part(buf,lb);
214         lb = lb + 1;
215         ll = ll + 1;
216       end
217
218       ch = part(buf,lb);
219
220       if ch=="." & ll<width & lb<=lbuf then
221         x  = x  + ".";
222         lb = lb + 1;
223         ll = ll + 1;
224
225         while isdigit(part(buf,lb))&ll<width&lb<=lbuf do
226           x  = x  + part(buf,lb);
227           lb = lb + 1;
228           ll = ll + 1;
229         end
230
231       end
232
233       ch=part(buf,lb)
234
235       if (ch=='e'|ch=='E')&ll<width&lb<=lbuf then
236
237         x  = x  + 'e';
238         lb = lb + 1;
239         ll = ll + 1;
240         ch = part(buf,lb);
241
242         if (ch=='+'|ch=='-') & ll<width & lb<=lbuf then
243           x  = x+ch;
244           lb = lb+1;
245           ll = ll+1;
246         end
247
248         while isdigit(part(buf,lb))&ll<width&lb<=lbuf do
249           x  = x  + part(buf,lb);
250           lb = lb + 1;
251           ll = ll + 1;
252         end
253
254       end
255
256       if length(x)>0 then
257         v=evstr(x)
258       else
259         v=[]
260       end
261     end
262
263   elseif cc=="c" then
264
265     if lb>lbuf then
266       err=1
267       return
268     end
269
270     v=part(buf,lb);
271
272   elseif cc=="s" then
273     ll=0
274     ch=part(buf,lb)
275     while ch<>' '&lb<=lbuf&ll<width do
276       x  = x+ch;
277       lb = lb+1;
278       ll = ll+1;
279       ch = part(buf,lb);
280     end
281
282     v = x;
283   end
284
285   if flags=='*' then
286     v=[];
287   end
288
289 endfunction
290
291
292 // =============================================================================
293 // next_scanf_format
294 // =============================================================================
295
296 function [str, flags, width, typemod, scanfconversiontype, err] = next_scanf_format()
297
298   //Scan frmt for % escapes and print out the arguments.
299   err     = 0;
300   str     = emptystr();
301   kstr    = 1;
302   width   = [];
303   prec    = [];
304   flags   = [];
305   typemod = [];
306   scanfconversiontype = [];
307   il      = il+1;
308
309   if il>lfmt then
310     [il,count] = resume(il,count);
311   end
312
313   c = part(frmt,il);
314
315   while c<>"%" then
316     if c=='\' then
317       if part(frmt,il+1)=='n' then
318         str  = [str;emptystr()];
319         kstr = kstr+1
320       end
321       il=il+1;
322     else
323       str(kstr)=str(kstr)+c
324     end
325
326     il=il+1
327
328     if il>lfmt then break, end
329
330     c=part(frmt,il);
331   end
332
333   if il>lfmt then
334     [il,count] = resume(il,count);
335   end
336
337   if part(frmt,il+1)=='%' then
338     str(kstr)  = str(kstr)+'%';
339     il         = il+1;
340     [il,count] = resume(il,count);
341   end
342
343   //beginning of a format
344
345   //get flags
346   flags = [];
347   il    = il+1;
348   c     = part(frmt,il);
349
350   if c=="*" then
351     flags = "*";
352     il    = il+1;
353     c     = part(frmt,il)
354   end
355
356   width = [];
357
358   if isdigit(c) then
359     // get width
360     width = 0;
361     while isdigit(c) do
362       width = 10*width+evstr(c);
363       il    = il+1;
364       if il>lfmt then
365         err=1;
366         return;
367       end
368       c = part(frmt,il)
369     end
370   end
371
372   // get type modifier
373   typemod = [];
374   if c=='l'| c=='L'|c=='h' then
375     typemod = c;
376     il      = il+1;
377
378     if il>lfmt then
379       err=1;
380       return;
381     end
382
383     c = part(frmt,il);
384   end
385
386   //get conversion
387   scanfconversiontype       = c;
388   [il, count] = resume(il, count);
389
390 endfunction