/**************************************************************************/ /*** format.c: format routines ***/ /*** Author: Christopher M. Caldwell of IO Software, Inc. ***/ /*** Created: 09-Jul-86 ***/ /*** "Do with as ye may" ***/ /**************************************************************************/ #include #include #define PF_COUNT 0 #define PF_ARRAY 1 #define PF_PUTC 2 #define then #define TRUE 1 #define FALSE 0 static char *al; extern char *malloc(); int lcase(c) char c; { return( isupper(c) ? tolower(c) : c ); } int ucase(c) char c; { return( islower(c) ? toupper(c) : c ); } int digtobin(c) char c; { return( c<='9' ? c-'0' : lcase(c)-'a'+10 ); } char bintodig(i)int i; { return ( i<=9 ? i+'0' : i+'a'-10 ); } int isbase( c, b ) /* Return TRUE if character c is digit of base b. Similar to isdigit, but allows bases with letters and won't except "9" in base 8, etc. */ char c; int b; { if( !isdigit(c) && !isalpha(c) ) then return FALSE; else return( c<='9' ? (c-'0'36 || *fs!='_' ) then break; pbase = nm; fs++; } } switch( c ) { case 'r': pf_right = nm; break; case 'l': pf_left = nm; break; case 'c': pf_center = nm; break; case '.': pf_dec = nm; break; case 'm': pf_max = nm; break; case 'b': pf_base = nm; break; case 'n': pf_iter = nm; break; case 'p': pf_pad = nm; break; case 'u': pf_unsigned = nm; break; } } bufcnt = 0; switch( t ) { case 's': if( pf_string == NULL ) then cp = "(null)"; else cp = pf_string; bufcnt = strlen( cp ); break; case 'S': saveal = al; pf(pf_string,PF_COUNT,&bufcnt,NULL,NULL); al = saveal; cp = malloc( bufcnt+1 ); pf(pf_string,PF_ARRAY,NULL,cp,NULL); break; case 'c': buf[bufcnt++] = pf_char; cp = buf; break; case 'i': pf_char = ( pf_int < 0 ); if( pf_int >= 0 || !pf_unsigned ) then { do { buf[100-(++bufcnt)] = bintodig( abs(pf_int%pf_base) ); pf_int /= pf_base; } while( pf_int != 0 ); if(pf_char) then buf[100-(++bufcnt)]='-'; cp = buf; cp += (100 - bufcnt); } else { c = pf_int & 1; pf_int >>= 1; pf_int &= (1<<(sizeof(pf_int)-1)); c = c + ((pf_int%(pf_base>>1)) << 1); pf_int /= (pf_base>>1); buf[100-(++bufcnt)] = bintodig( c ); while( pf_int != 0 ) { buf[100-(++bufcnt)] = bintodig( abs(pf_int%pf_base) ); pf_int /= pf_base; } cp = buf; cp += (100 - bufcnt); } break; case 'l': pf_char = ( pf_long < 0 ); if( pf_long >= 0 || !pf_unsigned ) then { do { buf[100-(++bufcnt)] = bintodig( abs((int)(pf_long%pf_base)) ); pf_long /= pf_base; } while( pf_long != 0 ); if(pf_char) then buf[100-(++bufcnt)]='-'; cp = buf; cp += (100 - bufcnt); } else { c = pf_long & 1; pf_long >>= 1; pf_long &= (1<<(sizeof(pf_long)-1)); c = c + ((pf_long%(pf_base>>1)) << 1); pf_long /= (pf_base>>1); buf[100-(++bufcnt)] = bintodig( c ); while( pf_long != 0 ) { buf[100-(++bufcnt)] = bintodig( abs((int)(pf_long%pf_base)) ); pf_long /= pf_base; } cp = buf; cp += (100 - bufcnt); } break; case 'f': if( pf_double < 0 ) then { buf[bufcnt++] = '-'; pf_double = -pf_double; } ind = 0; for(pnum=1.0; pnum<=pf_double; pnum*=pf_base) ind--; pnum /= pf_base; do { if( ind++ == 0 ) then buf[bufcnt++]='.'; c = (int)(pf_double/pnum); buf[bufcnt++] = bintodig( c ); pf_double -= (pnum*c); pnum /= pf_base; } while( ind < pf_dec ); cp = buf; break; } if( bufcnt > pf_max && pf_max > 0 ) then bufcnt = pf_max; if( pf_center > 0 ) then { pf_left = ( pf_center - bufcnt ) / 2; pf_right = pf_center - pf_left - bufcnt; } else { pf_left -= bufcnt; pf_right -= bufcnt; } while( pf_iter-- > 0 ) { for( ind=0; ind