gbranden pushed a commit to branch master
in repository groff.
commit 9a9d7b55b6cc565ed2c065b8e993bdac9fb576d1
Author: G. Branden Robinson <[email protected]>
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 <[email protected]>
+
+ [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 <[email protected]>
[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
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit