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 2DDF62ED34 for ; Mon, 6 Jan 2025 19:50:22 +0100 (CET) Received: from fantadrom.bsd.lv (localhost [127.0.0.1]) by mandoc.bsd.lv (OpenSMTPD) with ESMTP id a849ecf8 for ; Mon, 6 Jan 2025 18:50:21 +0000 (UTC) Received: from localhost (mandoc.bsd.lv [local]) by mandoc.bsd.lv (OpenSMTPD) with ESMTPA id c0bb2d07 for ; Mon, 6 Jan 2025 18:50:21 +0000 (UTC) Date: Mon, 6 Jan 2025 18:50:21 +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: Even though roff(7) numerical expressions use integer arithmetic X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Message-ID: <9500a3aca8c768a9@mandoc.bsd.lv> 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 @@ NNAAMMEE DDEESSCCRRIIPPTTIIOONN 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