* mandoc: Even though roff(7) numerical expressions use integer arithmetic
@ 2025-01-06 18:50 schwarze
0 siblings, 0 replies; only message in thread
From: schwarze @ 2025-01-06 18:50 UTC (permalink / raw)
To: source
Log Message:
-----------
Even though roff(7) numerical expressions use integer arithmetic throughout
and all numbers are rounded down before any arithmetic operation is attempted,
let the number parser support decimal fractions in front of scaling units,
which is useful for all scaling units except basic units ('u').
For example, this allows 0.25i = 2.5n = 60u.
On the other hand, even though 3p = 10u, we get 1p+1p+1p = 1p*3 = 9u
because arithmetic operations do not support floating point,
so the intermediate result gets rounded down as 1p = 3.33u = 3u.
Modified Files:
--------------
mandoc:
roff.c
mandoc/regress/roff/nr:
scale.in
scale.out_ascii
Revision Data
-------------
Index: roff.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/roff.c,v
diff -Lroff.c -Lroff.c -u -p -r1.403 -r1.404
--- roff.c
+++ roff.c
@@ -2422,7 +2422,7 @@ roff_cond_text(ROFF_ARGS)
/* --- handling of numeric and conditional expressions -------------------- */
/*
- * Parse a single signed integer number. Stop at the first non-digit.
+ * Parse a single signed decimal number. Stop at the first non-digit.
* If there is at least one digit, return success and advance the
* parse point, else return failure and let the parse point unchanged.
* Ignore overflows, treat them just like the C language.
@@ -2430,10 +2430,8 @@ roff_cond_text(ROFF_ARGS)
static int
roff_getnum(const char *v, int *pos, int *res, char unit, int skipspace)
{
- int myres, n, p;
-
- if (NULL == res)
- res = &myres;
+ double frac, myres;
+ int n, p;
p = *pos;
n = v[p] == '-';
@@ -2444,13 +2442,17 @@ roff_getnum(const char *v, int *pos, int
while (isspace((unsigned char)v[p]))
p++;
- for (*res = 0; isdigit((unsigned char)v[p]); p++)
- *res = 10 * *res + v[p] - '0';
+ for (myres = 0.0; isdigit((unsigned char)v[p]); p++)
+ myres = myres * 10.0 + (v[p] - '0');
+ if (v[p] == '.')
+ for (frac = 0.1; isdigit((unsigned char)v[++p]); frac *= 0.1)
+ myres += frac * (v[p] - '0');
+
if (p == *pos + n)
return 0;
if (n)
- *res = -*res;
+ myres *= -1.0;
/* Each number may be followed by one optional scaling unit. */
@@ -2462,36 +2464,35 @@ roff_getnum(const char *v, int *pos, int
switch (unit) {
case 'f':
- *res *= 65536;
+ myres *= 65536.0;
break;
case 'i':
- *res *= 240;
+ myres *= 240.0;
break;
case 'c':
- *res *= 24000;
- *res /= 254;
+ myres *= 240.0 / 2.54;
break;
case 'v':
case 'P':
- *res *= 40;
+ myres *= 40.0;
break;
case 'm':
case 'n':
- *res *= 24;
+ myres *= 24.0;
break;
case 'p':
- *res *= 10;
- *res /= 3;
+ myres *= 40.0 / 12.0;
break;
case 'u':
break;
case 'M':
- *res *= 6;
- *res /= 25;
+ myres *= 24.0 / 100.0;
break;
default:
break;
}
+ if (res != NULL)
+ *res = myres;
*pos = p;
return 1;
}
Index: scale.out_ascii
===================================================================
RCS file: /home/cvs/mandoc/mandoc/regress/roff/nr/scale.out_ascii,v
diff -Lregress/roff/nr/scale.out_ascii -Lregress/roff/nr/scale.out_ascii -u -p -r1.3 -r1.4
--- regress/roff/nr/scale.out_ascii
+++ regress/roff/nr/scale.out_ascii
@@ -6,4 +6,8 @@ N\bNA\bAM\bME\bE
D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
65537 241 945 41 41 25 25 34 2 25 1
-OpenBSD January 23, 2015 NR-INT(1)
+ 0.001f = 65u; 0.1i = 24u; 0.1c = 9u; 0.25P = 10u; 0.6p = 2u
+
+ 3p = 10u; 1p+1p+1p = 9u; 1p*3 = 9u
+
+OpenBSD January 6, 2025 NR-INT(1)
Index: scale.in
===================================================================
RCS file: /home/cvs/mandoc/mandoc/regress/roff/nr/scale.in,v
diff -Lregress/roff/nr/scale.in -Lregress/roff/nr/scale.in -u -p -r1.2 -r1.3
--- regress/roff/nr/scale.in
+++ regress/roff/nr/scale.in
@@ -1,5 +1,5 @@
-.\" $OpenBSD: scale.in,v 1.2 2017/07/04 14:53:27 schwarze Exp $
-.TH NR-INT 1 "January 23, 2015"
+.\" $OpenBSD: scale.in,v 1.3 2025/01/06 18:48:13 schwarze Exp $
+.TH NR-INT 1 "January 6, 2025"
.SH NAME
nr-scale \- scaling units in numeric expressions
.SH DESCRIPTION
@@ -25,3 +25,21 @@ nr-scale \- scaling units in numeric exp
\nY
.nr Y 1X+2
\nY
+.PP
+.nr Y 0.001f
+0.001f = \nYu;
+.nr Y 0.1i
+0.1i = \nYu;
+.nr Y 0.1c
+0.1c = \nYu;
+.nr Y 0.25P
+0.25P = \nYu;
+.nr Y 0.6p
+0.6p = \nYu
+.PP
+.nr Y 3p
+3p = \nYu;
+.nr Y 1p+1p+1p
+1p+1p+1p = \nYu;
+.nr Y 1p*3
+1p*3 = \nYu
--
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-06 18:50 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-01-06 18:50 mandoc: Even though roff(7) numerical expressions use integer arithmetic 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).