1
0
mirror of https://git.zap.org.au/git/trader.git synced 2025-02-02 15:08:13 -05:00

Add vprepstr() with a va_list argument: for the future txdlgbox()

This commit is contained in:
John Zaitseff 2011-08-12 15:10:05 +10:00
parent 2612eddf3d
commit 4e7699f192
2 changed files with 125 additions and 58 deletions

View File

@ -555,6 +555,27 @@ void txresize (void)
#endif // HANDLE_RESIZE_EVENTS #endif // HANDLE_RESIZE_EVENTS
/***********************************************************************/
// prepstr: Prepare a string for printing to screen
int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
chtype attr_alt1, chtype attr_alt2, int maxlines, int maxwidth,
int *restrict widthbuf, int widthbufsize,
const char *restrict format, ...)
{
va_list args;
int lines;
va_start(args, format);
lines = vprepstr(chbuf, chbufsize, attr_norm, attr_alt1, attr_alt2,
maxlines, maxwidth, widthbuf, widthbufsize, format,
args);
va_end(args);
return lines;
}
/***********************************************************************/ /***********************************************************************/
// prepstr_addch: Add a character to the prepstr buffer // prepstr_addch: Add a character to the prepstr buffer
@ -641,17 +662,16 @@ int prepstr_addch (chtype *restrict *restrict chbuf, int *restrict chbufsize,
/***********************************************************************/ /***********************************************************************/
// prepstr: Prepare a string for printing to screen // vprepstr: Prepare a string for printing to screen
int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm, int vprepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
chtype attr_alt1, chtype attr_alt2, int maxlines, int maxwidth, chtype attr_alt1, chtype attr_alt2, int maxlines, int maxwidth,
int *restrict widthbuf, int widthbufsize, int *restrict widthbuf, int widthbufsize,
const char *restrict format, ...) const char *restrict format, va_list args)
{ {
struct argument format_arg[MAXFMTARGS]; struct argument format_arg[MAXFMTARGS];
int num_format_args, arg_num; int num_format_args, arg_num;
const char *orig_format; const char *orig_format;
va_list args;
int line, width; int line, width;
chtype *lastspc; chtype *lastspc;
int widthspc; int widthspc;
@ -676,14 +696,14 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
memset(format_arg, 0, sizeof(format_arg)); memset(format_arg, 0, sizeof(format_arg));
num_format_args = 0; num_format_args = 0;
arg_num = 0; arg_num = 0;
va_start(args, format);
while (*format != '\0') { while (*format != '\0') {
switch (*format++) { switch (*format++) {
case '^': case '^':
// Switch to a different character rendition // Switch to a different character rendition
if (*format == '\0') { if (*format == '\0') {
goto error_inval; errno = EINVAL;
return -1;
} else { } else {
format++; format++;
} }
@ -692,7 +712,8 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
case '%': case '%':
// Process a conversion specifier // Process a conversion specifier
if (*format == '\0') { if (*format == '\0') {
goto error_inval; errno = EINVAL;
return -1;
} else if (*format == '%') { } else if (*format == '%') {
format++; format++;
} else { } else {
@ -707,8 +728,10 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
switch (c) { switch (c) {
case '0': case '0':
// Zero flag, or part of numeric count // Zero flag, or part of numeric count
if (count == 0) if (count == 0) {
goto error_inval; errno = EINVAL;
return -1;
}
count *= 10; count *= 10;
break; break;
@ -728,12 +751,14 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
case '$': case '$':
// Fixed-position argument // Fixed-position argument
if (flag_posn || count == 0) if (flag_posn || count == 0) {
goto error_inval; errno = EINVAL;
return -1;
}
if (count > MAXFMTARGS) { if (count > MAXFMTARGS) {
errno = E2BIG; errno = E2BIG;
goto error; return -1;
} }
flag_posn = true; flag_posn = true;
@ -747,8 +772,10 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
case 'l': case 'l':
// Long length modifier // Long length modifier
if (flag_long) if (flag_long) {
goto error_inval; errno = EINVAL;
return -1;
}
flag_long = true; flag_long = true;
break; break;
@ -760,29 +787,34 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
case 'N': case 'N':
// Insert a monetary amount (double) // Insert a monetary amount (double)
if (flag_long) if (flag_long) {
goto error_inval; errno = EINVAL;
return -1;
}
arg_type = TYPE_DOUBLE; arg_type = TYPE_DOUBLE;
goto handlefmt; goto handlefmt;
case 's': case 's':
// Insert a string (const char *) // Insert a string (const char *)
if (flag_long) if (flag_long) {
goto error_inval; errno = EINVAL;
return -1;
}
arg_type = TYPE_STRING; arg_type = TYPE_STRING;
handlefmt: handlefmt:
if (arg_num >= MAXFMTARGS) { if (arg_num >= MAXFMTARGS) {
errno = E2BIG; errno = E2BIG;
goto error; return -1;
} }
if (format_arg[arg_num].a_type == TYPE_NONE) { if (format_arg[arg_num].a_type == TYPE_NONE) {
format_arg[arg_num].a_type = arg_type; format_arg[arg_num].a_type = arg_type;
} else if (format_arg[arg_num].a_type != arg_type) { } else if (format_arg[arg_num].a_type != arg_type) {
goto error_inval; errno = EINVAL;
return -1;
} }
arg_num++; arg_num++;
@ -792,11 +824,14 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
break; break;
default: default:
goto error_inval; errno = EINVAL;
return -1;
} }
} }
if (inspec) if (inspec) {
goto error_inval; errno = EINVAL;
return -1;
}
} }
break; break;
@ -828,7 +863,8 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
/* Cannot allow unused arguments, as we have no way of /* Cannot allow unused arguments, as we have no way of
knowing how much space they take (cf. int vs. long long knowing how much space they take (cf. int vs. long long
int). */ int). */
goto error_inval; errno = EINVAL;
return -1;
} }
} }
@ -848,7 +884,8 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
case '^': case '^':
// Switch to a different character rendition // Switch to a different character rendition
if (*++format == '\0') { if (*++format == '\0') {
goto error_inval; errno = EINVAL;
return -1;
} else { } else {
switch (*format) { switch (*format) {
case '^': case '^':
@ -856,7 +893,7 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
maxwidth, &line, &width, &lastspc, maxwidth, &line, &width, &lastspc,
&widthspc, widthbuf, widthbufsize, &widthspc, widthbuf, widthbufsize,
&format) < 0) { &format) < 0) {
goto error; return -1;
} }
break; break;
@ -877,7 +914,8 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
break; break;
default: default:
goto error_inval; errno = EINVAL;
return -1;
} }
} }
break; break;
@ -885,12 +923,13 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
case '%': case '%':
// Process a conversion specifier // Process a conversion specifier
if (*++format == '\0') { if (*++format == '\0') {
goto error_inval; errno = EINVAL;
return -1;
} else if (*format == '%') { } else if (*format == '%') {
if (prepstr_addch(&chbuf, &chbufsize, curattr, maxlines, if (prepstr_addch(&chbuf, &chbufsize, curattr, maxlines,
maxwidth, &line, &width, &lastspc, &widthspc, maxwidth, &line, &width, &lastspc, &widthspc,
widthbuf, widthbufsize, &format) < 0) { widthbuf, widthbufsize, &format) < 0) {
goto error; return -1;
} }
} else { } else {
bool inspec = true; bool inspec = true;
@ -912,7 +951,8 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
if (count == 0) { if (count == 0) {
// Zero flag is not supported // Zero flag is not supported
free(buf); free(buf);
goto error_inval; errno = EINVAL;
return -1;
} }
count *= 10; count *= 10;
@ -935,13 +975,14 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
// Fixed-position argument // Fixed-position argument
if (flag_posn || count == 0) { if (flag_posn || count == 0) {
free(buf); free(buf);
goto error_inval; errno = EINVAL;
return -1;
} }
if (count > MAXFMTARGS) { if (count > MAXFMTARGS) {
free(buf); free(buf);
errno = E2BIG; errno = E2BIG;
goto error; return -1;
} }
flag_posn = true; flag_posn = true;
@ -953,7 +994,8 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
// Use locale-specific thousands separator // Use locale-specific thousands separator
if (flag_thou) { if (flag_thou) {
free(buf); free(buf);
goto error_inval; errno = EINVAL;
return -1;
} }
flag_thou = true; flag_thou = true;
@ -963,7 +1005,8 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
// Long length modifier // Long length modifier
if (flag_long) { if (flag_long) {
free(buf); free(buf);
goto error_inval; errno = EINVAL;
return -1;
} }
flag_long = true; flag_long = true;
@ -973,13 +1016,14 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
// Insert an integer (int or long int) into the output // Insert an integer (int or long int) into the output
if (count != 0) { if (count != 0) {
free(buf); free(buf);
goto error_inval; errno = EINVAL;
return -1;
} }
if (arg_num >= MAXFMTARGS) { if (arg_num >= MAXFMTARGS) {
free(buf); free(buf);
errno = E2BIG; errno = E2BIG;
goto error; return -1;
} }
if (flag_long) { if (flag_long) {
@ -988,7 +1032,7 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
saved_errno = errno; saved_errno = errno;
free(buf); free(buf);
errno = saved_errno; errno = saved_errno;
goto error; return -1;
} }
} else { } else {
if (snprintf(buf, BUFSIZE, flag_thou ? "%'d" : "%d", if (snprintf(buf, BUFSIZE, flag_thou ? "%'d" : "%d",
@ -996,7 +1040,7 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
saved_errno = errno; saved_errno = errno;
free(buf); free(buf);
errno = saved_errno; errno = saved_errno;
goto error; return -1;
} }
} }
@ -1007,13 +1051,14 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
// Insert a monetary amount (double) into the output // Insert a monetary amount (double) into the output
if (count != 0 || flag_thou || flag_long) { if (count != 0 || flag_thou || flag_long) {
free(buf); free(buf);
goto error_inval; errno = EINVAL;
return -1;
} }
if (arg_num >= MAXFMTARGS) { if (arg_num >= MAXFMTARGS) {
free(buf); free(buf);
errno = E2BIG; errno = E2BIG;
goto error; return -1;
} }
if (l_strfmon(buf, BUFSIZE, "%n", if (l_strfmon(buf, BUFSIZE, "%n",
@ -1021,7 +1066,7 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
saved_errno = errno; saved_errno = errno;
free(buf); free(buf);
errno = saved_errno; errno = saved_errno;
goto error; return -1;
} }
str = buf; str = buf;
@ -1031,13 +1076,14 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
// Insert a string (const char *) into the output // Insert a string (const char *) into the output
if (count != 0 || flag_thou || flag_long) { if (count != 0 || flag_thou || flag_long) {
free(buf); free(buf);
goto error_inval; errno = EINVAL;
return -1;
} }
if (arg_num >= MAXFMTARGS) { if (arg_num >= MAXFMTARGS) {
free(buf); free(buf);
errno = E2BIG; errno = E2BIG;
goto error; return -1;
} }
str = format_arg[arg_num].a.a_string; str = format_arg[arg_num].a.a_string;
@ -1056,7 +1102,7 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
saved_errno = errno; saved_errno = errno;
free(buf); free(buf);
errno = saved_errno; errno = saved_errno;
goto error; return -1;
} }
} }
@ -1066,12 +1112,15 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
default: default:
free(buf); free(buf);
goto error_inval; errno = EINVAL;
return -1;
} }
} }
free(buf); free(buf);
if (inspec) if (inspec) {
goto error_inval; errno = EINVAL;
return -1;
}
} }
break; break;
@ -1080,7 +1129,7 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
if (prepstr_addch(&chbuf, &chbufsize, curattr, maxlines, maxwidth, if (prepstr_addch(&chbuf, &chbufsize, curattr, maxlines, maxwidth,
&line, &width, &lastspc, &widthspc, widthbuf, &line, &width, &lastspc, &widthspc, widthbuf,
widthbufsize, &format) < 0) { widthbufsize, &format) < 0) {
goto error; return -1;
} }
} }
} }
@ -1093,15 +1142,7 @@ int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
line = maxlines - 1; line = maxlines - 1;
} }
va_end(args);
return line + 1; return line + 1;
error_inval:
errno = EINVAL;
error:
va_end(args);
return -1;
} }

