#include "fido.h" #include #include "fidomem.h" #include "proto.h" /* printf() and all it's relatives: printf The usual, Control-C able cprintf Ditto, not Control-C able mprintf Modem printf lprintf Logfile clprintf Console/Logfile puts The usual, Control-C able cputs Ditto, not Control-C able mputs Modem puts lputs Logfile clputs Console/Logfile sprintf() _fspr() The format engine; this handles the stringID Fido language file text system. */ #define MAXSTR 300 /* largest string we'll handle */ printf(f) char *f; { char buf[MAXSTR]; _fspr(buf,&f); puts(buf); } cprintf(f) char *f; { char buf[MAXSTR]; _fspr(buf,&f); cputs(buf); } mprintf(f) char *f; { char buf[MAXSTR]; _fspr(buf,&f); mputs(buf); } lprintf(f) char *f; { char buf[MAXSTR]; _fspr(buf,&f); lputs(buf); } clprintf(f) char *f; { char buf[MAXSTR]; _fspr(buf,&f); clputs(buf); } puts(s) char *s; { while (*s) { if (*s == 255) { bdos(2,CR); bdos(2,LF); } else bdos(2,*s); ++s; } } cputs(s) char *s; { while (*s) { if (*s == 255) { lconout(CR); lconout(LF); } else lconout(*s); ++s;} } mputs(s) char *s; { while (*s) { if (*s == 255) { mconout(CR); mconout(LF); } else mconoutr(*s); ++s;} } clputs(s) char *s; { cputs(s); lputs(s); } lputs(s) char *s; { while (*s && (cmtfile != -1)) { if (*s == 255) { write(cmtfile,"\r\n",2); } else if (write(cmtfile,s,1) != 1) { close(cmtfile); cmtfile= -1; cprintf(SM+115,"FIDO.LOG"); /* "disk full" */ } ++s; } } sprintf(s,f) char *s,*f; { _fspr(s,&f); } #define B32MASK 0x7fffffff /* strip the long int sign bit */ /* Format string options: "%-0w.p,l{dux}" - left justified (else right) 0 left zero fill w field width , comma separate 1000's l long a base 36 */ char _spr_sepchar = ','; /* 1000's seperator character */ /* Formatted string processor for printf() etc. Will only work on a Lattice long data model. Gross. Plagiarized from Leor Zolman's STDLIB2 for BDS C 1.42. Brain Damage Software still lives on ... This is gross, as it uses funny pointers instead of a structure. Oh well. Also, it is dependent on a char being the same size as an int on the stack. This handles either the Fido stringID junk or an explicit format string: printf(ID,args...); or printf(0,"format string",args...); */ _fspr(line,fmt) char *line, **fmt; { char c, base, *sptr, *format, **s; char lastc, sign, ljflag, zfflag, sepflag; int width, *args; int sizearg,islong; long num; unsigned li; /* index into line, above */ char sb[MAXSTR]; char wb[32]; /* room for largest possible digit string */ unsigned si; /* index to sb[] */ unsigned i,j,l; long *longarg; char **charstararg; /* If the stringID is zero, then a literal format string follows, else locate the format string. */ format= *fmt++; /* ID or format string */ if (format == 0) format= (char *) *fmt++; /* if 0, a format follows, */ else format= (char *)string((unsigned)format); /* else its a string ID */ args = (int *)fmt; lastc= si= li= 0; /* total output line length */ while (c = *format++) if ((c == '%') && (lastc != '\\')) { si= 0; /* output buffer index */ ljflag = zfflag = sepflag= 0; if (*format == '-') { format++; ljflag++; } if (*format == '0') zfflag++; /* test for zero-fill */ width = (isdigit(*format)) ? _gv2(&format) : 0; c= *format++; if (c == ',') { c= *format++; sepflag= 1; } longarg= (long *)args; charstararg= (char **)args; islong= 0; if (c == 'l') { /* if long, */ c= *format++; /* skip the L, */ sizearg= sizeof(long); /* for bumping pointer */ longarg= (long *)args; /* force confusing typing */ num= *longarg; /* get the value, */ islong= 1; } else { sizearg= sizeof(int); num= 0L + *args; } sign= '\0'; switch(toupper(c)) { case 'D': if (num < 0L) { sign= '-'; width--; num= 0L - num; } case 'U': base = 10; goto val; case 'X': base = 16; goto val; case 'O': base = 8; goto val; case 'A': base = 36; goto val; /* _uspr() builds the plain digit string in wb, the Work Buffer. If using comma formatting, then separators are added before the string is moved to sb, the String Buffer. Since Lattice doesn't have an unsigned long, we can't have the hi bit set on positive numbers. Flag overflow with a '*'. */ val: if (islong) { if (num & ~B32MASK) sign= '*'; num &= B32MASK; } else num &= 0x0000ffffL; _uspr(wb,&si,num,base); if ((si > 4) && sepflag) { l = si % 3; if (l == 0) l= 3; /* si= raw string length wb= raw digit string (ie. "12345") sb= working string (ie. "12,345") l= 100's digits counter, MOD 3 i= index into sb[] j= index into wb[] */ for (i= j= 0; j < si;) { sb[i++]= wb[j++]; if ((--l == 0) && (j < si)) sb[i++]= _spr_sepchar; if (l <= 0) l= 3; } si= i; /* see pad: */ } else for (i= 0; i < si; i++) sb[i]= wb[i]; width -= i; if (islong) args= (int *) ++longarg; else ++args; goto pad; case 'C': sb[si]= *(char *)args; if (si < MAXSTR) ++si; ++args; width--; goto pad; case 'S': sptr = *(char **)args; args= (int *) ++charstararg; while (*sptr) { sb[si]= *sptr++; if (si < MAXSTR) ++si; width--; } pad: sb[si]= '\0'; si= 0; if (! ljflag) { while (width-- > 0) { line[li]= (zfflag ? '0' : ' '); if (li < MAXSTR) ++li; } } if (sign) { line[li]= sign; if (li < MAXSTR) ++li; } while (sb[si]) { line[li]= sb[si++]; if (li < MAXSTR) ++li; } if (ljflag) { while (width-- > 0) { line[li]= ' '; if (li < MAXSTR) ++li; } } break; default: line[li]= c; if (li < MAXSTR) ++li; break; } } else { lastc= c; /* for next time through */ line[li]= c; if (li < MAXSTR) ++li; } line[li]= '\0'; } /* Internal routine used by "_spr" to perform ascii- to-decimal conversion and update an associated pointer: */ static int _gv2(sptr) char **sptr; { int n; n = 0; while (isdigit(**sptr)) n = 10 * n + *(*sptr)++ - '0'; return(n); } static char itoctbl[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static _uspr(buff, buffi, n, base) char buff[]; unsigned *buffi; long n; unsigned base; { unsigned length; if ((n < base) && (n >= 0L)) { buff[*buffi]= itoctbl[n]; if (*buffi < MAXSTR) ++(*buffi); buff[*buffi]= '\0'; return(1); } length = _uspr(buff, buffi, (long)(n / base), base); _uspr(buff, buffi, (long)(n % base), base); return (length + 1); }