Commit | Line | Data |
79072805 |
1 | void |
2 | do_sprintf(TARG,len,sarg) |
3 | register STR *TARG; |
4 | register int len; |
5 | register STR **sarg; |
6 | { |
7 | register char *s; |
8 | register char *t; |
9 | register char *f; |
10 | bool dolong; |
11 | #ifdef QUAD |
12 | bool doquad; |
13 | #endif /* QUAD */ |
14 | char ch; |
15 | register char *send; |
16 | register STR *arg; |
17 | char *xs; |
18 | int xlen; |
19 | int pre; |
20 | int post; |
21 | double value; |
22 | |
23 | str_set(TARG,""); |
24 | len--; /* don't count pattern string */ |
25 | t = s = str_get(*sarg); |
26 | send = s + (*sarg)->str_cur; |
27 | sarg++; |
28 | for ( ; ; len--) { |
29 | |
30 | /*SUPPRESS 560*/ |
31 | if (len <= 0 || !(arg = *sarg++)) |
32 | arg = &str_no; |
33 | |
34 | /*SUPPRESS 530*/ |
35 | for ( ; t < send && *t != '%'; t++) ; |
36 | if (t >= send) |
37 | break; /* end of format string, ignore extra args */ |
38 | f = t; |
39 | *buf = '\0'; |
40 | xs = buf; |
41 | #ifdef QUAD |
42 | doquad = |
43 | #endif /* QUAD */ |
44 | dolong = FALSE; |
45 | pre = post = 0; |
46 | for (t++; t < send; t++) { |
47 | switch (*t) { |
48 | default: |
49 | ch = *(++t); |
50 | *t = '\0'; |
51 | (void)sprintf(xs,f); |
52 | len++, sarg--; |
53 | xlen = strlen(xs); |
54 | break; |
55 | case '0': case '1': case '2': case '3': case '4': |
56 | case '5': case '6': case '7': case '8': case '9': |
57 | case '.': case '#': case '-': case '+': case ' ': |
58 | continue; |
59 | case 'l': |
60 | #ifdef QUAD |
61 | if (dolong) { |
62 | dolong = FALSE; |
63 | doquad = TRUE; |
64 | } else |
65 | #endif |
66 | dolong = TRUE; |
67 | continue; |
68 | case 'c': |
69 | ch = *(++t); |
70 | *t = '\0'; |
71 | xlen = (int)str_gnum(arg); |
72 | if (strEQ(f,"%c")) { /* some printfs fail on null chars */ |
73 | *xs = xlen; |
74 | xs[1] = '\0'; |
75 | xlen = 1; |
76 | } |
77 | else { |
78 | (void)sprintf(xs,f,xlen); |
79 | xlen = strlen(xs); |
80 | } |
81 | break; |
82 | case 'D': |
83 | dolong = TRUE; |
84 | /* FALL THROUGH */ |
85 | case 'd': |
86 | ch = *(++t); |
87 | *t = '\0'; |
88 | #ifdef QUAD |
89 | if (doquad) |
90 | (void)sprintf(buf,s,(quad)str_gnum(arg)); |
91 | else |
92 | #endif |
93 | if (dolong) |
94 | (void)sprintf(xs,f,(long)str_gnum(arg)); |
95 | else |
96 | (void)sprintf(xs,f,(int)str_gnum(arg)); |
97 | xlen = strlen(xs); |
98 | break; |
99 | case 'X': case 'O': |
100 | dolong = TRUE; |
101 | /* FALL THROUGH */ |
102 | case 'x': case 'o': case 'u': |
103 | ch = *(++t); |
104 | *t = '\0'; |
105 | value = str_gnum(arg); |
106 | #ifdef QUAD |
107 | if (doquad) |
108 | (void)sprintf(buf,s,(unsigned quad)value); |
109 | else |
110 | #endif |
111 | if (dolong) |
112 | (void)sprintf(xs,f,U_L(value)); |
113 | else |
114 | (void)sprintf(xs,f,U_I(value)); |
115 | xlen = strlen(xs); |
116 | break; |
117 | case 'E': case 'e': case 'f': case 'G': case 'g': |
118 | ch = *(++t); |
119 | *t = '\0'; |
120 | (void)sprintf(xs,f,str_gnum(arg)); |
121 | xlen = strlen(xs); |
122 | break; |
123 | case 's': |
124 | ch = *(++t); |
125 | *t = '\0'; |
126 | xs = str_get(arg); |
127 | xlen = arg->str_cur; |
128 | if (*xs == 'S' && xs[1] == 't' && xs[2] == 'B' && xs[3] == '\0' |
129 | && xlen == sizeof(STBP)) { |
130 | STR *tmpstr = Str_new(24,0); |
131 | |
132 | stab_efullname(tmpstr, ((STAB*)arg)); /* a stab value! */ |
133 | sprintf(tokenbuf,"*%s",tmpstr->str_ptr); |
134 | /* reformat to non-binary */ |
135 | xs = tokenbuf; |
136 | xlen = strlen(tokenbuf); |
137 | str_free(tmpstr); |
138 | } |
139 | if (strEQ(f,"%s")) { /* some printfs fail on >128 chars */ |
140 | break; /* so handle simple cases */ |
141 | } |
142 | else if (f[1] == '-') { |
143 | char *mp = index(f, '.'); |
144 | int min = atoi(f+2); |
145 | |
146 | if (mp) { |
147 | int max = atoi(mp+1); |
148 | |
149 | if (xlen > max) |
150 | xlen = max; |
151 | } |
152 | if (xlen < min) |
153 | post = min - xlen; |
154 | break; |
155 | } |
156 | else if (isDIGIT(f[1])) { |
157 | char *mp = index(f, '.'); |
158 | int min = atoi(f+1); |
159 | |
160 | if (mp) { |
161 | int max = atoi(mp+1); |
162 | |
163 | if (xlen > max) |
164 | xlen = max; |
165 | } |
166 | if (xlen < min) |
167 | pre = min - xlen; |
168 | break; |
169 | } |
170 | strcpy(tokenbuf+64,f); /* sprintf($s,...$s...) */ |
171 | *t = ch; |
172 | (void)sprintf(buf,tokenbuf+64,xs); |
173 | xs = buf; |
174 | xlen = strlen(xs); |
175 | break; |
176 | } |
177 | /* end of switch, copy results */ |
178 | *t = ch; |
179 | STR_GROW(TARG, TARG->str_cur + (f - s) + xlen + 1 + pre + post); |
180 | str_ncat(TARG, s, f - s); |
181 | if (pre) { |
182 | repeatcpy(TARG->str_ptr + TARG->str_cur, " ", 1, pre); |
183 | TARG->str_cur += pre; |
184 | } |
185 | str_ncat(TARG, xs, xlen); |
186 | if (post) { |
187 | repeatcpy(TARG->str_ptr + TARG->str_cur, " ", 1, post); |
188 | TARG->str_cur += post; |
189 | } |
190 | s = t; |
191 | break; /* break from for loop */ |
192 | } |
193 | } |
194 | str_ncat(TARG, s, t - s); |
195 | STABSET(TARG); |
196 | } |
197 | |