View File

@ -323,6 +323,32 @@ extern int prepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
const char *restrict format, ...); const char *restrict format, ...);
/*
Function: vprepstr - Prepare a string for printing to screen
Parameters: chbuf - Pointer to chtype buffer in which to store string
chbufsize - Number of chtype elements in chbuf
attr_norm - Normal character rendition to use
attr_alt1 - First alternate character rendition to use
attr_alt2 - Second alternate character rendition to use
maxlines - Maximum number of screen lines to use
maxwidth - Maximum width of each line, in chars
widthbuf - Pointer to buffer to store widths of each line
widthbufsize - Number of int elements in widthbuf
format - Format string as described for prepstr()
args - Variable argument list
Returns: int - Number of lines actually used, or -1 on error
This function is exactly the same as prepstr(), except that it is
called with a va_list parameter args instead of a variable number of
arguments. Note that va_end() is NOT called on args, and that args is
undefined after this function.
*/
extern int vprepstr (chtype *restrict chbuf, int chbufsize, chtype attr_norm,
chtype attr_alt1, chtype attr_alt2, int maxlines,
int maxwidth, int *restrict widthbuf, int widthbufsize,
const char *restrict format, va_list args);
/* /*
Function: pr_left - Print strings in chbuf left-aligned Function: pr_left - Print strings in chbuf left-aligned
Parameters: win - Window to use (should be curwin) Parameters: win - Window to use (should be curwin)