| #include "config.h" |
| #include "f2c.h" |
| #include "fio.h" |
| #include "fmt.h" |
| |
| extern icilist *f__svic; |
| extern char *f__icptr; |
| |
| static int |
| mv_cur (void) /* shouldn't use fseek because it insists on calling fflush */ |
| /* instead we know too much about stdio */ |
| { |
| int cursor = f__cursor; |
| f__cursor = 0; |
| if (f__external == 0) |
| { |
| if (cursor < 0) |
| { |
| if (f__hiwater < f__recpos) |
| f__hiwater = f__recpos; |
| f__recpos += cursor; |
| f__icptr += cursor; |
| if (f__recpos < 0) |
| err (f__elist->cierr, 110, "left off"); |
| } |
| else if (cursor > 0) |
| { |
| if (f__recpos + cursor >= f__svic->icirlen) |
| err (f__elist->cierr, 110, "recend"); |
| if (f__hiwater <= f__recpos) |
| for (; cursor > 0; cursor--) |
| (*f__putn) (' '); |
| else if (f__hiwater <= f__recpos + cursor) |
| { |
| cursor -= f__hiwater - f__recpos; |
| f__icptr += f__hiwater - f__recpos; |
| f__recpos = f__hiwater; |
| for (; cursor > 0; cursor--) |
| (*f__putn) (' '); |
| } |
| else |
| { |
| f__icptr += cursor; |
| f__recpos += cursor; |
| } |
| } |
| return (0); |
| } |
| if (cursor > 0) |
| { |
| if (f__hiwater <= f__recpos) |
| for (; cursor > 0; cursor--) |
| (*f__putn) (' '); |
| else if (f__hiwater <= f__recpos + cursor) |
| { |
| cursor -= f__hiwater - f__recpos; |
| f__recpos = f__hiwater; |
| for (; cursor > 0; cursor--) |
| (*f__putn) (' '); |
| } |
| else |
| { |
| f__recpos += cursor; |
| } |
| } |
| else if (cursor < 0) |
| { |
| if (cursor + f__recpos < 0) |
| err (f__elist->cierr, 110, "left off"); |
| if (f__hiwater < f__recpos) |
| f__hiwater = f__recpos; |
| f__recpos += cursor; |
| } |
| return (0); |
| } |
| |
| static int |
| wrt_Z (Uint * n, int w, int minlen, ftnlen len) |
| { |
| register char *s, *se; |
| register int i, w1; |
| static int one = 1; |
| static char hex[] = "0123456789ABCDEF"; |
| s = (char *) n; |
| --len; |
| if (*(char *) &one) |
| { |
| /* little endian */ |
| se = s; |
| s += len; |
| i = -1; |
| } |
| else |
| { |
| se = s + len; |
| i = 1; |
| } |
| for (;; s += i) |
| if (s == se || *s) |
| break; |
| w1 = (i * (se - s) << 1) + 1; |
| if (*s & 0xf0) |
| w1++; |
| if (w1 > w) |
| for (i = 0; i < w; i++) |
| (*f__putn) ('*'); |
| else |
| { |
| if ((minlen -= w1) > 0) |
| w1 += minlen; |
| while (--w >= w1) |
| (*f__putn) (' '); |
| while (--minlen >= 0) |
| (*f__putn) ('0'); |
| if (!(*s & 0xf0)) |
| { |
| (*f__putn) (hex[*s & 0xf]); |
| if (s == se) |
| return 0; |
| s += i; |
| } |
| for (;; s += i) |
| { |
| (*f__putn) (hex[*s >> 4 & 0xf]); |
| (*f__putn) (hex[*s & 0xf]); |
| if (s == se) |
| break; |
| } |
| } |
| return 0; |
| } |
| |
| static int |
| wrt_I (Uint * n, int w, ftnlen len, register int base) |
| { |
| int ndigit, sign, spare, i; |
| longint x; |
| char *ans; |
| if (len == sizeof (integer)) |
| x = n->il; |
| else if (len == sizeof (char)) |
| x = n->ic; |
| #ifdef Allow_TYQUAD |
| else if (len == sizeof (longint)) |
| x = n->ili; |
| #endif |
| else |
| x = n->is; |
| ans = f__icvt (x, &ndigit, &sign, base); |
| spare = w - ndigit; |
| if (sign || f__cplus) |
| spare--; |
| if (spare < 0) |
| for (i = 0; i < w; i++) |
| (*f__putn) ('*'); |
| else |
| { |
| for (i = 0; i < spare; i++) |
| (*f__putn) (' '); |
| if (sign) |
| (*f__putn) ('-'); |
| else if (f__cplus) |
| (*f__putn) ('+'); |
| for (i = 0; i < ndigit; i++) |
| (*f__putn) (*ans++); |
| } |
| return (0); |
| } |
| static int |
| wrt_IM (Uint * n, int w, int m, ftnlen len, int base) |
| { |
| int ndigit, sign, spare, i, xsign; |
| longint x; |
| char *ans; |
| if (sizeof (integer) == len) |
| x = n->il; |
| else if (len == sizeof (char)) |
| x = n->ic; |
| #ifdef Allow_TYQUAD |
| else if (len == sizeof (longint)) |
| x = n->ili; |
| #endif |
| else |
| x = n->is; |
| ans = f__icvt (x, &ndigit, &sign, base); |
| if (sign || f__cplus) |
| xsign = 1; |
| else |
| xsign = 0; |
| if (ndigit + xsign > w || m + xsign > w) |
| { |
| for (i = 0; i < w; i++) |
| (*f__putn) ('*'); |
| return (0); |
| } |
| if (x == 0 && m == 0) |
| { |
| for (i = 0; i < w; i++) |
| (*f__putn) (' '); |
| return (0); |
| } |
| if (ndigit >= m) |
| spare = w - ndigit - xsign; |
| else |
| spare = w - m - xsign; |
| for (i = 0; i < spare; i++) |
| (*f__putn) (' '); |
| if (sign) |
| (*f__putn) ('-'); |
| else if (f__cplus) |
| (*f__putn) ('+'); |
| for (i = 0; i < m - ndigit; i++) |
| (*f__putn) ('0'); |
| for (i = 0; i < ndigit; i++) |
| (*f__putn) (*ans++); |
| return (0); |
| } |
| static int |
| wrt_AP (char *s) |
| { |
| char quote; |
| int i; |
| |
| if (f__cursor && (i = mv_cur ())) |
| return i; |
| quote = *s++; |
| for (; *s; s++) |
| { |
| if (*s != quote) |
| (*f__putn) (*s); |
| else if (*++s == quote) |
| (*f__putn) (*s); |
| else |
| return (1); |
| } |
| return (1); |
| } |
| static int |
| wrt_H (int a, char *s) |
| { |
| int i; |
| |
| if (f__cursor && (i = mv_cur ())) |
| return i; |
| while (a--) |
| (*f__putn) (*s++); |
| return (1); |
| } |
| |
| int |
| wrt_L (Uint * n, int len, ftnlen sz) |
| { |
| int i; |
| longint x; |
| #ifdef Allow_TYQUAD |
| if (sizeof (longint) == sz) |
| x = n->ili; |
| else |
| #endif |
| if (sizeof (short ) == sz) |
| x = n->is; |
| else if (sizeof (char) == sz) |
| x = n->ic; |
| else if (sizeof (integer) == sz) |
| x = n->il; |
| |
| for (i = 0; i < len - 1; i++) |
| (*f__putn) (' '); |
| if (x) |
| (*f__putn) ('T'); |
| else |
| (*f__putn) ('F'); |
| return (0); |
| } |
| static int |
| wrt_A (char *p, ftnlen len) |
| { |
| while (len-- > 0) |
| (*f__putn) (*p++); |
| return (0); |
| } |
| static int |
| wrt_AW (char *p, int w, ftnlen len) |
| { |
| while (w > len) |
| { |
| w--; |
| (*f__putn) (' '); |
| } |
| while (w-- > 0) |
| (*f__putn) (*p++); |
| return (0); |
| } |
| |
| static int |
| wrt_G (ufloat * p, int w, int d, int e, ftnlen len) |
| { |
| double up = 1, x; |
| int i = 0, oldscale, n, j; |
| x = len == sizeof (real) ? p->pf : p->pd; |
| if (x < 0) |
| x = -x; |
| if (x < .1) |
| { |
| if (x != 0.) |
| return (wrt_E (p, w, d, e, len)); |
| i = 1; |
| goto have_i; |
| } |
| for (; i <= d; i++, up *= 10) |
| { |
| if (x >= up) |
| continue; |
| have_i: |
| oldscale = f__scale; |
| f__scale = 0; |
| if (e == 0) |
| n = 4; |
| else |
| n = e + 2; |
| i = wrt_F (p, w - n, d - i, len); |
| for (j = 0; j < n; j++) |
| (*f__putn) (' '); |
| f__scale = oldscale; |
| return (i); |
| } |
| return (wrt_E (p, w, d, e, len)); |
| } |
| |
| int |
| w_ed (struct syl * p, char *ptr, ftnlen len) |
| { |
| int i; |
| |
| if (f__cursor && (i = mv_cur ())) |
| return i; |
| switch (p->op) |
| { |
| default: |
| fprintf (stderr, "w_ed, unexpected code: %d\n", p->op); |
| sig_die (f__fmtbuf, 1); |
| case I: |
| return (wrt_I ((Uint *) ptr, p->p1, len, 10)); |
| case IM: |
| return (wrt_IM ((Uint *) ptr, p->p1, p->p2.i[0], len, 10)); |
| |
| /* O and OM don't work right for character, double, complex, */ |
| /* or doublecomplex, and they differ from Fortran 90 in */ |
| /* showing a minus sign for negative values. */ |
| |
| case O: |
| return (wrt_I ((Uint *) ptr, p->p1, len, 8)); |
| case OM: |
| return (wrt_IM ((Uint *) ptr, p->p1, p->p2.i[0], len, 8)); |
| case L: |
| return (wrt_L ((Uint *) ptr, p->p1, len)); |
| case A: |
| return (wrt_A (ptr, len)); |
| case AW: |
| return (wrt_AW (ptr, p->p1, len)); |
| case D: |
| case E: |
| case EE: |
| return (wrt_E ((ufloat *) ptr, p->p1, p->p2.i[0], p->p2.i[1], len)); |
| case G: |
| case GE: |
| return (wrt_G ((ufloat *) ptr, p->p1, p->p2.i[0], p->p2.i[1], len)); |
| case F: |
| return (wrt_F ((ufloat *) ptr, p->p1, p->p2.i[0], len)); |
| |
| /* Z and ZM assume 8-bit bytes. */ |
| |
| case Z: |
| return (wrt_Z ((Uint *) ptr, p->p1, 0, len)); |
| case ZM: |
| return (wrt_Z ((Uint *) ptr, p->p1, p->p2.i[0], len)); |
| } |
| } |
| |
| int |
| w_ned (struct syl * p) |
| { |
| switch (p->op) |
| { |
| default: |
| fprintf (stderr, "w_ned, unexpected code: %d\n", p->op); |
| sig_die (f__fmtbuf, 1); |
| case SLASH: |
| return ((*f__donewrec) ()); |
| case T: |
| f__cursor = p->p1 - f__recpos - 1; |
| return (1); |
| case TL: |
| f__cursor -= p->p1; |
| if (f__cursor < -f__recpos) /* TL1000, 1X */ |
| f__cursor = -f__recpos; |
| return (1); |
| case TR: |
| case X: |
| f__cursor += p->p1; |
| return (1); |
| case APOS: |
| return (wrt_AP (p->p2.s)); |
| case H: |
| return (wrt_H (p->p1, p->p2.s)); |
| } |
| } |