diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2008-08-16 12:21:47 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2008-08-16 12:21:47 +0000 |
commit | 32a17bdecdd07e7941404eef0770c432860ea368 (patch) | |
tree | fd31854b3a2ed749f7632e27066c9bbc7b699d0a /usr.bin/m4/gnum4.c | |
parent | 411f1cecb74fed58f93a6a2fa3d2f4d72864bb4c (diff) |
argument parsing should only skip spaces outside of parenthesis.
Inside matching parenthesis, keep spaces as is (use chrsave instead of
pbstr, since there's no way it can be a further macro expansion).
Fixes a long-standing issue with autoconf ( --option -> --option),
matches other m4 than gnum4
okay millert@, fries@
Diffstat (limited to 'usr.bin/m4/gnum4.c')
-rw-r--r-- | usr.bin/m4/gnum4.c | 102 |
1 files changed, 72 insertions, 30 deletions
diff --git a/usr.bin/m4/gnum4.c b/usr.bin/m4/gnum4.c index 2720c851aaf..f9ee4ed3e94 100644 --- a/usr.bin/m4/gnum4.c +++ b/usr.bin/m4/gnum4.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gnum4.c,v 1.36 2006/03/24 08:03:44 espie Exp $ */ +/* $OpenBSD: gnum4.c,v 1.37 2008/08/16 12:21:46 espie Exp $ */ /* * Copyright (c) 1999 Marc Espie @@ -508,43 +508,85 @@ doformat(const char *argv[], int argc) { const char *format = argv[2]; int pos = 3; + int left_padded; + long width; + size_t l; + const char *thisarg; + char temp[2]; + long extra; while (*format != 0) { if (*format != '%') { addchar(*format++); + continue; + } + + format++; + if (*format == '%') { + addchar(*format++); + continue; + } + if (*format == 0) { + addchar('%'); + break; + } + + if (*format == '*') { + format++; + if (pos >= argc) + m4errx(1, + "Format with too many format specifiers."); + width = strtol(argv[pos++], NULL, 10); + } else { + width = strtol(format, (char **)&format, 10); + } + if (width < 0) { + left_padded = 1; + width = -width; } else { + left_padded = 0; + } + if (*format == '.') { format++; - if (*format == '%' || *format == 0) { - addchar('%'); - if (*format == '%') - format++; + if (*format == '*') { + format++; + if (pos >= argc) + m4errx(1, + "Format with too many format specifiers."); + extra = strtol(argv[pos++], NULL, 10); } else { - int left_padded = 0; - unsigned long width; - size_t l; - - if (*format == '-') { - left_padded = 1; - format++; - } - width = strtoul(format, (char **)&format, 10); - if (*format != 's') { - m4errx(1, "Unsupported format specification: %s.", argv[2]); - } - format++; - if (pos >= argc) - m4errx(1, "Format with too many values."); - l = strlen(argv[pos]); - if (!left_padded) { - while (l < width--) - addchar(' '); - } - addchars(argv[pos++], l); - if (left_padded) { - while (l < width--) - addchar(' '); - } + extra = strtol(format, (char **)&format, 10); } + } else { + extra = LONG_MAX; + } + if (pos >= argc) + m4errx(1, "Format with too many format specifiers."); + switch(*format) { + case 's': + thisarg = argv[pos++]; + break; + case 'c': + temp[0] = strtoul(argv[pos++], NULL, 10); + temp[1] = 0; + thisarg = temp; + break; + default: + m4errx(1, "Unsupported format specification: %s.", + argv[2]); + } + format++; + l = strlen(thisarg); + if (l > extra) + l = extra; + if (!left_padded) { + while (l < width--) + addchar(' '); + } + addchars(thisarg, l); + if (left_padded) { + while (l < width--) + addchar(' '); } } pbstr(getstring()); |