|
|
1.1 root 1: /* doprnt.c - _doprnt, _prt10, _prt8, _prt16 */
2:
3: #define MAXSTR 80
4: #define LOCAL static
5:
6: /*------------------------------------------------------------------------
7: * _doprnt -- format and write output using 'func' to write characters
8: *------------------------------------------------------------------------
9: */
10: _doprnt(fmt, args, func, farg) /* adapted by S. Salisbury, Purdue U. */
11: char *fmt; /* Format string for printf */
12: int *args; /* Arguments to printf */
13: int (*func)(); /* Function to put a character */
14: int farg; /* Argument to func */
15: {
16: int c;
17: int i;
18: int f; /* The format character (comes after %) */
19: char *str; /* Running pointer in string */
20: char string[20]; /* The string str points to this output */
21: /* from number conversion */
22: int length; /* Length of string "str" */
23: char fill; /* Fill character (' ' or '0') */
24: int leftjust; /* 0 = right-justified, else left-just. */
25: int fmax,fmin; /* Field specifications % MIN . MAX s */
26: int leading; /* No. of leading/trailing fill chars. */
27: char sign; /* Set to '-' for negative decimals */
28: char digit1; /* Offset to add to first numeric digit */
29:
30: for(;;) {
31: /* Echo characters until '%' or end of fmt string */
32: while( (c = *fmt++) != '%' ) {
33: if( c == '\0' )
34: return;
35: (*func)(farg,c);
36: }
37: /* Echo "...%%..." as '%' */
38: if( *fmt == '%' ) {
39: (*func)(farg,*fmt++);
40: continue;
41: }
42: /* Check for "%-..." == Left-justified output */
43: if (leftjust = ((*fmt=='-') ? 1 : 0) )
44: fmt++;
45: /* Allow for zero-filled numeric outputs ("%0...") */
46: fill = (*fmt=='0') ? *fmt++ : ' ';
47: /* Allow for minimum field width specifier for %d,u,x,o,c,s*/
48: /* Also allow %* for variable width (%0* as well) */
49: fmin = 0;
50: if( *fmt == '*' ) {
51: fmin = *args++;
52: ++fmt;
53: }
54: else while( '0' <= *fmt && *fmt <= '9' ) {
55: fmin = fmin * 10 + *fmt++ - '0';
56: }
57: /* Allow for maximum string width for %s */
58: fmax = 0;
59: if( *fmt == '.' ) {
60: if( *(++fmt) == '*' ) {
61: fmax = *args++;
62: ++fmt;
63: }
64: else while( '0' <= *fmt && *fmt <= '9' ) {
65: fmax = fmax * 10 + *fmt++ - '0';
66: }
67: }
68: if (*fmt == 'l') /* long */
69: fmt++;
70: str = string;
71: if( (f= *fmt++) == '\0' ) {
72: (*func)(farg,'%');
73: return;
74: }
75: sign = '\0'; /* sign == '-' for negative decimal */
76:
77: switch( f ) {
78: case 'c' :
79: string[0] = (char) *args;
80: string[1] = '\0';
81: fmax = 0;
82: fill = ' ';
83: break;
84:
85: case 's' :
86: str = (char *) *args;
87: fill = ' ';
88: break;
89:
90: case 'D' :
91: case 'd' :
92: if ( *args < 0 ) {
93: sign = '-';
94: *args = -*args;
95: }
96: case 'U':
97: case 'u':
98: _prt10(*args, str);
99: fmax = 0;
100: break;
101:
102: case 'O' :
103: case 'o' :
104: _prt8(*args, str);
105: fmax = 0;
106: break;
107:
108: case 'X' :
109: case 'x' :
110: _prt16(*args, str);
111: fmax = 0;
112: break;
113:
114: default :
115: (*func)(farg,f);
116: break;
117: }
118: args++;
119: for(length = 0; str[length] != '\0'; length++)
120: ;
121: if ( fmin > MAXSTR || fmin < 0 )
122: fmin = 0;
123: if ( fmax > MAXSTR || fmax < 0 )
124: fmax = 0;
125: leading = 0;
126: if ( fmax != 0 || fmin != 0 ) {
127: if ( fmax != 0 )
128: if ( length > fmax )
129: length = fmax;
130: if ( fmin != 0 )
131: leading = fmin - length;
132: if ( sign == '-' )
133: --leading;
134: }
135: if( sign == '-' && fill == '0' )
136: (*func)(farg,sign);
137: if( leftjust == 0 )
138: for( i = 0; i < leading; i++ )
139: (*func)(farg,fill);
140: if( sign == '-' && fill == ' ' )
141: (*func)(farg,sign);
142: for( i = 0 ; i < length ; i++ )
143: (*func)(farg,str[i]);
144: if ( leftjust != 0 )
145: for( i = 0; i < leading; i++ )
146: (*func)(farg,fill);
147: }
148: }
149:
150: LOCAL _prt10(num,str)
151: unsigned long num;
152: char *str;
153: {
154: int i;
155: char c, temp[11];
156:
157: temp[0] = '\0';
158: for(i = 1; i <= 10; i++) {
159: temp[i] = num % 10 + '0';
160: num /= 10;
161: }
162: for(i = 10; temp[i] == '0'; i--);
163: if( i == 0 )
164: i++;
165: while( i >= 0 )
166: *str++ = temp[i--];
167: }
168:
169: LOCAL _prt8(num,str)
170: unsigned long num;
171: char *str;
172: {
173: int i;
174: char c, temp[12];
175:
176: temp[0] = '\0';
177: for(i = 1; i <= 11; i++) {
178: temp[i] = (num & 07) + '0';
179: num = num >> 3;
180: }
181: temp[11] &= '3';
182: for(i = 11; temp[i] == '0'; i--);
183: if( i == 0 )
184: i++;
185: while( i >= 0 )
186: *str++ = temp[i--];
187: }
188:
189: LOCAL _prt16(num,str)
190: unsigned long num;
191: char *str;
192: {
193: int i;
194: char c, temp[9];
195:
196: temp[0] = '\0';
197: for(i = 1; i <= 8; i++) {
198: temp[i] = "0123456789abcdef"[num & 0x0f];
199: num = num >> 4;
200: }
201: for(i = 8; temp[i] == '0'; i--);
202: if( i == 0 )
203: i++;
204: while( i >= 0 )
205: *str++ = temp[i--];
206: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.