1 #line 982 "../../src/builtin/snarf.m4"
2 /* -*- buffer-read-only: t -*- vi: set ro:
3 THIS FILE IS GENERATED AUTOMATICALLY. PLEASE DO NOT EDIT.
4 */
5 #line 982
6 #ifdef HAVE_CONFIG_H
7 #line 982
8 # include <config.h>
9 #line 982
10 #endif
11 #line 982
12 #include <sys/types.h>
13 #line 982
14
15 #line 982
16 #include "mailfromd.h"
17 #line 982
18 #include "prog.h"
19 #line 982
20 #include "builtin.h"
21 #line 982
22
23 #line 982
24
25 #line 1022 "../../src/builtin/snarf.m4"
26
27 /* End of snarf.m4 */
28 #line 1 "sprintf.bi"
29 /* This file is part of Mailfromd. -*- c -*-
30 Copyright (C) 2007-2021 Sergey Poznyakoff
31
32 This program is free software; you can redistribute it and/or modify
33 it under the terms of the GNU General Public License as published by
34 the Free Software Foundation; either version 3, or (at your option)
35 any later version.
36
37 This program is distributed in the hope that it will be useful,
38 but WITHOUT ANY WARRANTY; without even the implied warranty of
39 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 GNU General Public License for more details.
41
42 You should have received a copy of the GNU General Public License
43 along with this program. If not, see <http://www.gnu.org/licenses/>. */
44
45
46
47 #define FMT_ALTPOS 0x01
48 #define FMT_ALTERNATE 0x02
49 #define FMT_PADZERO 0x04
50 #define FMT_ADJUST_LEFT 0x08
51 #define FMT_SPACEPFX 0x10
52 #define FMT_SIGNPFX 0x20
53
54 typedef enum {
55 fmts_copy, /* Copy char as is */
56 fmts_pos, /* Expect argument position -- %_2$ */
57 fmts_flags, /* Expect flags -- %2$_# */
58 fmts_width, /* Expect width -- %2$#_8 or %2$#_* */
59 fmts_width_arg, /* Expect width argument position -- %2$#*_1$ */
60 fmts_prec, /* Expect precision */
61 fmts_prec_arg, /* Expect precision argument position */
62 fmts_conv /* Expect conversion specifier */
63 } printf_format_state;
64
65 static int
get_num(const char * p,int i,unsigned * pn)66 get_num(const char *p, int i, unsigned *pn)
67 {
68 unsigned n = 0;
69
70 for (; p[i] && mu_isdigit(p[i]); i++)
71 n = n * 10 + p[i] - '0';
72 *pn = n;
73 return i;
74 }
75
76 #define __MF_MAX(a,b) ((a)>(b) ? (a) : (b))
77 #define SPRINTF_BUF_SIZE (__MF_MAX(3*sizeof(long), NUMERIC_BUFSIZE_BOUND) + 2)
78
79 void
80 #line 51
bi_sprintf(eval_environ_t env)81 bi_sprintf(eval_environ_t env)
82 #line 51
83
84 #line 51
85
86 #line 51 "sprintf.bi"
87 {
88 #line 51
89
90 #line 51
91
92 #line 51
93 long __bi_argcnt;
94 #line 51
95 char * MFL_DATASEG format;
96 #line 51
97
98 #line 51
99 get_string_arg(env, 1, &format);
100 #line 51
101
102 #line 51
103 get_numeric_arg(env, 0, &__bi_argcnt);
104 #line 51
105 adjust_stack(env, __bi_argcnt + 1);
106 #line 51
107
108 #line 51
109
110 #line 51
111 if (builtin_module_trace(BUILTIN_IDX_sprintf))
112 #line 51
113 prog_trace(env, "sprintf %s",format);;
114 #line 51
115
116 {
117 int i = 0;
118 int cur = 0;
119 int start;
120 char buf[SPRINTF_BUF_SIZE];
121 printf_format_state state = fmts_copy;
122 int flags = 0;
123 unsigned width = 0;
124 unsigned prec = 0;
125 unsigned argnum;
126
127 heap_obstack_begin(env);
128
129 #line 64
130 unroll_stack(env, __bi_argcnt + 1);
131 while (format[cur]) {
132 unsigned n;
133 char *str;
134 long num;
135 int negative;
136 char fmtbuf[] = { '%', 'x', 0 };
137
138 switch (state) {
139 case fmts_copy:
140 /* Expect `%', and copy all the rest verbatim */
141 if (format[cur] == '%') {
142 start = cur;
143 state = fmts_pos;
144 flags = 0;
145 width = 0;
146 prec = 0;
147 } else
148 do { char __c = format[cur]; heap_obstack_grow(env, &__c, 1); } while(0);
149 cur++;
150 break;
151
152 case fmts_pos:
153 /* Expect '%' or an argument position -- %_% or %_2$ */
154 if (format[cur] == '%') {
155 do { char __c = '%'; heap_obstack_grow(env, &__c, 1); } while(0);
156 cur++;
157 state = fmts_copy;
158 break;
159 }
160 if (mu_isdigit(format[cur])) {
161 int pos = get_num(format, cur, &n);
162 if (format[pos] == '$') {
163 argnum = n - 1;
164 flags |= FMT_ALTPOS;
165 cur = pos + 1;
166 }
167 }
168 state = fmts_flags;
169 break;
170
171 case fmts_flags:
172 /* Expect flags -- %2$_# */
173 switch (format[cur]) {
174 case '#':
175 flags |= FMT_ALTERNATE;
176 cur++;
177 break;
178
179 case '0':
180 flags |= FMT_PADZERO;
181 cur++;
182 break;
183
184 case '-':
185 flags |= FMT_ADJUST_LEFT;
186 cur++;
187 break;
188
189 case ' ':
190 flags |= FMT_SPACEPFX;
191 cur++;
192 break;
193
194 case '+':
195 flags |= FMT_SIGNPFX;
196 cur++;
197 break;
198
199 default:
200 state = fmts_width;
201 }
202 break;
203
204 case fmts_width:
205 /* Expect width -- %2$#_8 or %2$#_* */
206 if (mu_isdigit(format[cur])) {
207 cur = get_num(format, cur, &width);
208 state = fmts_prec;
209 } else if (format[cur] == '*') {
210 cur++;
211 state = fmts_width_arg;
212 } else
213 state = fmts_prec;
214 break;
215
216 case fmts_width_arg:
217 /* Expect width argument position -- %2$#*_1$ */
218 state = fmts_prec;
219 if (mu_isdigit(format[cur])) {
220 int pos = get_num(format, cur, &n);
221 if (format[pos] == '$') {
222
223 #line 156
224 ((__bi_argcnt > (n-1+1)) ? get_numeric_arg(env, (n-1+1) + 1, &num) : ((
225 #line 156
226 env_throw_bi(env, mfe_range, "sprintf", "Argument %u is not supplied",(unsigned) (n-1+1))
227 #line 156
228 ),(long ) 0));
229 cur = pos + 1;
230 if (num < 0) {
231 flags |= FMT_SPACEPFX;
232 num = - num;
233 }
234 width = (unsigned) num;
235 break;
236 }
237 }
238
239 #line 166
240 ((__bi_argcnt > (i+1)) ? get_numeric_arg(env, (i+1) + 1, &num) : ((
241 #line 166
242 env_throw_bi(env, mfe_range, "sprintf", "Argument %u is not supplied",(unsigned) (i+1))
243 #line 166
244 ),(long ) 0));
245 i++;
246 if (num < 0) {
247 /* A negative field width is taken
248 as a `-' flag followed by a positive field width. */
249 flags |= FMT_SPACEPFX;
250 num = - num;
251 }
252 width = (unsigned) num;
253 break;
254
255 case fmts_prec:
256 /* Expect precision -- %2$#*1$_. */
257 state = fmts_conv;
258 if (format[cur] == '.') {
259 cur++;
260 if (mu_isdigit(format[cur])) {
261 cur = get_num(format, cur, &prec);
262 } else if (format[cur] == '*') {
263 cur++;
264 state = fmts_prec_arg;
265 }
266 }
267 break;
268
269 case fmts_prec_arg:
270 /* Expect precision argument position --
271 %2$#*1$.*_3$ */
272 state = fmts_conv;
273 if (mu_isdigit(format[cur])) {
274 int pos = get_num(format, cur, &n);
275 if (format[pos] == '$') {
276
277 #line 198
278 ((__bi_argcnt > (n-1+1)) ? get_numeric_arg(env, (n-1+1) + 1, &num) : ((
279 #line 198
280 env_throw_bi(env, mfe_range, "sprintf", "Argument %u is not supplied",(unsigned) (n-1+1))
281 #line 198
282 ),(long ) 0));
283 if (num > 0)
284 prec = (unsigned) num;
285 cur = pos + 1;
286 break;
287 }
288 }
289
290 #line 205
291 ((__bi_argcnt > (i+1)) ? get_numeric_arg(env, (i+1) + 1, &num) : ((
292 #line 205
293 env_throw_bi(env, mfe_range, "sprintf", "Argument %u is not supplied",(unsigned) (i+1))
294 #line 205
295 ),(long ) 0));
296 i++;
297 if (num > 0)
298 prec = (unsigned) num;
299 break;
300
301 case fmts_conv: /* Expect conversion specifier */
302 if (!(flags & FMT_ALTPOS))
303 argnum = i++;
304 switch (format[cur]) {
305 case 's':
306
307 #line 216
308 ((__bi_argcnt > (argnum+1)) ? get_string_arg(env, (argnum+1) + 1, &str) : ((
309 #line 216
310 env_throw_bi(env, mfe_range, "sprintf", "Argument %u is not supplied",(unsigned) (argnum+1))
311 #line 216
312 ),(char * MFL_DATASEG) 0));
313 n = strlen(str);
314 if (prec && prec < n)
315 n = prec;
316 if (width) {
317 char *q, *s;
318 if (n > width)
319 width = n;
320 q = s = mf_c_val(heap_tempspace(env, width + 1), ptr);
321 q[width] = 0;
322 memset(q, ' ', width);
323 if (!(flags & FMT_ADJUST_LEFT)
324 && n < width) {
325 s = q + width - n;
326 }
327 memcpy(s, str, n);
328 str = q;
329 n = width;
330 }
331 heap_obstack_grow(env, str, n);
332 break;
333
334 case 'i':
335 case 'd':
336
337 #line 240
338 ((__bi_argcnt > (argnum+1)) ? get_numeric_arg(env, (argnum+1) + 1, &num) : ((
339 #line 240
340 env_throw_bi(env, mfe_range, "sprintf", "Argument %u is not supplied",(unsigned) (argnum+1))
341 #line 240
342 ),(long ) 0));
343 if (num < 0) {
344 negative = 1;
345 num = - num;
346 } else
347 negative = 0;
348 /* If a precision is given with a
349 numeric conversion, the 0 flag is ignored.
350 */
351 /* A - overrides a 0 if both are given. */
352 if (prec || (flags & FMT_ADJUST_LEFT))
353 flags &= ~FMT_PADZERO;
354 snprintf(buf+1, sizeof(buf)-1, "%ld", num);
355 str = buf + 1;
356 n = strlen(str);
357 if (prec && prec > n) {
358 memmove(str + prec - n, str, n + 1);
359 memset(str, '0', prec - n);
360 }
361
362 if (flags & FMT_SIGNPFX) {
363 buf[0] = negative ? '-' : '+';
364 str = buf;
365 } else if (flags & FMT_SPACEPFX) {
366 buf[0] = negative ? '-' : ' ';
367 str = buf;
368 } else if (negative) {
369 buf[0] = '-';
370 str = buf;
371 } else
372 str = buf + 1;
373 n = strlen(str);
374
375 if (width && width > n) {
376 char *q;
377 q = heap_obstack_grow(env, NULL, width);
378 memset(q,
379 (flags & FMT_PADZERO) ?
380 '0' : ' ',
381 width);
382 if (flags & FMT_ADJUST_LEFT)
383 memcpy(q, str, n);
384 else {
385 if ((flags & FMT_PADZERO) &&
386 str == buf) {
387 q[0] = *str++;
388 n--;
389 }
390 memcpy(q + width - n, str, n);
391 }
392 } else
393 heap_obstack_grow(env, str, n);
394 break;
395
396 case 'u':
397
398 #line 295
399 ((__bi_argcnt > (argnum+1)) ? get_numeric_arg(env, (argnum+1) + 1, &num) : ((
400 #line 295
401 env_throw_bi(env, mfe_range, "sprintf", "Argument %u is not supplied",(unsigned) (argnum+1))
402 #line 295
403 ),(long ) 0));
404 /* If a precision is given with a
405 numeric conversion, the 0 flag is ignored.
406 */
407 /* A - overrides a 0 if both are given.*/
408 if (prec || (flags & FMT_ADJUST_LEFT))
409 flags &= ~FMT_PADZERO;
410 snprintf(buf, sizeof(buf), "%lu", num);
411 str = buf;
412 n = strlen(str);
413 if (prec && prec > n) {
414 memmove(str + prec - n, str, n + 1);
415 memset(str, '0', prec - n);
416 n = prec;
417 }
418
419 if (width && width > n) {
420 char *q;
421 q = heap_obstack_grow(env, NULL, width);
422 memset(q,
423 (flags & FMT_PADZERO) ?
424 '0' : ' ',
425 width);
426 if (flags & FMT_ADJUST_LEFT)
427 memcpy(q, str, n);
428 else
429 memcpy(q + width - n, str, n);
430 } else
431 heap_obstack_grow(env, str, n);
432 break;
433
434 case 'x':
435 case 'X':
436
437 #line 328
438 ((__bi_argcnt > (argnum+1)) ? get_numeric_arg(env, (argnum+1) + 1, &num) : ((
439 #line 328
440 env_throw_bi(env, mfe_range, "sprintf", "Argument %u is not supplied",(unsigned) (argnum+1))
441 #line 328
442 ),(long ) 0));
443 /* If a precision is given with a
444 numeric conversion, the 0 flag is ignored.
445 */
446 /* A - overrides a 0 if both are given.*/
447 if (prec || (flags & FMT_ADJUST_LEFT))
448 flags &= ~FMT_PADZERO;
449 fmtbuf[1] = format[cur];
450 snprintf(buf+2, sizeof(buf)-2, fmtbuf, num);
451 str = buf + 2;
452 n = strlen(str);
453 if (prec && prec > n) {
454 memmove(str + prec - n, str, n + 1);
455 memset(str, '0', prec - n);
456 n = prec;
457 }
458
459 if (flags & FMT_ALTERNATE) {
460 *--str = format[cur];
461 *--str = '0';
462 n += 2;
463 }
464
465 if (width && width > n) {
466 char *q;
467 q = heap_obstack_grow(env, NULL, width);
468 memset(q,
469 (flags & FMT_PADZERO) ?
470 '0' : ' ',
471 width);
472 if (flags & FMT_ADJUST_LEFT)
473 memcpy(q, str, n);
474 else {
475 if (flags & FMT_ALTERNATE
476 && flags & FMT_PADZERO) {
477 q[0] = *str++;
478 q[1] = *str++;
479 n -= 2;
480 }
481 memcpy(q + width - n, str, n);
482 }
483 } else
484 heap_obstack_grow(env, str, n);
485 break;
486
487 case 'o':
488
489 #line 374
490 ((__bi_argcnt > (argnum+1)) ? get_numeric_arg(env, (argnum+1) + 1, &num) : ((
491 #line 374
492 env_throw_bi(env, mfe_range, "sprintf", "Argument %u is not supplied",(unsigned) (argnum+1))
493 #line 374
494 ),(long ) 0));
495 /* If a precision is given with a
496 numeric conversion, the 0 flag is ignored.
497 */
498 /* A - overrides a 0 if both are given.*/
499 if (prec || (flags & FMT_ADJUST_LEFT))
500 flags &= ~FMT_PADZERO;
501 snprintf(buf+1, sizeof(buf)-1, "%lo", num);
502 str = buf + 2;
503 n = strlen(str);
504 if (prec && prec > n) {
505 memmove(str + prec - n, str, n + 1);
506 memset(str, '0', prec - n);
507 }
508
509 if ((flags & FMT_ALTERNATE) && *str != '0') {
510 *--str = '0';
511 n++;
512 }
513
514 if (width && width > n) {
515 char *q;
516 q = heap_obstack_grow(env, NULL, width);
517 memset(q,
518 (flags & FMT_PADZERO) ?
519 '0' : ' ',
520 width);
521 if (flags & FMT_ADJUST_LEFT)
522 memcpy(q, str, n);
523 else
524 memcpy(q + width - n, str, n);
525 } else
526 heap_obstack_grow(env, str, n);
527 break;
528
529 default:
530 heap_obstack_grow(env, &format[start], cur - start + 1);
531 #line 412
532 }
533
534 cur++;
535 state = fmts_copy;
536 }
537 }
538 do { char __c = 0; heap_obstack_grow(env, &__c, 1); } while(0);
539 adjust_stack(env, __bi_argcnt + 1);
540
541 #line 420
542 do {
543 #line 420
544 push(env, (STKVAL) (heap_obstack_finish(env)));
545 #line 420
546 goto endlab;
547 #line 420
548 } while (0);
549 }
550 endlab:
551 #line 422
552 env_function_cleanup_flush(env, NULL);
553 #line 422
554 return;
555 #line 422
556 }
557
558 #line 982 "../../src/builtin/snarf.m4"
559
560 #line 982
561
562 #line 982
563
564 #line 982
565 void
566 #line 982
sprintf_init_builtin(void)567 sprintf_init_builtin(void)
568 #line 982
569 {
570 #line 982
571
572 #line 982
573 #line 51 "sprintf.bi"
574 va_builtin_install_ex("sprintf", bi_sprintf, 0, dtype_string, 1, 0, 0|MFD_BUILTIN_VARIADIC|MFD_BUILTIN_NO_PROMOTE, dtype_string);
575
576 #line 982 "../../src/builtin/snarf.m4"
577
578 #line 982
579 }
580 #line 982 "../../src/builtin/snarf.m4"
581
582