diff --git a/src/libs/libdriver/input.cpp b/src/libs/libdriver/input.cpp index 15f0ef1c..f49721eb 100644 --- a/src/libs/libdriver/input.cpp +++ b/src/libs/libdriver/input.cpp @@ -383,7 +383,8 @@ ColorArg color_from_Df_command(IntArg); void delete_current_env(void); // delete global var current_env void fatal_command(char); // abort for invalid command inline Char get_char(void); // read next character from input stream -ColorArg get_color_arg(void); // read in argument for new color cmds +ColorArg get_color_arg(const char * cmd); + // read in argument for new color cmds IntArray *get_D_fixed_args(const size_t); // read in fixed number of integer // arguments @@ -393,13 +394,16 @@ IntArray *get_D_fixed_args_odd_dummy(const size_t); IntArray *get_D_variable_args(void); // variable, even number of int args char *get_extended_arg(void); // argument for 'x X' (several lines) -IntArg get_integer_arg(void); // read in next integer argument +IntArg get_integer_arg(const char * const); + // read in next integer argument IntArray *get_possibly_integer_args(); // 0 or more integer arguments -char *get_string_arg(void); // read in next string arg, ended by WS +char *get_string_arg(const char * const); + // read in next string arg, ended by WS inline bool is_space_or_tab(const Char); // test on space/tab char -Char next_arg_begin(void); // skip white space on current line +Char next_arg_begin(const char * const); + // skip white space on current line Char next_command(void); // go to next command, evt. diff. line inline bool odd(const int); // test if integer is odd void position_to_end_of_args(const IntArray * const); @@ -631,12 +635,15 @@ get_char(void) /* get_color_arg(): Retrieve an argument suitable for the color commands m and DF. + cmd: In parameter; command whose argument we're parsing. To be + passed to next_arg_begin(). + Return: The retrieved color argument. */ ColorArg -get_color_arg(void) +get_color_arg(const char * const cmd) { - IntArg x = get_integer_arg(); + IntArg x = get_integer_arg(cmd); if (x < 0 || x > (IntArg)COLORARG_MAX) { error("color component argument out of range"); x = 0; @@ -662,12 +669,20 @@ get_color_arg(void) IntArray * get_D_fixed_args(const size_t number) { + // Set up command argument buffer template for diagnostics. + char cmdbuft[] = "D (argument 18446744073709551616)"; // 2^64 + char *cmdbuf = (char *)calloc(1, strlen(cmdbuft)); if (number <= 0) fatal("requested number of arguments must be > 0"); IntArray *args = new IntArray(number); - for (size_t i = 0; i < number; i++) - args->append(get_integer_arg()); + for (size_t i = 0; i < number; i++) { + if (0 == sprintf(cmdbuf, "D (argument %ld)", number)) + error("internal error using sprintf() on command buffer"); + else + args->append(get_integer_arg(cmdbuf)); + } skip_line_D(); + free(cmdbuf); return args; } @@ -688,11 +703,17 @@ get_D_fixed_args(const size_t number) IntArray * get_D_fixed_args_odd_dummy(const size_t number) { + // Set up command argument buffer template for diagnostics. + char cmdbuft[] = "D (argument 18446744073709551616)"; // 2^64 + char *cmdbuf = (char *)calloc(1, strlen(cmdbuft)); if (number <= 0) fatal("requested number of arguments must be > 0"); IntArray *args = new IntArray(number); for (size_t i = 0; i < number; i++) - args->append(get_integer_arg()); + if (0 == sprintf(cmdbuf, "D (argument %ld)", number)) + error("internal error using sprintf() on command buffer"); + else + args->append(get_integer_arg(cmdbuf)); if (odd(number)) { IntArray *a = get_possibly_integer_args(); if (a->len() > 1) @@ -700,6 +721,7 @@ get_D_fixed_args_odd_dummy(const size_t number) delete a; } skip_line_D(); + free(cmdbuf); return args; } @@ -746,7 +768,7 @@ char * get_extended_arg(void) { StringBuf buf = StringBuf(); - Char c = next_arg_begin(); + Char c = next_arg_begin("x X"); while ((int) c != EOF) { if ((int) c == '\n') { current_lineno++; @@ -774,13 +796,16 @@ get_extended_arg(void) Fatal error on all other situations. + cmd: In parameter; command whose argument we're parsing. To be + passed to next_arg_begin(). + Return: Retrieved integer. */ IntArg -get_integer_arg(void) +get_integer_arg(const char * const cmd) { StringBuf buf = StringBuf(); - Char c = next_arg_begin(); + Char c = next_arg_begin(cmd); if ((int) c == '-') { buf.append(c); c = get_char(); @@ -892,13 +917,16 @@ get_possibly_integer_args() - The terminating space, tab, newline, or EOF character is restored onto the input queue, so no line skip. + cmd: In parameter; command whose argument we're parsing. To be + passed to next_arg_begin(). + Return: Retrieved string as char *, allocated by 'new'. */ char * -get_string_arg(void) +get_string_arg(const char * const cmd) { StringBuf buf = StringBuf(); - Char c = next_arg_begin(); + Char c = next_arg_begin(cmd); while (!is_space_or_tab(c) && c != Char('\n') && c != Char(EOF)) { buf.append(c); @@ -928,10 +956,13 @@ is_space_or_tab(const Char c) Skip space and tab characters; error on newline or EOF. + cmd: In parameter, name of command whose argument we're gathering, so + that our diagnostic message is useful. + Return: The first character different from these (including '#'). */ Char -next_arg_begin(void) +next_arg_begin(const char * const cmd) { Char c; while (1) { @@ -942,7 +973,7 @@ next_arg_begin(void) break; case '\n': case EOF: - error("missing argument"); + error("missing argument to %1 command", cmd); return c; default: // first essential character return c; @@ -1260,39 +1291,42 @@ unget_char(const Char c) col: In-out-parameter; the color object to be set, must have been initialized before. + + cmd: In parameter; command whose argument we're parsing. To be + passed to next_arg_begin(). */ void -parse_color_command(color *col) +parse_color_command(color *col, const char * const cmd) { ColorArg gray = 0; ColorArg red = 0, green = 0, blue = 0; ColorArg cyan = 0, magenta = 0, yellow = 0, black = 0; - Char subcmd = next_arg_begin(); + Char subcmd = next_arg_begin(cmd); switch((int) subcmd) { case 'c': // DFc or mc: CMY - cyan = get_color_arg(); - magenta = get_color_arg(); - yellow = get_color_arg(); + cyan = get_color_arg(cmd); + magenta = get_color_arg(cmd); + yellow = get_color_arg(cmd); col->set_cmy(cyan, magenta, yellow); break; case 'd': // DFd or md: set default color col->set_default(); break; case 'g': // DFg or mg: gray - gray = get_color_arg(); + gray = get_color_arg(cmd); col->set_gray(gray); break; case 'k': // DFk or mk: CMYK - cyan = get_color_arg(); - magenta = get_color_arg(); - yellow = get_color_arg(); - black = get_color_arg(); + cyan = get_color_arg(cmd); + magenta = get_color_arg(cmd); + yellow = get_color_arg(cmd); + black = get_color_arg(cmd); col->set_cmyk(cyan, magenta, yellow, black); break; case 'r': // DFr or mr: RGB - red = get_color_arg(); - green = get_color_arg(); - blue = get_color_arg(); + red = get_color_arg(cmd); + green = get_color_arg(cmd); + blue = get_color_arg(cmd); col->set_rgb(red, green, blue); break; default: @@ -1314,7 +1348,7 @@ parse_color_command(color *col) void parse_D_command() { - Char subcmd = next_arg_begin(); + Char subcmd = next_arg_begin("D"); switch((int) subcmd) { case '~': // D~: draw B-spline // actually, this isn't available for some postprocessors @@ -1365,7 +1399,7 @@ parse_D_command() } case 'f': // Df: set fill gray; obsoleted by DFg { - IntArg arg = get_integer_arg(); + IntArg arg = get_integer_arg("Df"); if ((arg >= 0) && (arg <= 1000)) { // convert arg and treat it like DFg ColorArg gray = color_from_Df_command(arg); @@ -1378,7 +1412,7 @@ parse_D_command() } pr->change_fill_color(current_env); // skip unused 'vertical' component (\D'...' always emits pairs) - (void) get_integer_arg(); + (void) get_integer_arg("Df (unused vertical)"); # ifdef STUPID_DRAWING_POSITIONING current_env->hpos += arg; # endif @@ -1386,7 +1420,7 @@ parse_D_command() break; } case 'F': // DF: set fill color, several formats - parse_color_command(current_env->fill); + parse_color_command(current_env->fill, "DF"); pr->change_fill_color(current_env); // no positioning (setting-only command) skip_line_x(); @@ -1448,13 +1482,13 @@ bool parse_x_command(void) { bool stopped = false; - char *subcmd_str = get_string_arg(); + char *subcmd_str = get_string_arg("x"); char subcmd = subcmd_str[0]; switch (subcmd) { case 'f': // x font: mount font { - IntArg n = get_integer_arg(); - char *name = get_string_arg(); + IntArg n = get_integer_arg("x f"); + char *name = get_string_arg("x f"); pr->load_font(n, name); a_delete name; skip_line_x(); @@ -1472,7 +1506,7 @@ parse_x_command(void) break; } case 'H': // x Height: set character height - current_env->height = get_integer_arg(); + current_env->height = get_integer_arg("x H"); if (current_env->height == current_env->size) current_env->height = 0; skip_line_x(); @@ -1493,7 +1527,7 @@ parse_x_command(void) skip_line_x(); break; case 'S': // x Slant: set slant - current_env->slant = get_integer_arg(); + current_env->slant = get_integer_arg("x S"); skip_line_x(); break; case 't': // x trailer: generate trailer info @@ -1505,7 +1539,7 @@ parse_x_command(void) break; case 'u': // x underline: from .cu { - char *str_arg = get_string_arg(); + char *str_arg = get_string_arg("x u"); pr->special(str_arg, current_env, 'u'); a_delete str_arg; skip_line_x(); @@ -1594,11 +1628,11 @@ do_file(const char *filename) return; if ((int) command != 'x') fatal("the first command must be 'x T'"); - str_arg = get_string_arg(); + str_arg = get_string_arg("x T"); if (str_arg[0] != 'T') fatal("the first command must be 'x T'"); a_delete str_arg; - char *tmp_dev = get_string_arg(); + char *tmp_dev = get_string_arg("x T"); if (pr == 0) { // note: 'pr' initialized after prologue device = tmp_dev; if (!font::load_desc()) @@ -1616,18 +1650,18 @@ do_file(const char *filename) command = next_command(); if ((int) command != 'x') fatal("the second command must be 'x res'"); - str_arg = get_string_arg(); + str_arg = get_string_arg("x res"); if (str_arg[0] != 'r') fatal("the second command must be 'x res'"); a_delete str_arg; - int_arg = get_integer_arg(); + int_arg = get_integer_arg("x res (font)"); EnvInt font_res = font::res; if (int_arg != font_res) fatal("resolution does not match"); - int_arg = get_integer_arg(); + int_arg = get_integer_arg("x res (hor)"); if (int_arg != font::hor) fatal("minimum horizontal motion does not match"); - int_arg = get_integer_arg(); + int_arg = get_integer_arg("x res (vert)"); if (int_arg != font::vert) fatal("minimum vertical motion does not match"); skip_line_x(); // ignore further arguments @@ -1636,7 +1670,7 @@ do_file(const char *filename) command = next_command(); if (command != 'x') fatal("the third command must be 'x init'"); - str_arg = get_string_arg(); + str_arg = get_string_arg("x init"); if (str_arg[0] != 'i') fatal("the third command must be 'x init'"); a_delete str_arg; @@ -1676,7 +1710,7 @@ do_file(const char *filename) case '9': { // expect 2 digits and a character char s[3]; - Char c = next_arg_begin(); + Char c = next_arg_begin("jump-and-move (digits)"); if (npages <= 0) fatal_command(command); if (!isdigit((int) c)) { @@ -1692,7 +1726,7 @@ do_file(const char *filename) error("couldn't convert 2 digits"); EnvInt hor_pos = (EnvInt) x; current_env->hpos += hor_pos; - c = next_arg_begin(); + c = next_arg_begin("jump-and-move (character)"); if ((int) c == '\n' || (int) c == EOF) error("character argument expected"); else @@ -1703,10 +1737,8 @@ do_file(const char *filename) { if (npages <= 0) fatal_command(command); - Char c = next_arg_begin(); - if (c == '\n' || c == EOF) - error("missing argument to 'c' command"); - else + Char c = next_arg_begin("c"); + if (c != '\n' && c != EOF) pr->set_ascii_char((unsigned char) c, current_env); break; } @@ -1714,7 +1746,7 @@ do_file(const char *filename) { if (npages <= 0) fatal_command(command); - char *str_arg = get_string_arg(); + char *str_arg = get_string_arg("C"); pr->set_special_char(str_arg, current_env); a_delete str_arg; break; @@ -1725,7 +1757,7 @@ do_file(const char *filename) parse_D_command(); break; case 'f': // f: set font to number - current_env->fontno = get_integer_arg(); + current_env->fontno = get_integer_arg("f"); break; case 'F': // F: obsolete, replaced by 'x F' { @@ -1735,13 +1767,13 @@ do_file(const char *filename) break; } case 'h': // h: relative horizontal move - current_env->hpos += (EnvInt) get_integer_arg(); + current_env->hpos += (EnvInt) get_integer_arg("h"); break; case 'H': // H: absolute horizontal positioning - current_env->hpos = (EnvInt) get_integer_arg(); + current_env->hpos = (EnvInt) get_integer_arg("H"); break; case 'm': // m: glyph color - parse_color_command(current_env->col); + parse_color_command(current_env->col, "m"); pr->change_color(current_env); break; case 'n': // n: print end of line @@ -1749,23 +1781,23 @@ do_file(const char *filename) if (npages <= 0) fatal_command(command); pr->end_of_line(); - (void) get_integer_arg(); - (void) get_integer_arg(); + (void) get_integer_arg("n (first ignored)"); + (void) get_integer_arg("n (second ignored)"); break; case 'N': // N: print char with given int code if (npages <= 0) fatal_command(command); - pr->set_numbered_char(get_integer_arg(), current_env); + pr->set_numbered_char(get_integer_arg("N"), current_env); break; case 'p': // p: start new page with given number if (npages > 0) pr->end_page(current_env->vpos); npages++; // increment # of processed pages - pr->begin_page(get_integer_arg()); + pr->begin_page(get_integer_arg("p")); current_env->vpos = 0; break; case 's': // s: set point size - current_env->size = get_integer_arg(); + current_env->size = get_integer_arg("s"); if (current_env->height == current_env->size) current_env->height = 0; break; @@ -1774,7 +1806,7 @@ do_file(const char *filename) char c; if (npages <= 0) fatal_command(command); - char *str_arg = get_string_arg(); + char *str_arg = get_string_arg("t"); size_t i = 0; while ((c = str_arg[i++]) != '\0') { EnvInt w; @@ -1789,8 +1821,8 @@ do_file(const char *filename) char c; if (npages <= 0) fatal_command(command); - EnvInt kern = (EnvInt) get_integer_arg(); - char *str_arg = get_string_arg(); + EnvInt kern = (EnvInt) get_integer_arg("u"); + char *str_arg = get_string_arg("u"); size_t i = 0; while ((c = str_arg[i++]) != '\0') { EnvInt w; @@ -1801,10 +1833,10 @@ do_file(const char *filename) break; } case 'v': // v: relative vertical move - current_env->vpos += (EnvInt) get_integer_arg(); + current_env->vpos += (EnvInt) get_integer_arg("v"); break; case 'V': // V: absolute vertical positioning - current_env->vpos = (EnvInt) get_integer_arg(); + current_env->vpos = (EnvInt) get_integer_arg("V"); break; case 'w': // w: inform about paddable space break; diff --git a/src/libs/libgroff/errarg.cpp b/src/libs/libgroff/errarg.cpp index 593e2a57..6cb5fd12 100644 --- a/src/libs/libgroff/errarg.cpp +++ b/src/libs/libgroff/errarg.cpp @@ -121,7 +121,7 @@ void errprint(const char *format, arg3.print(); break; default: - assert(0); + assert(0 == "unsupported format specifier given to errprint()"); } } else