summaryrefslogtreecommitdiffstats
path: root/contrib/libf2c/libI77/fmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libf2c/libI77/fmt.c')
-rw-r--r--contrib/libf2c/libI77/fmt.c602
1 files changed, 602 insertions, 0 deletions
diff --git a/contrib/libf2c/libI77/fmt.c b/contrib/libf2c/libI77/fmt.c
new file mode 100644
index 0000000..fa9b73c
--- /dev/null
+++ b/contrib/libf2c/libI77/fmt.c
@@ -0,0 +1,602 @@
+#include "config.h"
+#include "f2c.h"
+#include "fio.h"
+#include "fmt.h"
+#define skip(s) while(*s==' ') s++
+#ifdef interdata
+#define SYLMX 300
+#endif
+#ifdef pdp11
+#define SYLMX 300
+#endif
+#ifdef vax
+#define SYLMX 300
+#endif
+#ifndef SYLMX
+#define SYLMX 300
+#endif
+#define GLITCH '\2'
+ /* special quote character for stu */
+extern int f__cursor, f__scale;
+extern flag f__cblank, f__cplus; /*blanks in I and compulsory plus */
+static struct syl f__syl[SYLMX];
+int f__parenlvl, f__pc, f__revloc;
+
+static char *
+ap_end (char *s)
+{
+ char quote;
+ quote = *s++;
+ for (; *s; s++)
+ {
+ if (*s != quote)
+ continue;
+ if (*++s != quote)
+ return (s);
+ }
+ if (f__elist->cierr)
+ {
+ errno = 100;
+ return (NULL);
+ }
+ f__fatal (100, "bad string");
+ /*NOTREACHED*/ return 0;
+}
+
+static int
+op_gen (int a, int b, int c, int d)
+{
+ struct syl *p = &f__syl[f__pc];
+ if (f__pc >= SYLMX)
+ {
+ fprintf (stderr, "format too complicated:\n");
+ sig_die (f__fmtbuf, 1);
+ }
+ p->op = a;
+ p->p1 = b;
+ p->p2.i[0] = c;
+ p->p2.i[1] = d;
+ return (f__pc++);
+}
+static char *f_list (char *);
+static char *
+gt_num (char *s, int *n, int n1)
+{
+ int m = 0, f__cnt = 0;
+ char c;
+ for (c = *s;; c = *s)
+ {
+ if (c == ' ')
+ {
+ s++;
+ continue;
+ }
+ if (c > '9' || c < '0')
+ break;
+ m = 10 * m + c - '0';
+ f__cnt++;
+ s++;
+ }
+ if (f__cnt == 0)
+ {
+ if (!n1)
+ s = 0;
+ *n = n1;
+ }
+ else
+ *n = m;
+ return (s);
+}
+
+static char *
+f_s (char *s, int curloc)
+{
+ skip (s);
+ if (*s++ != '(')
+ {
+ return (NULL);
+ }
+ if (f__parenlvl++ == 1)
+ f__revloc = curloc;
+ if (op_gen (RET1, curloc, 0, 0) < 0 || (s = f_list (s)) == NULL)
+ {
+ return (NULL);
+ }
+ return (s);
+}
+
+static int
+ne_d (char *s, char **p)
+{
+ int n, x, sign = 0;
+ struct syl *sp;
+ switch (*s)
+ {
+ default:
+ return (0);
+ case ':':
+ (void) op_gen (COLON, 0, 0, 0);
+ break;
+ case '$':
+ (void) op_gen (NONL, 0, 0, 0);
+ break;
+ case 'B':
+ case 'b':
+ if (*++s == 'z' || *s == 'Z')
+ (void) op_gen (BZ, 0, 0, 0);
+ else
+ (void) op_gen (BN, 0, 0, 0);
+ break;
+ case 'S':
+ case 's':
+ if (*(s + 1) == 's' || *(s + 1) == 'S')
+ {
+ x = SS;
+ s++;
+ }
+ else if (*(s + 1) == 'p' || *(s + 1) == 'P')
+ {
+ x = SP;
+ s++;
+ }
+ else
+ x = S;
+ (void) op_gen (x, 0, 0, 0);
+ break;
+ case '/':
+ (void) op_gen (SLASH, 0, 0, 0);
+ break;
+ case '-':
+ sign = 1;
+ case '+':
+ s++; /*OUTRAGEOUS CODING TRICK */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (!(s = gt_num (s, &n, 0)))
+ {
+ bad:*p = 0;
+ return 1;
+ }
+ switch (*s)
+ {
+ default:
+ return (0);
+ case 'P':
+ case 'p':
+ if (sign)
+ n = -n;
+ (void) op_gen (P, n, 0, 0);
+ break;
+ case 'X':
+ case 'x':
+ (void) op_gen (X, n, 0, 0);
+ break;
+ case 'H':
+ case 'h':
+ sp = &f__syl[op_gen (H, n, 0, 0)];
+ sp->p2.s = s + 1;
+ s += n;
+ break;
+ }
+ break;
+ case GLITCH:
+ case '"':
+ case '\'':
+ sp = &f__syl[op_gen (APOS, 0, 0, 0)];
+ sp->p2.s = s;
+ if ((*p = ap_end (s)) == NULL)
+ return (0);
+ return (1);
+ case 'T':
+ case 't':
+ if (*(s + 1) == 'l' || *(s + 1) == 'L')
+ {
+ x = TL;
+ s++;
+ }
+ else if (*(s + 1) == 'r' || *(s + 1) == 'R')
+ {
+ x = TR;
+ s++;
+ }
+ else
+ x = T;
+ if (!(s = gt_num (s + 1, &n, 0)))
+ goto bad;
+ s--;
+ (void) op_gen (x, n, 0, 0);
+ break;
+ case 'X':
+ case 'x':
+ (void) op_gen (X, 1, 0, 0);
+ break;
+ case 'P':
+ case 'p':
+ (void) op_gen (P, 1, 0, 0);
+ break;
+ }
+ s++;
+ *p = s;
+ return (1);
+}
+
+static int
+e_d (char *s, char **p)
+{
+ int i, im, n, w, d, e, found = 0, x = 0;
+ char *sv = s;
+ s = gt_num (s, &n, 1);
+ (void) op_gen (STACK, n, 0, 0);
+ switch (*s++)
+ {
+ default:
+ break;
+ case 'E':
+ case 'e':
+ x = 1;
+ case 'G':
+ case 'g':
+ found = 1;
+ if (!(s = gt_num (s, &w, 0)))
+ {
+ bad:
+ *p = 0;
+ return 1;
+ }
+ if (w == 0)
+ break;
+ if (*s == '.')
+ {
+ if (!(s = gt_num (s + 1, &d, 0)))
+ goto bad;
+ }
+ else
+ d = 0;
+ if (*s != 'E' && *s != 'e')
+ (void) op_gen (x == 1 ? E : G, w, d, 0); /* default is Ew.dE2 */
+ else
+ {
+ if (!(s = gt_num (s + 1, &e, 0)))
+ goto bad;
+ (void) op_gen (x == 1 ? EE : GE, w, d, e);
+ }
+ break;
+ case 'O':
+ case 'o':
+ i = O;
+ im = OM;
+ goto finish_I;
+ case 'Z':
+ case 'z':
+ i = Z;
+ im = ZM;
+ goto finish_I;
+ case 'L':
+ case 'l':
+ found = 1;
+ if (!(s = gt_num (s, &w, 0)))
+ goto bad;
+ if (w == 0)
+ break;
+ (void) op_gen (L, w, 0, 0);
+ break;
+ case 'A':
+ case 'a':
+ found = 1;
+ skip (s);
+ if (*s >= '0' && *s <= '9')
+ {
+ s = gt_num (s, &w, 1);
+ if (w == 0)
+ break;
+ (void) op_gen (AW, w, 0, 0);
+ break;
+ }
+ (void) op_gen (A, 0, 0, 0);
+ break;
+ case 'F':
+ case 'f':
+ if (!(s = gt_num (s, &w, 0)))
+ goto bad;
+ found = 1;
+ if (w == 0)
+ break;
+ if (*s == '.')
+ {
+ if (!(s = gt_num (s + 1, &d, 0)))
+ goto bad;
+ }
+ else
+ d = 0;
+ (void) op_gen (F, w, d, 0);
+ break;
+ case 'D':
+ case 'd':
+ found = 1;
+ if (!(s = gt_num (s, &w, 0)))
+ goto bad;
+ if (w == 0)
+ break;
+ if (*s == '.')
+ {
+ if (!(s = gt_num (s + 1, &d, 0)))
+ goto bad;
+ }
+ else
+ d = 0;
+ (void) op_gen (D, w, d, 0);
+ break;
+ case 'I':
+ case 'i':
+ i = I;
+ im = IM;
+ finish_I:
+ if (!(s = gt_num (s, &w, 0)))
+ goto bad;
+ found = 1;
+ if (w == 0)
+ break;
+ if (*s != '.')
+ {
+ (void) op_gen (i, w, 0, 0);
+ break;
+ }
+ if (!(s = gt_num (s + 1, &d, 0)))
+ goto bad;
+ (void) op_gen (im, w, d, 0);
+ break;
+ }
+ if (found == 0)
+ {
+ f__pc--; /*unSTACK */
+ *p = sv;
+ return (0);
+ }
+ *p = s;
+ return (1);
+}
+static char *
+i_tem (char *s)
+{
+ char *t;
+ int n, curloc;
+ if (*s == ')')
+ return (s);
+ if (ne_d (s, &t))
+ return (t);
+ if (e_d (s, &t))
+ return (t);
+ s = gt_num (s, &n, 1);
+ if ((curloc = op_gen (STACK, n, 0, 0)) < 0)
+ return (NULL);
+ return (f_s (s, curloc));
+}
+
+static char *
+f_list (char *s)
+{
+ for (; *s != 0;)
+ {
+ skip (s);
+ if ((s = i_tem (s)) == NULL)
+ return (NULL);
+ skip (s);
+ if (*s == ',')
+ s++;
+ else if (*s == ')')
+ {
+ if (--f__parenlvl == 0)
+ {
+ (void) op_gen (REVERT, f__revloc, 0, 0);
+ return (++s);
+ }
+ (void) op_gen (GOTO, 0, 0, 0);
+ return (++s);
+ }
+ }
+ return (NULL);
+}
+
+int
+pars_f (char *s)
+{
+ char *e;
+
+ f__parenlvl = f__revloc = f__pc = 0;
+ if ((e = f_s (s, 0)) == NULL)
+ {
+ /* Try and delimit the format string. Parens within
+ hollerith and quoted strings have to match for this
+ to work, but it's probably adequate for most needs.
+ Note that this is needed because a valid CHARACTER
+ variable passed for FMT= can contain '(I)garbage',
+ where `garbage' is billions and billions of junk
+ characters, and it's up to the run-time library to
+ know where the format string ends by counting parens.
+ Meanwhile, still treat NUL byte as "hard stop", since
+ f2c still appends that at end of FORMAT-statement
+ strings. */
+
+ int level = 0;
+
+ for (f__fmtlen = 0;
+ ((*s != ')') || (--level > 0))
+ && (*s != '\0') && (f__fmtlen < 80); ++s, ++f__fmtlen)
+ {
+ if (*s == '(')
+ ++level;
+ }
+ if (*s == ')')
+ ++f__fmtlen;
+ return (-1);
+ }
+ f__fmtlen = e - s;
+ return (0);
+}
+
+#define STKSZ 10
+int f__cnt[STKSZ], f__ret[STKSZ], f__cp, f__rp;
+flag f__workdone, f__nonl;
+
+static int
+type_f (int n)
+{
+ switch (n)
+ {
+ default:
+ return (n);
+ case RET1:
+ return (RET1);
+ case REVERT:
+ return (REVERT);
+ case GOTO:
+ return (GOTO);
+ case STACK:
+ return (STACK);
+ case X:
+ case SLASH:
+ case APOS:
+ case H:
+ case T:
+ case TL:
+ case TR:
+ return (NED);
+ case F:
+ case I:
+ case IM:
+ case A:
+ case AW:
+ case O:
+ case OM:
+ case L:
+ case E:
+ case EE:
+ case D:
+ case G:
+ case GE:
+ case Z:
+ case ZM:
+ return (ED);
+ }
+}
+integer
+do_fio (ftnint * number, char *ptr, ftnlen len)
+{
+ struct syl *p;
+ int n, i;
+ for (i = 0; i < *number; i++, ptr += len)
+ {
+ loop:switch (type_f ((p = &f__syl[f__pc])->op))
+ {
+ default:
+ fprintf (stderr, "unknown code in do_fio: %d\n%.*s\n",
+ p->op, f__fmtlen, f__fmtbuf);
+ err (f__elist->cierr, 100, "do_fio");
+ case NED:
+ if ((*f__doned) (p))
+ {
+ f__pc++;
+ goto loop;
+ }
+ f__pc++;
+ continue;
+ case ED:
+ if (f__cnt[f__cp] <= 0)
+ {
+ f__cp--;
+ f__pc++;
+ goto loop;
+ }
+ if (ptr == NULL)
+ return ((*f__doend) ());
+ f__cnt[f__cp]--;
+ f__workdone = 1;
+ if ((n = (*f__doed) (p, ptr, len)) > 0)
+ errfl (f__elist->cierr, errno, "fmt");
+ if (n < 0)
+ err (f__elist->ciend, (EOF), "fmt");
+ continue;
+ case STACK:
+ f__cnt[++f__cp] = p->p1;
+ f__pc++;
+ goto loop;
+ case RET1:
+ f__ret[++f__rp] = p->p1;
+ f__pc++;
+ goto loop;
+ case GOTO:
+ if (--f__cnt[f__cp] <= 0)
+ {
+ f__cp--;
+ f__rp--;
+ f__pc++;
+ goto loop;
+ }
+ f__pc = 1 + f__ret[f__rp--];
+ goto loop;
+ case REVERT:
+ f__rp = f__cp = 0;
+ f__pc = p->p1;
+ if (ptr == NULL)
+ return ((*f__doend) ());
+ if (!f__workdone)
+ return (0);
+ if ((n = (*f__dorevert) ()) != 0)
+ return (n);
+ goto loop;
+ case COLON:
+ if (ptr == NULL)
+ return ((*f__doend) ());
+ f__pc++;
+ goto loop;
+ case NONL:
+ f__nonl = 1;
+ f__pc++;
+ goto loop;
+ case S:
+ case SS:
+ f__cplus = 0;
+ f__pc++;
+ goto loop;
+ case SP:
+ f__cplus = 1;
+ f__pc++;
+ goto loop;
+ case P:
+ f__scale = p->p1;
+ f__pc++;
+ goto loop;
+ case BN:
+ f__cblank = 0;
+ f__pc++;
+ goto loop;
+ case BZ:
+ f__cblank = 1;
+ f__pc++;
+ goto loop;
+ }
+ }
+ return (0);
+}
+
+int
+en_fio (void)
+{
+ ftnint one = 1;
+ return (do_fio (&one, (char *) NULL, (ftnint) 0));
+}
+
+void
+fmt_bg (void)
+{
+ f__workdone = f__cp = f__rp = f__pc = f__cursor = 0;
+ f__cnt[0] = f__ret[0] = 0;
+}
OpenPOWER on IntegriCloud