1
0
mirror of https://git.zap.org.au/git/trader.git synced 2024-11-03 17:27:29 -05:00

Handle floating-point numbers in mkchstr(), with optional precision

This commit is contained in:
John Zaitseff 2011-08-15 23:12:10 +10:00
parent 665605d144
commit 22677c0d89
2 changed files with 68 additions and 12 deletions

View File

@ -70,11 +70,13 @@ struct argument {
#define MAXFMTSPECS 16 // Maximum number of conversion specifiers #define MAXFMTSPECS 16 // Maximum number of conversion specifiers
struct convspec { struct convspec {
int len; // Length of conversion specifier, 0 = unused char spec; // Conversion specifier: c d f N s
int arg_num; // Which variable argument to use int arg_num; // Which variable argument to use
char spec; // Conversion specifier: c d N s int len; // Length of conversion specifier, 0 = unused
int precision; // Precision value
bool flag_group; // Flag "'" (thousands grouping) bool flag_group; // Flag "'" (thousands grouping)
bool flag_nosym; // Flag "!" (omit currency symbol) bool flag_nosym; // Flag "!" (omit currency symbol)
bool flag_prec; // Flag "." (precision)
bool flag_long; // Length modifier "l" (long) bool flag_long; // Length modifier "l" (long)
}; };
@ -835,6 +837,17 @@ int mkchstr_parse (const char *restrict format,
flag_other = true; flag_other = true;
break; break;
case '.':
// Precision flag
if (format_spec->flag_prec || count != 0) {
errno = EINVAL;
return -1;
}
format_spec->flag_prec = true;
flag_other = true;
break;
case 'l': case 'l':
// Long length modifier // Long length modifier
if (format_spec->flag_long) { if (format_spec->flag_long) {
@ -850,7 +863,8 @@ int mkchstr_parse (const char *restrict format,
case 'c': case 'c':
// Insert a character (char) // Insert a character (char)
if (format_spec->flag_group || format_spec->flag_nosym if (format_spec->flag_group || format_spec->flag_nosym
|| format_spec->flag_long || count != 0) { || format_spec->flag_prec || format_spec->flag_long
|| count != 0) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
@ -860,7 +874,8 @@ int mkchstr_parse (const char *restrict format,
case 'd': case 'd':
// Insert an integer (int or long int) // Insert an integer (int or long int)
if (count != 0) { if (format_spec->flag_nosym || format_spec->flag_prec
|| count != 0) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
@ -869,10 +884,23 @@ int mkchstr_parse (const char *restrict format,
TYPE_LONGINT : TYPE_INT; TYPE_LONGINT : TYPE_INT;
goto handlefmt; goto handlefmt;
case 'f':
// Insert a floating-point number (double)
if (format_spec->flag_nosym || format_spec->flag_long ||
(! format_spec->flag_prec && count != 0)) {
errno = EINVAL;
return -1;
}
format_spec->precision = count;
arg_type = TYPE_DOUBLE;
goto handlefmt;
case 'N': case 'N':
// Insert a monetary amount (double) // Insert a monetary amount (double)
if (format_spec->flag_group || format_spec->flag_long if (format_spec->flag_group || format_spec->flag_prec
|| count != 0) { || format_spec->flag_long || count != 0) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
@ -883,7 +911,8 @@ int mkchstr_parse (const char *restrict format,
case 's': case 's':
// Insert a string (const char *) // Insert a string (const char *)
if (format_spec->flag_group || format_spec->flag_nosym if (format_spec->flag_group || format_spec->flag_nosym
|| format_spec->flag_long || count != 0) { || format_spec->flag_prec || format_spec->flag_long
|| count != 0) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
@ -1102,6 +1131,31 @@ int vmkchstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
str = buf; str = buf;
goto insertstr; goto insertstr;
case 'f':
// Insert a floating-point number (double) into the output
if (spec->flag_prec) {
if (snprintf(buf, BUFSIZE, spec->flag_group ?
"%'.*f" : "%.*f", spec->precision,
format_arg[spec->arg_num].a.a_double) < 0) {
saved_errno = errno;
free(buf);
errno = saved_errno;
goto error;
}
} else {
if (snprintf(buf, BUFSIZE, spec->flag_group ?
"%'f" : "%f",
format_arg[spec->arg_num].a.a_double) < 0) {
saved_errno = errno;
free(buf);
errno = saved_errno;
goto error;
}
}
str = buf;
goto insertstr;
case 'N': case 'N':
// Insert a monetary amount (double) into the output // Insert a monetary amount (double) into the output
if (l_strfmon(buf, BUFSIZE, spec->flag_nosym ? "%!n" : "%n", if (l_strfmon(buf, BUFSIZE, spec->flag_nosym ? "%!n" : "%n",

View File

@ -317,14 +317,16 @@ extern int txdlgbox (int maxlines, int ncols, int begin_y, int begin_x,
%c - Insert the next parameter as a character (type char) %c - Insert the next parameter as a character (type char)
%s - Insert the next parameter as a string (type char *) %s - Insert the next parameter as a string (type char *)
%d - Insert the next parameter as an integer (type int) %d - Insert the next parameter as an integer (type int)
%'d - Insert as an int, using the locale's thousands separator %'d - As above, using the locale's thousands group separator
%ld - Insert the next parameter as a long int %ld - Insert the next parameter as a long int
%'ld - Insert as a long int, using the locale's thousands separator %'ld - As above, using the locale's thousands group separator
%f - Insert the next parameter as a floating point number (double)
%.mf - As above, with precision "m" (a positive integer > 0)
%'.mf - As above, using the locale's thousands group separator
%N - Insert the next parameter as a double, using the locale's %N - Insert the next parameter as a double, using the locale's
national currency format (extension to printf()) national currency format (extension to printf())
%!N - Insert the next parameter as a double, using the locale's %!N - As above, using the locale's national currency format without
national currency format without the actual currency symbol the actual currency symbol (extension to printf())
(extension to printf())
Instead of using "%" to convert the next parameter, "%m$" can be used Instead of using "%" to convert the next parameter, "%m$" can be used
to indicate fixed parameter m (where m is an integer from 1 to 8). For to indicate fixed parameter m (where m is an integer from 1 to 8). For