5 #define skip(s) while(*s==' ') s++
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
;
42 f__fatal (100, "bad string");
43 /*NOTREACHED*/ return 0;
47 op_gen (int a
, int b
, int c
, int d
)
49 struct syl
*p
= &f__syl
[f__pc
];
52 fprintf (stderr
, "format too complicated:\n");
53 sig_die (f__fmtbuf
, 1);
61 static char *f_list (char *);
63 gt_num (char *s
, int *n
, int n1
)
65 int m
= 0, f__cnt
= 0;
74 if (c
> '9' || c
< '0')
92 f_s (char *s
, int curloc
)
99 if (f__parenlvl
++ == 1)
101 if (op_gen (RET1
, curloc
, 0, 0) < 0 || (s
= f_list (s
)) == NULL
)
109 ne_d (char *s
, char **p
)
118 (void) op_gen (COLON
, 0, 0, 0);
121 (void) op_gen (NONL
, 0, 0, 0);
125 if (*++s
== 'z' || *s
== 'Z')
126 (void) op_gen (BZ
, 0, 0, 0);
128 (void) op_gen (BN
, 0, 0, 0);
132 if (*(s
+ 1) == 's' || *(s
+ 1) == 'S')
137 else if (*(s
+ 1) == 'p' || *(s
+ 1) == 'P')
144 (void) op_gen (x
, 0, 0, 0);
147 (void) op_gen (SLASH
, 0, 0, 0);
152 s
++; /*OUTRAGEOUS CODING TRICK */
163 if (!(s
= gt_num (s
, &n
, 0)))
176 (void) op_gen (P
, n
, 0, 0);
180 (void) op_gen (X
, n
, 0, 0);
184 sp
= &f__syl
[op_gen (H
, n
, 0, 0)];
193 sp
= &f__syl
[op_gen (APOS
, 0, 0, 0)];
195 if ((*p
= ap_end (s
)) == NULL
)
200 if (*(s
+ 1) == 'l' || *(s
+ 1) == 'L')
205 else if (*(s
+ 1) == 'r' || *(s
+ 1) == 'R')
212 if (!(s
= gt_num (s
+ 1, &n
, 0)))
215 (void) op_gen (x
, n
, 0, 0);
219 (void) op_gen (X
, 1, 0, 0);
223 (void) op_gen (P
, 1, 0, 0);
232 e_d (char *s
, char **p
)
234 int i
, im
, n
, w
, d
, e
, found
= 0, x
= 0;
236 s
= gt_num (s
, &n
, 1);
237 (void) op_gen (STACK
, n
, 0, 0);
248 if (!(s
= gt_num (s
, &w
, 0)))
258 if (!(s
= gt_num (s
+ 1, &d
, 0)))
263 if (*s
!= 'E' && *s
!= 'e')
264 (void) op_gen (x
== 1 ? E
: G
, w
, d
, 0); /* default is Ew.dE2 */
267 if (!(s
= gt_num (s
+ 1, &e
, 0)))
269 (void) op_gen (x
== 1 ? EE
: GE
, w
, d
, e
);
285 if (!(s
= gt_num (s
, &w
, 0)))
289 (void) op_gen (L
, w
, 0, 0);
295 if (*s
>= '0' && *s
<= '9')
297 s
= gt_num (s
, &w
, 1);
300 (void) op_gen (AW
, w
, 0, 0);
303 (void) op_gen (A
, 0, 0, 0);
307 if (!(s
= gt_num (s
, &w
, 0)))
314 if (!(s
= gt_num (s
+ 1, &d
, 0)))
319 (void) op_gen (F
, w
, d
, 0);
324 if (!(s
= gt_num (s
, &w
, 0)))
330 if (!(s
= gt_num (s
+ 1, &d
, 0)))
335 (void) op_gen (D
, w
, d
, 0);
342 if (!(s
= gt_num (s
, &w
, 0)))
349 (void) op_gen (i
, w
, 0, 0);
352 if (!(s
= gt_num (s
+ 1, &d
, 0)))
354 (void) op_gen (im
, w
, d
, 0);
359 f__pc
--; /*unSTACK */
377 s
= gt_num (s
, &n
, 1);
378 if ((curloc
= op_gen (STACK
, n
, 0, 0)) < 0)
380 return (f_s (s
, curloc
));
389 if ((s
= i_tem (s
)) == NULL
)
396 if (--f__parenlvl
== 0)
398 (void) op_gen (REVERT
, f__revloc
, 0, 0);
401 (void) op_gen (GOTO
, 0, 0, 0);
413 f__parenlvl
= f__revloc
= f__pc
= 0;
414 if ((e
= f_s (s
, 0)) == NULL
)
416 /* Try and delimit the format string. Parens within
417 hollerith and quoted strings have to match for this
418 to work, but it's probably adequate for most needs.
419 Note that this is needed because a valid CHARACTER
420 variable passed for FMT= can contain '(I)garbage',
421 where `garbage' is billions and billions of junk
422 characters, and it's up to the run-time library to
423 know where the format string ends by counting parens.
424 Meanwhile, still treat NUL byte as "hard stop", since
425 f2c still appends that at end of FORMAT-statement
431 ((*s
!= ')') || (--level
> 0))
432 && (*s
!= '\0') && (f__fmtlen
< 80); ++s
, ++f__fmtlen
)
446 int f__cnt
[STKSZ
], f__ret
[STKSZ
], f__cp
, f__rp
;
447 flag f__workdone
, f__nonl
;
491 do_fio (ftnint
* number
, char *ptr
, ftnlen len
)
495 for (i
= 0; i
< *number
; i
++, ptr
+= len
)
497 loop
:switch (type_f ((p
= &f__syl
[f__pc
])->op
))
500 fprintf (stderr
, "unknown code in do_fio: %d\n%.*s\n",
501 p
->op
, f__fmtlen
, f__fmtbuf
);
502 err (f__elist
->cierr
, 100, "do_fio");
512 if (f__cnt
[f__cp
] <= 0)
519 return ((*f__doend
) ());
522 if ((n
= (*f__doed
) (p
, ptr
, len
)) > 0)
523 errfl (f__elist
->cierr
, errno
, "fmt");
525 err (f__elist
->ciend
, (EOF
), "fmt");
528 f__cnt
[++f__cp
] = p
->p1
;
532 f__ret
[++f__rp
] = p
->p1
;
536 if (--f__cnt
[f__cp
] <= 0)
543 f__pc
= 1 + f__ret
[f__rp
--];
549 return ((*f__doend
) ());
552 if ((n
= (*f__dorevert
) ()) != 0)
557 return ((*f__doend
) ());
594 return (do_fio (&one
, (char *) NULL
, (ftnint
) 0));
600 f__workdone
= f__cp
= f__rp
= f__pc
= f__cursor
= 0;
601 f__cnt
[0] = f__ret
[0] = 0;