Follow-up Comment #1, bug #60981 (project groff): Work in progress.
commit 6a7294a254808b590c2417d730a1a12a566618c2 (HEAD -> master) Author: G. Branden Robinson <[email protected]> AuthorDate: Wed Jul 28 16:51:41 2021 +1000 Commit: G. Branden Robinson <[email protected]> CommitDate: Wed Jul 28 16:53:55 2021 +1000 [grohtml]: Fix Savannah #60981. Refactor device description file handling, make it more robust, and make this preprocessor's -F option work as documented, and to honor documented device description file semantics. * src/preproc/html/pre-html.cpp: Store partial filespecs of HTML and PostScript device files in constant strings. (get_resolution): Initialize `res` to zero. Only `free()` the pointer `pathp` if `open_file()` succeeded (populating it). Stop checking for valid `sscanf()` conversions of an integer to store in `res`, and don't return early. Instead process the whole DESC file; per our Texinfo manual and groff_font(5), "Later entries in the file ... override previous values." (get_image_generator): Add new function, paralleling `get_resolution()`, replacing open-coded logic in `main()`. Only the body of the `while` loop significantly differs. Instead of using `sscanf`, process the input character by character matching the keyword and {1,} spaces or tabs after it. Whatever follows in `linebuf` must be the program name. (imageList::createPage): Add `assert()` to cause failure if an empty image generator program gets this far, because it creates repeated messes if it does. (Something isn't checking exit statuses.) (main): Condense `image_gen` collection to a function call, a null pointer check, and a fatal diagnostic. Add a sanity check and a fatal diagnostic if the PostScript resolution is garbage. (It's initialized to -1 and `get_resolution()` will return 0 if it doesn't find one.) Fixes <https://savannah.gnu.org/bugs/?60981>. [...] diff --git a/src/preproc/html/pre-html.cpp b/src/preproc/html/pre-html.cpp index d32d46ae..25c9180c 100644 --- a/src/preproc/html/pre-html.cpp +++ b/src/preproc/html/pre-html.cpp @@ -217,6 +217,9 @@ static char *linebuf = NULL; // for scanning devps/DESC static int linebufsize = 0; static const char *image_gen = NULL; // the 'gs' program +static const char devhtml_desc[] = "devhtml/DESC"; +static const char devps_desc[] = "devps/DESC"; + const char *const FONT_ENV_VAR = "GROFF_FONT_PATH"; static search_path font_path(FONT_ENV_VAR, FONTPATH, 0, 0); static html_dialect dialect = html4; @@ -287,27 +290,61 @@ int get_line(FILE *f) } /* - * get_resolution - Return the postscript resolution from devps/DESC. + * get_resolution - Return the PostScript device resolution. */ static unsigned int get_resolution(void) { char *pathp; FILE *f; - unsigned int res; - f = font_path.open_file("devps/DESC", &pathp); + unsigned int res = 0; + f = font_path.open_file(devps_desc, &pathp); + if (0 == f) + fatal("cannot open file '%1'", devps_desc); free(pathp); - if (f == 0) - fatal("can't open devps/DESC"); while (get_line(f)) { - int n = sscanf(linebuf, "res %u", &res); - if (n >= 1) { - fclose(f); - return res; + (void) sscanf(linebuf, "res %u", &res); + } + fclose(f); + return res; +} + + +/* + * get_image_generator - Return the declared program from the HTML + * device description. + */ + +static char *get_image_generator(void) +{ + char *pathp; + FILE *f; + char *generator = 0; + const char keyword[] = "image_generator"; + size_t keyword_len = strlen(keyword); + f = font_path.open_file(devhtml_desc, &pathp); + if (0 == f) + fatal("cannot open file '%1'", devhtml_desc); + free(pathp); + while (get_line(f)) { + char *cursor = linebuf; + size_t limit = strlen(linebuf); + char *end = linebuf + limit; + if (0 == (strncmp(linebuf, keyword, keyword_len))) { + cursor += keyword_len; + // At least one space or tab is required. + if(!(' ' == *cursor) || ('\t' == *cursor)) + continue; + cursor++; + while((' ' == *cursor) || ('\t' == *cursor) && (cursor < end)) + cursor++; + if (cursor == end) + continue; + generator = cursor; } } - fatal("can't find 'res' keyword in devps/DESC"); - return 0; + fclose(f); + return generator; } /* @@ -929,6 +966,7 @@ int imageList::createPage(int pageno) sys_fatal("make_message"); html_system(s, 1); + assert(strlen(image_gen) > 0); s = make_message("echo showpage | " "%s%s -q -dBATCH -dSAFER " "-dDEVICEHEIGHTPOINTS=792 " @@ -1784,14 +1822,14 @@ int main(int argc, char **argv) #endif /* CAPTURE_MODE */ device = "html"; i = scanArguments(argc, argv); - if (!font::load_desc()) - fatal("cannot find devhtml/DESC exiting"); - image_gen = font::image_generator; - if (image_gen == NULL || (strcmp(image_gen, "") == 0)) - fatal("devhtml/DESC must set the image_generator field, exiting"); - debug("image_gen: '%1'", image_gen); + image_gen = strsave(get_image_generator()); + if (0 == image_gen) + fatal("'image_generator' directive not found in file '%1'", + devhtml_desc); postscriptRes = get_resolution(); - debug("res: '%1'", postscriptRes); + if (postscriptRes < 1) // TODO: what's a more sane minimum value? + fatal("'res' directive missing or invalid in file '%1'", + devps_desc); setupAntiAlias(); checkImageDir(); makeFileName(); _______________________________________________________ Reply to this item at: <https://savannah.gnu.org/bugs/?60981> _______________________________________________ Message sent via Savannah https://savannah.gnu.org/
