OSDN Git Service

* libI77/backspace.c: Include "config.h".
[pf3gnuchains/gcc-fork.git] / libf2c / libI77 / fmt.c
1 #include "config.h"
2 #include "f2c.h"
3 #include "fio.h"
4 #include "fmt.h"
5 #define skip(s) while(*s==' ') s++
6 #ifdef interdata
7 #define SYLMX 300
8 #endif
9 #ifdef pdp11
10 #define SYLMX 300
11 #endif
12 #ifdef vax
13 #define SYLMX 300
14 #endif
15 #ifndef SYLMX
16 #define SYLMX 300
17 #endif
18 #define GLITCH '\2'
19         /* special quote character for stu */
20 extern int f__cursor,f__scale;
21 extern flag f__cblank,f__cplus; /*blanks in I and compulsory plus*/
22 static struct syl f__syl[SYLMX];
23 int f__parenlvl,f__pc,f__revloc;
24
25  static
26 #ifdef KR_headers
27 char *ap_end(s) char *s;
28 #else
29 char *ap_end(char *s)
30 #endif
31 {       char quote;
32         quote= *s++;
33         for(;*s;s++)
34         {       if(*s!=quote) continue;
35                 if(*++s!=quote) return(s);
36         }
37         if(f__elist->cierr) {
38                 errno = 100;
39                 return(NULL);
40         }
41         f__fatal(100, "bad string");
42         /*NOTREACHED*/ return 0;
43 }
44  static
45 #ifdef KR_headers
46 op_gen(a,b,c,d)
47 #else
48 op_gen(int a, int b, int c, int d)
49 #endif
50 {       struct syl *p= &f__syl[f__pc];
51         if(f__pc>=SYLMX)
52         {       fprintf(stderr,"format too complicated:\n");
53                 sig_die(f__fmtbuf, 1);
54         }
55         p->op=a;
56         p->p1=b;
57         p->p2.i[0]=c;
58         p->p2.i[1]=d;
59         return(f__pc++);
60 }
61 #ifdef KR_headers
62 static char *f_list();
63 static char *gt_num(s,n,n1) char *s; int *n, n1;
64 #else
65 static char *f_list(char*);
66 static char *gt_num(char *s, int *n, int n1)
67 #endif
68 {       int m=0,f__cnt=0;
69         char c;
70         for(c= *s;;c = *s)
71         {       if(c==' ')
72                 {       s++;
73                         continue;
74                 }
75                 if(c>'9' || c<'0') break;
76                 m=10*m+c-'0';
77                 f__cnt++;
78                 s++;
79         }
80         if(f__cnt==0) {
81                 if (!n1)
82                         s = 0;
83                 *n=n1;
84                 }
85         else *n=m;
86         return(s);
87 }
88
89  static
90 #ifdef KR_headers
91 char *f_s(s,curloc) char *s;
92 #else
93 char *f_s(char *s, int curloc)
94 #endif
95 {
96         skip(s);
97         if(*s++!='(')
98         {
99                 return(NULL);
100         }
101         if(f__parenlvl++ ==1) f__revloc=curloc;
102         if(op_gen(RET1,curloc,0,0)<0 ||
103                 (s=f_list(s))==NULL)
104         {
105                 return(NULL);
106         }
107         return(s);
108 }
109
110  static
111 #ifdef KR_headers
112 ne_d(s,p) char *s,**p;
113 #else
114 ne_d(char *s, char **p)
115 #endif
116 {       int n,x,sign=0;
117         struct syl *sp;
118         switch(*s)
119         {
120         default:
121                 return(0);
122         case ':': (void) op_gen(COLON,0,0,0); break;
123         case '$':
124                 (void) op_gen(NONL, 0, 0, 0); break;
125         case 'B':
126         case 'b':
127                 if(*++s=='z' || *s == 'Z') (void) op_gen(BZ,0,0,0);
128                 else (void) op_gen(BN,0,0,0);
129                 break;
130         case 'S':
131         case 's':
132                 if(*(s+1)=='s' || *(s+1) == 'S')
133                 {       x=SS;
134                         s++;
135                 }
136                 else if(*(s+1)=='p' || *(s+1) == 'P')
137                 {       x=SP;
138                         s++;
139                 }
140                 else x=S;
141                 (void) op_gen(x,0,0,0);
142                 break;
143         case '/': (void) op_gen(SLASH,0,0,0); break;
144         case '-': sign=1;
145         case '+':       s++;    /*OUTRAGEOUS CODING TRICK*/
146         case '0': case '1': case '2': case '3': case '4':
147         case '5': case '6': case '7': case '8': case '9':
148                 if (!(s=gt_num(s,&n,0))) {
149  bad:                   *p = 0;
150                         return 1;
151                         }
152                 switch(*s)
153                 {
154                 default:
155                         return(0);
156                 case 'P':
157                 case 'p': if(sign) n= -n; (void) op_gen(P,n,0,0); break;
158                 case 'X':
159                 case 'x': (void) op_gen(X,n,0,0); break;
160                 case 'H':
161                 case 'h':
162                         sp = &f__syl[op_gen(H,n,0,0)];
163                         sp->p2.s = s + 1;
164                         s+=n;
165                         break;
166                 }
167                 break;
168         case GLITCH:
169         case '"':
170         case '\'':
171                 sp = &f__syl[op_gen(APOS,0,0,0)];
172                 sp->p2.s = s;
173                 if((*p = ap_end(s)) == NULL)
174                         return(0);
175                 return(1);
176         case 'T':
177         case 't':
178                 if(*(s+1)=='l' || *(s+1) == 'L')
179                 {       x=TL;
180                         s++;
181                 }
182                 else if(*(s+1)=='r'|| *(s+1) == 'R')
183                 {       x=TR;
184                         s++;
185                 }
186                 else x=T;
187                 if (!(s=gt_num(s+1,&n,0)))
188                         goto bad;
189                 s--;
190                 (void) op_gen(x,n,0,0);
191                 break;
192         case 'X':
193         case 'x': (void) op_gen(X,1,0,0); break;
194         case 'P':
195         case 'p': (void) op_gen(P,1,0,0); break;
196         }
197         s++;
198         *p=s;
199         return(1);
200 }
201
202  static
203 #ifdef KR_headers
204 e_d(s,p) char *s,**p;
205 #else
206 e_d(char *s, char **p)
207 #endif
208 {       int i,im,n,w,d,e,found=0,x=0;
209         char *sv=s;
210         s=gt_num(s,&n,1);
211         (void) op_gen(STACK,n,0,0);
212         switch(*s++)
213         {
214         default: break;
215         case 'E':
216         case 'e':       x=1;
217         case 'G':
218         case 'g':
219                 found=1;
220                 if (!(s=gt_num(s,&w,0))) {
221  bad:
222                         *p = 0;
223                         return 1;
224                         }
225                 if(w==0) break;
226                 if(*s=='.') {
227                         if (!(s=gt_num(s+1,&d,0)))
228                                 goto bad;
229                         }
230                 else d=0;
231                 if(*s!='E' && *s != 'e')
232                         (void) op_gen(x==1?E:G,w,d,0);  /* default is Ew.dE2 */
233                 else {
234                         if (!(s=gt_num(s+1,&e,0)))
235                                 goto bad;
236                         (void) op_gen(x==1?EE:GE,w,d,e);
237                         }
238                 break;
239         case 'O':
240         case 'o':
241                 i = O;
242                 im = OM;
243                 goto finish_I;
244         case 'Z':
245         case 'z':
246                 i = Z;
247                 im = ZM;
248                 goto finish_I;
249         case 'L':
250         case 'l':
251                 found=1;
252                 if (!(s=gt_num(s,&w,0)))
253                         goto bad;
254                 if(w==0) break;
255                 (void) op_gen(L,w,0,0);
256                 break;
257         case 'A':
258         case 'a':
259                 found=1;
260                 skip(s);
261                 if(*s>='0' && *s<='9')
262                 {       s=gt_num(s,&w,1);
263                         if(w==0) break;
264                         (void) op_gen(AW,w,0,0);
265                         break;
266                 }
267                 (void) op_gen(A,0,0,0);
268                 break;
269         case 'F':
270         case 'f':
271                 if (!(s=gt_num(s,&w,0)))
272                         goto bad;
273                 found=1;
274                 if(w==0) break;
275                 if(*s=='.') {
276                         if (!(s=gt_num(s+1,&d,0)))
277                                 goto bad;
278                         }
279                 else d=0;
280                 (void) op_gen(F,w,d,0);
281                 break;
282         case 'D':
283         case 'd':
284                 found=1;
285                 if (!(s=gt_num(s,&w,0)))
286                         goto bad;
287                 if(w==0) break;
288                 if(*s=='.') {
289                         if (!(s=gt_num(s+1,&d,0)))
290                                 goto bad;
291                         }
292                 else d=0;
293                 (void) op_gen(D,w,d,0);
294                 break;
295         case 'I':
296         case 'i':
297                 i = I;
298                 im = IM;
299  finish_I:
300                 if (!(s=gt_num(s,&w,0)))
301                         goto bad;
302                 found=1;
303                 if(w==0) break;
304                 if(*s!='.')
305                 {       (void) op_gen(i,w,0,0);
306                         break;
307                 }
308                 if (!(s=gt_num(s+1,&d,0)))
309                         goto bad;
310                 (void) op_gen(im,w,d,0);
311                 break;
312         }
313         if(found==0)
314         {       f__pc--; /*unSTACK*/
315                 *p=sv;
316                 return(0);
317         }
318         *p=s;
319         return(1);
320 }
321  static
322 #ifdef KR_headers
323 char *i_tem(s) char *s;
324 #else
325 char *i_tem(char *s)
326 #endif
327 {       char *t;
328         int n,curloc;
329         if(*s==')') return(s);
330         if(ne_d(s,&t)) return(t);
331         if(e_d(s,&t)) return(t);
332         s=gt_num(s,&n,1);
333         if((curloc=op_gen(STACK,n,0,0))<0) return(NULL);
334         return(f_s(s,curloc));
335 }
336
337  static
338 #ifdef KR_headers
339 char *f_list(s) char *s;
340 #else
341 char *f_list(char *s)
342 #endif
343 {
344         for(;*s!=0;)
345         {       skip(s);
346                 if((s=i_tem(s))==NULL) return(NULL);
347                 skip(s);
348                 if(*s==',') s++;
349                 else if(*s==')')
350                 {       if(--f__parenlvl==0)
351                         {
352                                 (void) op_gen(REVERT,f__revloc,0,0);
353                                 return(++s);
354                         }
355                         (void) op_gen(GOTO,0,0,0);
356                         return(++s);
357                 }
358         }
359         return(NULL);
360 }
361
362 #ifdef KR_headers
363 pars_f(s) char *s;
364 #else
365 pars_f(char *s)
366 #endif
367 {
368         char *e;
369
370         f__parenlvl=f__revloc=f__pc=0;
371         if((e=f_s(s,0)) == NULL)
372         {
373                 /* Try and delimit the format string.  Parens within
374                    hollerith and quoted strings have to match for this
375                    to work, but it's probably adequate for most needs.
376                    Note that this is needed because a valid CHARACTER
377                    variable passed for FMT= can contain '(I)garbage',
378                    where `garbage' is billions and billions of junk
379                    characters, and it's up to the run-time library to
380                    know where the format string ends by counting parens.
381                    Meanwhile, still treat NUL byte as "hard stop", since
382                    f2c still appends that at end of FORMAT-statement
383                    strings.  */
384
385                 int level=0;
386
387                 for (f__fmtlen=0;
388                         ((*s!=')') || (--level > 0))
389                                 && (*s!='\0')
390                                 && (f__fmtlen<80);
391                         ++s, ++f__fmtlen)
392                 {
393                         if (*s=='(')
394                                 ++level;
395                 }
396                 if (*s==')')
397                         ++f__fmtlen;
398                 return(-1);
399         }
400         f__fmtlen = e - s;
401         return(0);
402 }
403 #define STKSZ 10
404 int f__cnt[STKSZ],f__ret[STKSZ],f__cp,f__rp;
405 flag f__workdone, f__nonl;
406
407  static
408 #ifdef KR_headers
409 type_f(n)
410 #else
411 type_f(int n)
412 #endif
413 {
414         switch(n)
415         {
416         default:
417                 return(n);
418         case RET1:
419                 return(RET1);
420         case REVERT: return(REVERT);
421         case GOTO: return(GOTO);
422         case STACK: return(STACK);
423         case X:
424         case SLASH:
425         case APOS: case H:
426         case T: case TL: case TR:
427                 return(NED);
428         case F:
429         case I:
430         case IM:
431         case A: case AW:
432         case O: case OM:
433         case L:
434         case E: case EE: case D:
435         case G: case GE:
436         case Z: case ZM:
437                 return(ED);
438         }
439 }
440 #ifdef KR_headers
441 integer do_fio(number,ptr,len) ftnint *number; ftnlen len; char *ptr;
442 #else
443 integer do_fio(ftnint *number, char *ptr, ftnlen len)
444 #endif
445 {       struct syl *p;
446         int n,i;
447         for(i=0;i<*number;i++,ptr+=len)
448         {
449 loop:   switch(type_f((p= &f__syl[f__pc])->op))
450         {
451         default:
452                 fprintf(stderr,"unknown code in do_fio: %d\n%.*s\n",
453                         p->op,f__fmtlen,f__fmtbuf);
454                 err(f__elist->cierr,100,"do_fio");
455         case NED:
456                 if((*f__doned)(p))
457                 {       f__pc++;
458                         goto loop;
459                 }
460                 f__pc++;
461                 continue;
462         case ED:
463                 if(f__cnt[f__cp]<=0)
464                 {       f__cp--;
465                         f__pc++;
466                         goto loop;
467                 }
468                 if(ptr==NULL)
469                         return((*f__doend)());
470                 f__cnt[f__cp]--;
471                 f__workdone=1;
472                 if((n=(*f__doed)(p,ptr,len))>0)
473                         errfl(f__elist->cierr,errno,"fmt");
474                 if(n<0)
475                         err(f__elist->ciend,(EOF),"fmt");
476                 continue;
477         case STACK:
478                 f__cnt[++f__cp]=p->p1;
479                 f__pc++;
480                 goto loop;
481         case RET1:
482                 f__ret[++f__rp]=p->p1;
483                 f__pc++;
484                 goto loop;
485         case GOTO:
486                 if(--f__cnt[f__cp]<=0)
487                 {       f__cp--;
488                         f__rp--;
489                         f__pc++;
490                         goto loop;
491                 }
492                 f__pc=1+f__ret[f__rp--];
493                 goto loop;
494         case REVERT:
495                 f__rp=f__cp=0;
496                 f__pc = p->p1;
497                 if(ptr==NULL)
498                         return((*f__doend)());
499                 if(!f__workdone) return(0);
500                 if((n=(*f__dorevert)()) != 0) return(n);
501                 goto loop;
502         case COLON:
503                 if(ptr==NULL)
504                         return((*f__doend)());
505                 f__pc++;
506                 goto loop;
507         case NONL:
508                 f__nonl = 1;
509                 f__pc++;
510                 goto loop;
511         case S:
512         case SS:
513                 f__cplus=0;
514                 f__pc++;
515                 goto loop;
516         case SP:
517                 f__cplus = 1;
518                 f__pc++;
519                 goto loop;
520         case P: f__scale=p->p1;
521                 f__pc++;
522                 goto loop;
523         case BN:
524                 f__cblank=0;
525                 f__pc++;
526                 goto loop;
527         case BZ:
528                 f__cblank=1;
529                 f__pc++;
530                 goto loop;
531         }
532         }
533         return(0);
534 }
535 en_fio(Void)
536 {       ftnint one=1;
537         return(do_fio(&one,(char *)NULL,(ftnint)0));
538 }
539  VOID
540 fmt_bg(Void)
541 {
542         f__workdone=f__cp=f__rp=f__pc=f__cursor=0;
543         f__cnt[0]=f__ret[0]=0;
544 }