From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.4 Received: from mandoc.bsd.lv (bsd.lv [66.111.2.12]) by inbox.vuxu.org (Postfix) with ESMTP id C072820F40 for ; Sun, 5 Jan 2025 17:58:53 +0100 (CET) Received: from fantadrom.bsd.lv (localhost [127.0.0.1]) by mandoc.bsd.lv (OpenSMTPD) with ESMTP id db9164ad for ; Sun, 5 Jan 2025 16:58:52 +0000 (UTC) Received: from localhost (mandoc.bsd.lv [local]) by mandoc.bsd.lv (OpenSMTPD) with ESMTPA id 350af47e for ; Sun, 5 Jan 2025 16:58:52 +0000 (UTC) Date: Sun, 5 Jan 2025 16:58:52 +0000 (UTC) X-Mailinglist: mandoc-source Reply-To: source@mandoc.bsd.lv MIME-Version: 1.0 From: schwarze@mandoc.bsd.lv To: source@mandoc.bsd.lv Subject: mandoc: Add an additional argument to the functions implementing the X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Message-ID: <95009fa137dccb29@mandoc.bsd.lv> Log Message: ----------- Add an additional argument to the functions implementing the roff(7) numerical parser to select the default scaling unit for numbers not followed by a scaling unit, rather than always using basic units ('u'). Expose roff_evalnum() via the internal parser API such that, in addition to the roff(7) parser, other parsers become able to parse numerical expressions, too. This commit implies no functional change yet, but prepares for adding new functionality in future commits. Modified Files: -------------- mandoc: libmandoc.h roff.c Revision Data ------------- Index: roff.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/roff.c,v diff -Lroff.c -Lroff.c -u -p -r1.402 -r1.403 --- roff.c +++ roff.c @@ -1,6 +1,6 @@ /* $Id$ */ /* - * Copyright (c) 2010-2015, 2017-2024 Ingo Schwarze + * Copyright (c) 2010-2015, 2017-2025 Ingo Schwarze * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons * * Permission to use, copy, modify, and distribute this software for any @@ -192,8 +192,8 @@ static int roff_ec(ROFF_ARGS); static int roff_eo(ROFF_ARGS); static int roff_eqndelim(struct roff *, struct buf *, int); static int roff_evalcond(struct roff *, int, char *, int *); -static int roff_evalnum(int, const char *, int *, int *, int); -static int roff_evalpar(int, const char *, int *, int *, int); +static int roff_evalpar(int, const char *, int *, int *, + char, int); static int roff_evalstrcond(const char *, int *); static int roff_expand(struct roff *, struct buf *, int, int, char); @@ -203,7 +203,7 @@ static void roff_free1(struct roff *); static void roff_freereg(struct roffreg *); static void roff_freestr(struct roffkv *); static size_t roff_getname(char **, int, int); -static int roff_getnum(const char *, int *, int *, int); +static int roff_getnum(const char *, int *, int *, char, int); static int roff_getop(const char *, int *, char *); static int roff_getregn(struct roff *, const char *, size_t, char); @@ -256,9 +256,6 @@ static int roff_userdef(ROFF_ARGS); /* --- constant data ------------------------------------------------------ */ -#define ROFFNUM_SCALE (1 << 0) /* Honour scaling in roff_getnum(). */ -#define ROFFNUM_WHITE (1 << 1) /* Skip whitespace in roff_evalnum(). */ - const char *__roff_name[MAN_MAX + 1] = { "br", "ce", "fi", "ft", "ll", "mc", "nf", @@ -1528,7 +1525,7 @@ roff_expand(struct roff *r, struct buf * npos = 0; ubuf[0] = iendarg > iarg && iend > iendarg && roff_evalnum(ln, buf->buf + iarg, &npos, - NULL, ROFFNUM_SCALE) && + NULL, 'u', 0) && npos == iendarg - iarg ? '1' : '0'; ubuf[1] = '\0'; res = ubuf; @@ -2431,9 +2428,9 @@ roff_cond_text(ROFF_ARGS) * Ignore overflows, treat them just like the C language. */ static int -roff_getnum(const char *v, int *pos, int *res, int flags) +roff_getnum(const char *v, int *pos, int *res, char unit, int skipspace) { - int myres, scaled, n, p; + int myres, n, p; if (NULL == res) res = &myres; @@ -2443,7 +2440,7 @@ roff_getnum(const char *v, int *pos, int if (n || v[p] == '+') p++; - if (flags & ROFFNUM_WHITE) + if (skipspace) while (isspace((unsigned char)v[p])) p++; @@ -2457,42 +2454,45 @@ roff_getnum(const char *v, int *pos, int /* Each number may be followed by one optional scaling unit. */ - switch (v[p]) { + if (v[p] != '\0' && strchr("ficvPmnpuM", v[p]) != NULL) { + if (unit != '\0') + unit = v[p]; + p++; + } + + switch (unit) { case 'f': - scaled = *res * 65536; + *res *= 65536; break; case 'i': - scaled = *res * 240; + *res *= 240; break; case 'c': - scaled = *res * 240 / 2.54; + *res *= 24000; + *res /= 254; break; case 'v': case 'P': - scaled = *res * 40; + *res *= 40; break; case 'm': case 'n': - scaled = *res * 24; + *res *= 24; break; case 'p': - scaled = *res * 10 / 3; + *res *= 10; + *res /= 3; break; case 'u': - scaled = *res; break; case 'M': - scaled = *res * 6 / 25; + *res *= 6; + *res /= 25; break; default: - scaled = *res; - p--; break; } - if (flags & ROFFNUM_SCALE) - *res = scaled; - - *pos = p + 1; + *pos = p; return 1; } @@ -2631,7 +2631,7 @@ roff_evalcond(struct roff *r, int ln, ch } savepos = *pos; - if (roff_evalnum(ln, v, pos, &number, ROFFNUM_SCALE)) + if (roff_evalnum(ln, v, pos, &number, 'u', 0)) return (number > 0) == wanttrue; else if (*pos == savepos) return roff_evalstrcond(v, pos) == wanttrue; @@ -2860,14 +2860,15 @@ roff_getop(const char *v, int *pos, char * or a single signed integer number. */ static int -roff_evalpar(int ln, const char *v, int *pos, int *res, int flags) +roff_evalpar(int ln, const char *v, int *pos, int *res, char unit, + int skipspace) { if ('(' != v[*pos]) - return roff_getnum(v, pos, res, flags); + return roff_getnum(v, pos, res, unit, skipspace); (*pos)++; - if ( ! roff_evalnum(ln, v, pos, res, flags | ROFFNUM_WHITE)) + if ( ! roff_evalnum(ln, v, pos, res, unit, 1)) return 0; /* @@ -2888,8 +2889,9 @@ roff_evalpar(int ln, const char *v, int * Evaluate a complete numeric expression. * Proceed left to right, there is no concept of precedence. */ -static int -roff_evalnum(int ln, const char *v, int *pos, int *res, int flags) +int +roff_evalnum(int ln, const char *v, int *pos, int *res, char unit, + int skipspace) { int mypos, operand2; char operator; @@ -2899,29 +2901,29 @@ roff_evalnum(int ln, const char *v, int pos = &mypos; } - if (flags & ROFFNUM_WHITE) + if (skipspace) while (isspace((unsigned char)v[*pos])) (*pos)++; - if ( ! roff_evalpar(ln, v, pos, res, flags)) + if ( ! roff_evalpar(ln, v, pos, res, unit, skipspace)) return 0; while (1) { - if (flags & ROFFNUM_WHITE) + if (skipspace) while (isspace((unsigned char)v[*pos])) (*pos)++; if ( ! roff_getop(v, pos, &operator)) break; - if (flags & ROFFNUM_WHITE) + if (skipspace) while (isspace((unsigned char)v[*pos])) (*pos)++; - if ( ! roff_evalpar(ln, v, pos, &operand2, flags)) + if ( ! roff_evalpar(ln, v, pos, &operand2, unit, skipspace)) return 0; - if (flags & ROFFNUM_WHITE) + if (skipspace) while (isspace((unsigned char)v[*pos])) (*pos)++; @@ -3162,13 +3164,13 @@ roff_nr(ROFF_ARGS) val++; len = 0; - if (roff_evalnum(ln, val, &len, &iv, ROFFNUM_SCALE) == 0) + if (roff_evalnum(ln, val, &len, &iv, 'u', 0) == 0) return ROFF_IGN; step = val + len; while (isspace((unsigned char)*step)) step++; - if (roff_evalnum(ln, step, NULL, &is, 0) == 0) + if (roff_evalnum(ln, step, NULL, &is, '\0', 0) == 0) is = INT_MIN; roff_setregn(r, key, keysz, iv, sign, is); @@ -3231,7 +3233,7 @@ roff_it(ROFF_ARGS) /* Parse the number of lines. */ - if ( ! roff_evalnum(ln, buf->buf, &pos, &iv, 0)) { + if ( ! roff_evalnum(ln, buf->buf, &pos, &iv, '\0', 0)) { mandoc_msg(MANDOCERR_IT_NONUM, ln, ppos, "%s", buf->buf + 1); return ROFF_IGN; @@ -3499,7 +3501,7 @@ roff_onearg(ROFF_ARGS) } npos = 0; if (roff_evalnum(ln, r->man->last->string, &npos, - &roffce_lines, 0) == 0) { + &roffce_lines, '\0', 0) == 0) { mandoc_msg(MANDOCERR_CE_NONUM, ln, pos, "ce %s", buf->buf + pos); roffce_lines = 1; @@ -3881,7 +3883,7 @@ roff_shift(ROFF_ARGS) argpos = pos; levels = 1; if (buf->buf[pos] != '\0' && - roff_evalnum(ln, buf->buf, &pos, &levels, 0) == 0) { + roff_evalnum(ln, buf->buf, &pos, &levels, '\0', 0) == 0) { mandoc_msg(MANDOCERR_CE_NONUM, ln, pos, "shift %s", buf->buf + pos); levels = 1; Index: libmandoc.h =================================================================== RCS file: /home/cvs/mandoc/mandoc/libmandoc.h,v diff -Llibmandoc.h -Llibmandoc.h -u -p -r1.80 -r1.81 --- libmandoc.h +++ libmandoc.h @@ -78,6 +78,7 @@ void roff_userret(struct roff *); void roff_endparse(struct roff *); void roff_setreg(struct roff *, const char *, int, char); int roff_getreg(struct roff *, const char *); +int roff_evalnum(int, const char *, int *, int *, char, int); char *roff_strdup(const struct roff *, const char *); char *roff_getarg(struct roff *, char **, int, int *); int roff_getcontrol(const struct roff *, -- To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv