diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2011-04-27 15:29:33 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2011-04-27 15:29:33 -0700 |
commit | 54b8e3f7753cdd63ba6dac998d56fcd34dd59d8e (patch) | |
tree | 9d2fdec724dec1b168c7b6fe5155e30282090909 /src/doprnt.c | |
parent | 8f41de3a66a32996d77512569eae74c926a81c84 (diff) | |
parent | fc3b729195fbe5297aa23320f83adb11225b6ded (diff) | |
download | emacs-54b8e3f7753cdd63ba6dac998d56fcd34dd59d8e.tar.gz |
Merge from mainline.
Diffstat (limited to 'src/doprnt.c')
-rw-r--r-- | src/doprnt.c | 62 |
1 files changed, 31 insertions, 31 deletions
diff --git a/src/doprnt.c b/src/doprnt.c index 229ad06e057..cc4e5daebf3 100644 --- a/src/doprnt.c +++ b/src/doprnt.c @@ -55,7 +55,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ %s means print a string argument. %S is silently treated as %s, for loose compatibility with `Fformat'. %d means print a `signed int' argument in decimal. - %l means print a `long int' argument in decimal. %o means print an `unsigned int' argument in octal. %x means print an `unsigned int' argument in hex. %e means print a `double' argument in exponential notation. @@ -65,24 +64,28 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ %c means print a `signed int' argument as a single character. %% means produce a literal % character. - A %-sequence may contain optional flag, width, and precision specifiers, as - follows: + A %-sequence may contain optional flag, width, and precision specifiers, and + a length modifier, as follows: - %<flags><width><precision>character + %<flags><width><precision><length>character where flags is [+ -0l], width is [0-9]+, and precision is .[0-9]+ The + flag character inserts a + before any positive number, while a space - inserts a space before any positive number; these flags only affect %d, %l, - %o, %x, %e, %f, and %g sequences. The - and 0 flags affect the width - specifier, as described below. - - The l (lower-case letter ell) flag is a `long' data type modifier: it is - supported for %d, %o, and %x conversions of integral arguments, and means - that the respective argument is to be treated as `long int' or `unsigned - long int'. ll means to use 'long long'. EMACS_INT arguments - should use the pI macro, which expands to whatever length modifier - is needed for the target host, e.g., "", "l", "ll". + inserts a space before any positive number; these flags only affect %d, %o, + %x, %e, %f, and %g sequences. The - and 0 flags affect the width specifier, + as described below. For signed numerical arguments only, the ` ' (space) + flag causes the result to be prefixed with a space character if it does not + start with a sign (+ or -). + + The l (lower-case letter ell) length modifier is a `long' data type + modifier: it is supported for %d, %o, and %x conversions of integral + arguments, must immediately precede the conversion specifier, and means that + the respective argument is to be treated as `long int' or `unsigned long + int'. Similarly, ll (two letter ells) means to use `long long int' or + `unsigned long long int'. The empty length modifier means to use `int' or + `unsigned int'. EMACS_INT arguments should use the pI macro, which + expands to whatever length modifier is needed for the target host. The width specifier supplies a lower limit for the length of the printed representation. The padding, if any, normally goes on the left, but it goes @@ -168,7 +171,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format, bufsize--; /* Loop until end of format string or buffer full. */ - while (fmt != format_end && bufsize > 0) + while (fmt < format_end && bufsize > 0) { if (*fmt == '%') /* Check for a '%' character */ { @@ -180,7 +183,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format, /* Copy this one %-spec into fmtcpy. */ string = fmtcpy; *string++ = '%'; - while (1) + while (fmt < format_end) { *string++ = *fmt; if ('0' <= *fmt && *fmt <= '9') @@ -190,7 +193,8 @@ doprnt (char *buffer, register size_t bufsize, const char *format, %1.1000f and %1000.1f both might need 1000+ bytes. Parse the width or precision, checking for overflow. */ size_t n = *fmt - '0'; - while ('0' <= fmt[1] && fmt[1] <= '9') + while (fmt < format_end + && '0' <= fmt[1] && fmt[1] <= '9') { if (n >= SIZE_MAX / 10 || n * 10 > SIZE_MAX - (fmt[1] - '0')) @@ -206,20 +210,16 @@ doprnt (char *buffer, register size_t bufsize, const char *format, ; else if (*fmt == 'l') { - long_flag = 1; - if (fmt[1] == 'l') - { - long_flag = 2; - fmt++; - } - if (!strchr ("dox", fmt[1])) - /* %l as conversion specifier, not as modifier. */ - break; + long_flag = 1 + (fmt + 1 < fmt_end && fmt[1] == 'l'); + fmt += long_flag; + break; } else break; fmt++; } + if (fmt > format_end) + fmt = format_end; *string = 0; /* Make the size bound large enough to handle floating point formats @@ -232,9 +232,8 @@ doprnt (char *buffer, register size_t bufsize, const char *format, if (size_bound > size_allocated) { if (big_buffer) - big_buffer = (char *) xrealloc (big_buffer, size_bound); - else - big_buffer = (char *) xmalloc (size_bound); + xfree (big_buffer); + big_buffer = (char *) xmalloc (size_bound); sprintf_buffer = big_buffer; size_allocated = size_bound; } @@ -242,7 +241,8 @@ doprnt (char *buffer, register size_t bufsize, const char *format, switch (*fmt++) { default: - error ("Invalid format operation %%%c", fmt[-1]); + error ("Invalid format operation %%%s%c", + long_flag ? "l" : "", fmt[-1]); /* case 'b': */ case 'l': @@ -398,7 +398,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format, char *save_bufptr = bufptr; do { *bufptr++ = *fmt++; } - while (--bufsize > 0 && !CHAR_HEAD_P (*fmt)); + while (fmt < format_end && --bufsize > 0 && !CHAR_HEAD_P (*fmt)); if (!CHAR_HEAD_P (*fmt)) { bufptr = save_bufptr; |