Update of bug #68252 (group groff):
Status: Confirmed => In Progress
_______________________________________________________
Follow-up Comment #6:
I have a fix.
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 53295db10..983f470c2 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -7002,28 +7002,60 @@ bool is_valid_font(int n)
// Read the next token and look it up as a font name or position number.
// Return lookup success. Store, in the supplied struct argument, the
// requested name or position, and the position actually resolved.
+//
+// TODO: This duplicates logic from env.cpp:select_font(). Refactor.
+// Need read_font_mounting_position_or_identifier(), storing the
+// resolved mounting position in an argument.
static bool read_font_identifier(font_lookup_info *finfo)
{
- int n;
tok.skip_spaces();
- if (tok.is_usable_as_delimiter()) {
- symbol s = read_identifier(true /* want_diagnostic */);
+ // Painful. We read the whole argument as a symbol, then see if it's
+ // interpretable as an (unsigned) decimal integer. If is, we treat it
+ // as a mounting position. If not, we treat it as a font "name".
+ symbol s = read_identifier();
+ bool is_number = true;
+ assert(!s.is_null() && !s.is_empty());
+ if (!s.is_null() && !s.is_empty()) {
+ const char *p = s.contents();
+ assert(*p != 0 /* nullptr */);
+ // Silently ignore a leading minus sign so we can issue a range
+ // warning later.
+ if ((csdigit(*p)) || ('-' == *p))
+ p++;
+ for (; (p != 0 /* nullptr */) && (*p != '\0'); p++) {
+ if (!csdigit(*p)) {
+ is_number = false;
+ break;
+ }
+ }
+ }
+ if (is_number) {
+ errno = 0;
+ long val = strtol(s.contents(), NULL, 10);
+ if ((ERANGE == errno) || (val > INT_MAX) || (val < 0)) {
+ warning(WARN_RANGE, "font mounting position must be in range"
+ " 0..%1, got %2", INT_MAX, s.contents());
+ return false;
+ }
+ int mp = int(val);
+ if (!is_valid_font_mounting_position(mp)) {
+ warning(WARN_FONT, "no font mounted at position %1", mp);
+ return false;
+ }
+ finfo->position = curenv->get_family()->resolve(mp);
+ }
+ else {
finfo->requested_name = const_cast<char *>(s.contents());
if (!s.is_null()) {
- n = mounting_position_of_font(s);
- if (n < 0) {
- n = next_available_font_mounting_position();
- if (mount_font_at_position(s, n))
- finfo->position = n;
+ int mp = mounting_position_of_font(s);
+ if (mp < 0) {
+ mp = next_available_font_mounting_position();
+ if (mount_font_at_position(s, mp))
+ finfo->position = mp;
}
- finfo->position = curenv->get_family()->resolve(n);
+ finfo->position = curenv->get_family()->resolve(mp);
}
}
- else if (read_integer(&n)) {
- finfo->requested_position = n;
- if (is_valid_font_mounting_position(n))
- finfo->position = curenv->get_family()->resolve(n);
- }
return (finfo->position != FONT_NOT_MOUNTED);
}
_______________________________________________________
Reply to this item at:
<https://savannah.gnu.org/bugs/?68252>
_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/
signature.asc
Description: PGP signature
