mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-03 09:00:21 +00:00
402 lines
7.7 KiB
C
402 lines
7.7 KiB
C
#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;
|
|
long x;
|
|
if (sizeof (long) == sz)
|
|
x = n->il;
|
|
else if (sz == sizeof (char))
|
|
x = n->ic;
|
|
else
|
|
x = n->is;
|
|
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));
|
|
}
|
|
}
|