* mandoc: Add an additional argument to the functions implementing the
@ 2025-01-05 16:58 schwarze
0 siblings, 0 replies; only message in thread
From: schwarze @ 2025-01-05 16:58 UTC (permalink / raw)
To: source
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 <schwarze@openbsd.org>
+ * Copyright (c) 2010-2015, 2017-2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
*
* 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
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2025-01-05 16:58 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-01-05 16:58 mandoc: Add an additional argument to the functions implementing the schwarze
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).