gbranden pushed a commit to branch master in repository groff. commit 9a9d7b55b6cc565ed2c065b8e993bdac9fb576d1 Author: G. Branden Robinson <g.branden.robin...@gmail.com> AuthorDate: Fri Feb 21 04:05:40 2025 -0600
[troff]: Create characters less aggressively. Make it possible to retrieve information about a *roff character without creating it as a side effect. * src/roff/troff/charinfo.h (get_charinfo, get_charinfo_by_index): * src/roff/troff/token.h (get_char): * src/roff/troff/input.cpp (get_charinfo_by_index): Add new `bool` argument `lookup_only`, defaulting `false`. * src/roff/troff/input.cpp: Use these new facilities. (report_character_request): Prevent creation of each character we look up. Improve diagnostics. Report information about indexed characters (`\N'123'`) more intelligibly. (remove_character): Prevent creation of each character we remove. Intelligibly report nonexistence of characters for which removal is attempted. Throw error when attempt is made to remove a non-character, like `\~`. --- ChangeLog | 18 ++++++++++++ src/roff/troff/charinfo.h | 2 +- src/roff/troff/input.cpp | 74 ++++++++++++++++++++++++++++++++++------------- src/roff/troff/token.h | 3 +- 4 files changed, 75 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index afad02463..c03dd90ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2025-02-21 G. Branden Robinson <g.branden.robin...@gmail.com> + + [troff]: Make it possible to retrieve information about a *roff + character without creating it as a side effect. + + * src/roff/troff/charinfo.h (get_charinfo): + * src/roff/troff/token.h (get_char): + * src/roff/troff/input.cpp (get_charinfo_by_index): Add new + `bool` argument `lookup_only`, defaulting `false`. + * src/roff/troff/input.cpp: Use these new facilities. + (report_character_request): Prevent creation of each character + we look up. Improve diagnostics. Report information about + indexed characters (`\N'123'`) more intelligibly. + (remove_character): Prevent creation of each character we + remove. Intelligibly report nonexistence of characters for + which removal is attempted. Throw error when attempt is made to + remove a non-character, like `\~`. + 2025-02-21 G. Branden Robinson <g.branden.robin...@gmail.com> [troff]: Add member functions to `token` class to assist with diff --git a/src/roff/troff/charinfo.h b/src/roff/troff/charinfo.h index 05d785e91..93c1ca8a1 100644 --- a/src/roff/troff/charinfo.h +++ b/src/roff/troff/charinfo.h @@ -114,7 +114,7 @@ public: void dump(); }; -charinfo *get_charinfo(symbol); +charinfo *get_charinfo(symbol, bool /* lookup_only */ = false); extern charinfo *charset_table[]; inline bool charinfo::overlaps_horizontally() diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp index 54072a520..f67090bef 100644 --- a/src/roff/troff/input.cpp +++ b/src/roff/troff/input.cpp @@ -4690,12 +4690,26 @@ static void report_character_request() } charinfo *ci; do { - ci = tok.get_char(); - if (0 /* nullptr */ == ci) - warning(WARN_CHAR, "%1 is not a character", tok.description()); + ci = tok.get_char(false, true /* lookup only */); + if (!tok.is_character()) { + error("character report request expects characters as arguments;" + " got %1", tok.description()); + break; + } + if (0 /* nullptr */ == ci) { + if (!tok.is_indexed_character()) + warning(WARN_CHAR, "%1 is not defined", tok.description()); + else + warning(WARN_CHAR, "character with index %1 in the current font" + " is not defined", tok.character_index()); + } else { // A charinfo doesn't know the name by which it is accessed. - errprint("%1\n", tok.description()); + if (tok.is_indexed_character()) + errprint("character indexed %1 in current font\n", + tok.character_index()); + else + errprint("%1\n", tok.description()); fflush(stderr); ci->dump(); } @@ -4714,12 +4728,27 @@ static void remove_character() } while (!tok.is_newline() && !tok.is_eof()) { if (!tok.is_space() && !tok.is_tab()) { - charinfo *ci = tok.get_char(true /* required */); - if (0 /* nullptr */ == ci) + if (tok.is_character()) { + charinfo *ci = tok.get_char(true /* required */, + true /* lookup only */); + if (0 /* nullptr */ == ci) { + if (!tok.is_indexed_character()) + warning(WARN_CHAR, "%1 is not defined", tok.description()); + else + warning(WARN_CHAR, "character with index %1 in the current" + " font is not defined", tok.character_index()); + } + else { + macro *m = ci->set_macro(0 /* nullptr */); + if (m) + delete m; + } + } + else { + error("cannot remove character; %1 is not a character", + tok.description()); break; - macro *m = ci->set_macro(0 /* nullptr */); - if (m) - delete m; + } } tok.next(); } @@ -8148,16 +8177,17 @@ void define_class() skip_line(); } -static charinfo *get_charinfo_by_index(int n); // forward declaration +// forward declaration +static charinfo *get_charinfo_by_index(int n, bool lookup_only = false); -charinfo *token::get_char(bool required) +charinfo *token::get_char(bool required, bool lookup_only) { if (type == TOKEN_CHAR) return charset_table[c]; if (type == TOKEN_SPECIAL_CHAR) - return get_charinfo(nm); + return get_charinfo(nm, lookup_only); if (type == TOKEN_INDEXED_CHAR) - return get_charinfo_by_index(val); + return get_charinfo_by_index(val, lookup_only); if (type == TOKEN_ESCAPE) { if (escape_char != 0) return charset_table[escape_char]; @@ -9986,14 +10016,18 @@ void debug_with_file_and_line(const char *filename, dictionary charinfo_dictionary(501); -charinfo *get_charinfo(symbol nm) +charinfo *get_charinfo(symbol nm, bool lookup_only) { void *p = charinfo_dictionary.lookup(nm); if (p != 0 /* nullptr */) return static_cast<charinfo *>(p); - charinfo *cp = new charinfo(nm); - (void) charinfo_dictionary.lookup(nm, cp); - return cp; + if (lookup_only) + return static_cast<charinfo *>(0 /* nullptr */); + else { + charinfo *cp = new charinfo(nm); + (void) charinfo_dictionary.lookup(nm, cp); + return cp; + } } int charinfo::next_index = 0; @@ -10211,13 +10245,13 @@ symbol UNNAMED_SYMBOL("---"); dictionary indexed_charinfo_dictionary(11); -static charinfo *get_charinfo_by_index(int n) +static charinfo *get_charinfo_by_index(int n, bool lookup_only) { static charinfo *index_table[256]; if (n >= 0 && n < 256) { charinfo *ci = index_table[n]; - if (0 /*nullptr */ == ci) { + if ((0 /*nullptr */ == ci) && !lookup_only) { ci = new charinfo(UNNAMED_SYMBOL); ci->set_number(n); index_table[n] = ci; @@ -10227,7 +10261,7 @@ static charinfo *get_charinfo_by_index(int n) else { symbol ns(i_to_a(n)); charinfo *ci = (charinfo *)indexed_charinfo_dictionary.lookup(ns); - if (0 /*nullptr */ == ci) { + if ((0 /*nullptr */ == ci) && !lookup_only) { ci = new charinfo(UNNAMED_SYMBOL); ci->set_number(n); (void) indexed_charinfo_dictionary.lookup(ns, ci); diff --git a/src/roff/troff/token.h b/src/roff/troff/token.h index 796d2b1bf..a3da2e2d2 100644 --- a/src/roff/troff/token.h +++ b/src/roff/troff/token.h @@ -99,7 +99,8 @@ public: bool operator!=(const token &); // ditto unsigned char ch(); int character_index(); - charinfo *get_char(bool /* required */ = false); + charinfo *get_char(bool /* required */ = false, + bool /* lookup_only */ = false); bool add_to_zero_width_node_list(node **); void make_space(); void make_newline(); _______________________________________________ groff-commit mailing list groff-commit@gnu.org https://lists.gnu.org/mailman/listinfo/groff-commit