chiark / gitweb /
16-bit safety, maybe
authorBen Harris <bjh21@bjh21.me.uk>
Wed, 10 Jul 2024 13:38:53 +0000 (14:38 +0100)
committerBen Harris <bjh21@bjh21.me.uk>
Wed, 10 Jul 2024 13:57:49 +0000 (14:57 +0100)
Bedstead claims to be written in ISO C.  ISO C allows "int" to be only
16 bits wide, which is a bit of a problem.  In fact, it's not much of
a problem because Bedstead mostly deals in small numbers.  The main
exception is Unicode code points, which can exceed 16 bits.

To hopefully fix this, Bedstead now mostly uses "long" for Unicode
code points.  The main exception is in the gklph table where that
seems a bit profligate on 64-bit systems so I've used int_least32_t
instead.

The fiddliest bits of this are around uses of printf(), which cares
whether it's being passed an "int" or a "long".

This is untested on an actual 16-bit system, but at least on a 64-bit
system it continues to produce correct results.

bedstead.c

index 636ca79dcbf104645c0a0b4fe9073461ab70b9e4..350fcfe503b173d075b20808347fe13966b4b157 100644 (file)
@@ -99,6 +99,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <stdbool.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -241,9 +242,9 @@ static void glyph_complement(void);
 
 static struct glyph {
        char data[YSIZE];
-       int unicode;
+       int_least32_t unicode;
        char const *name;
-       unsigned int flags;
+       uint_least8_t flags;
 #define SEP  0x01 /* Separated graphics */
 #define MOS6 0x02 /* 6-cell mosaic graphics character */
 #define MOS4 0x04 /* 4-cell mosaic graphics character */
@@ -2856,7 +2857,7 @@ main(int argc, char **argv)
        printf("OtfFeatName: 'ss16' 1033 \"6-cell separated graphics\"\n");
        printf("Lookup: 257 0 0 \"palt: proportional metrics\" {\"palt\"} "
            "['palt' ('DFLT' <'dflt'> 'latn' <'dflt'>)]\n");
-       printf("BeginChars: %d %d\n", 0x110000 + extraglyphs, nglyphs);
+       printf("BeginChars: %ld %d\n", 0x110000L + extraglyphs, nglyphs);
        extraglyphs = 0;
        for (i = 0; i < nglyphs; i++)
                glyphs_by_name[i] = glyphs + i;
@@ -2864,9 +2865,10 @@ main(int argc, char **argv)
              &compare_glyphs_by_name);
        for (i = 0; i < nglyphs; i++) {
                printf("\nStartChar: %s\n", glyphs[i].name);
-               printf("Encoding: %d %d %d\n",
-                   glyphs[i].unicode != -1 ? glyphs[i].unicode :
-                   0x110000 + extraglyphs++, glyphs[i].unicode, i);
+               printf("Encoding: %ld %ld %d\n",
+                      (long)(glyphs[i].unicode != -1 ? glyphs[i].unicode :
+                             0x110000 + extraglyphs++),
+                      (long)glyphs[i].unicode, i);
                printf("Width: %g\n", (double)(XSIZE * XPIX));
                if (glyphs[i].flags & (MOS6|MOS4))
                        printf("Flags: W\n");
@@ -3668,7 +3670,8 @@ static void
 glyph_complement()
 {
        int const nrow = 16, ncol=12;
-       int i, unicol = 32/nrow, col = -1, row = 0;
+       long unicol = 32/nrow;
+       int i, col = -1, row = 0;
        int const nglyphs = sizeof(glyphs) / sizeof(glyphs[0]);
        int npages = 0;
        bool newcol = false;
@@ -3731,15 +3734,16 @@ glyph_complement()
                        newcol = true;
                }
                if (newcol && g->unicode != -1) {
-                       printf("gsave %d 0 translate (%03X) colnum grestore\n",
+                       printf("gsave %d 0 translate (%03lX) colnum grestore\n",
                               col * 40, unicol);
                        newcol = false;
                }
                printf("gsave %d %d translate ",
                       (col * 40),
-                      -((g->unicode == -1 ? row++ : g->unicode%nrow) * 40));
+                      (int)-((g->unicode == -1 ?
+                              row++ : g->unicode % nrow) * 40));
                if (g->unicode != -1)
-                       printf("(U+%04X)", g->unicode);
+                       printf("(U+%04lX)", (long)g->unicode);
                else
                        printf("()");
                printf("/%s ", g->name);