]> diplodocus.org Git - nmh/commitdiff
Alter ctype-checked to handle EOF and be hand-written.
authorRalph Corderoy <ralph@inputplus.co.uk>
Wed, 19 Oct 2016 14:43:12 +0000 (15:43 +0100)
committerRalph Corderoy <ralph@inputplus.co.uk>
Wed, 19 Oct 2016 14:43:12 +0000 (15:43 +0100)
Along the way, replace the code generation with code that punts the work
onto the stdlib's C functions, needing only a single `identity' array
for all the macros.  A mkdir needed to be added in Makefile.am because
otherwise etc didn't exist in a distcheck and attempting to redirect
stdout to a file in etc failed.  I'm not happy that's the best automake
way to achieve this, i.e. what if another rule attempts to create in etc
first?

.gitignore
Makefile.am
etc/gen-ctype-checked.c [deleted file]
sbr/ctype-checked.c [new file with mode: 0644]
sbr/ctype-checked.h [new file with mode: 0644]

index c5410fb..3515afe 100644 (file)
@@ -60,7 +60,6 @@ a.out.dSYM/
 /man/mh-chart.man
 /mts/libmts.a
 /sbr/*.a
-/sbr/ctype-checked.*
 /sbr/addrparse.tab.c
 /sbr/addrparse.tab.h
 /sbr/addrparse.output
index 7cc5387..92d9dde 100644 (file)
@@ -134,7 +134,7 @@ AM_DISTCHECK_CONFIGURE_FLAGS = DISABLE_SETGID_MAIL=1 \
 ## automake 1.12.6 on FreeBSD 9 needs the sbr/dtimep.c.
 ##
 CLEANFILES = config/version.c sbr/sigmsg.h sbr/dtimep.c etc/mts.conf \
-            etc/gen-ctype-checked sbr/ctype-checked.[hc] \
+            sbr/ctype-checked.[hc] \
             etc/mhn.defaults man/man.sed man/mh-chart.man $(man_MANS) \
             *.plist
 clean-local:
@@ -186,13 +186,6 @@ nmhlibexec_PROGRAMS = uip/ap uip/dp uip/fmtdump uip/mhl uip/mkstemp \
 
 nmhlibexec_SCRIPTS = uip/spost
 
-##
-## Programs that MAY need to get built at some point; we need to list them
-## here if they don't appear in any other primary so Automake knows about
-## them and can properly record dependency information.
-##
-EXTRA_PROGRAMS = etc/gen-ctype-checked
-
 ##
 ## Internal libraries that we create as part of the build process
 ## but do not install
@@ -517,9 +510,6 @@ test_fakehttp_LDADD = $(LDADD) $(POSTLINK)
 test_getcwidth_SOURCES = test/getcwidth.c
 test_getcwidth_LDADD = $(POSTLINK)
 
-etc_gen_ctype_checked_SOURCES = etc/gen-ctype-checked.c
-etc_gen_ctype_checked_LDADD = $(POSTLINK)
-
 ##
 ## Our rebuild rules for files that aren't built via the normal mechanisms
 ##
@@ -530,11 +520,6 @@ etc_gen_ctype_checked_LDADD = $(POSTLINK)
 config/version.c: Makefile $(srcdir)/config/version.sh
        env srcdir="$(srcdir)" sh $(srcdir)/config/version.sh $(VERSION) > ./config/version.c
 
-sbr/ctype-checked.h: etc/gen-ctype-checked
-       etc/gen-ctype-checked
-
-sbr/ctype-checked.c: etc/gen-ctype-checked sbr/ctype-checked.h
-
 etc/mts.conf: $(srcdir)/etc/mts.conf.in Makefile
        @rm -f $@
        $(SED) -e 's,%mts%,$(MTS),' \
@@ -545,6 +530,7 @@ etc/mts.conf: $(srcdir)/etc/mts.conf.in Makefile
                                < $(srcdir)/etc/mts.conf.in > $@
 
 etc/mhn.defaults: $(srcdir)/etc/mhn.defaults.sh $(MHNSEARCHPROG)
+       $(MKDIR_P) $(@D) # FIXME: A better way?
        @rm -f $@
        $(srcdir)/etc/mhn.defaults.sh $(MHNSEARCHPATH) $(MHNSEARCHPROG) > $@
 
diff --git a/etc/gen-ctype-checked.c b/etc/gen-ctype-checked.c
deleted file mode 100644 (file)
index befd64a..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * gen-ctype-checked.c:  generates ctype-checked.h on stdout
- *
- * This code is Copyright (c) 2013, by the authors of nmh.
- * See the COPYRIGHT file in the root directory of the nmh
- * distribution for complete copyright information.
- */
-
-/*
- * This is intended to catch any calls using a char argument to any of
- * the is*(int) functions in <ctype.h>.  It does that by defining a
- * macro that uses the argument as an array index, along with a
- * compiler warning such as gcc -Wchar-subscripts (include with
- * -Wall).  This program creates sbr/ctype-checked.h and
- * sbr/ctype-checked.c.  The header file is put into sbr/ because h/
- * is unwritable during make distcheck.
- */
-
-#include <ctype.h>
-#include <stdio.h>
-
-#define CTYPE_FUNCTIONS \
-    X(isalnum) \
-    X(isalpha) \
-    X(iscntrl) \
-    X(isdigit) \
-    X(isgraph) \
-    X(islower) \
-    X(isprint) \
-    X(ispunct) \
-    X(isspace) \
-    X(isupper) \
-    X(isxdigit) \
-    X(tolower) \
-    X(toupper) \
-
-#if (defined (_BSD_SOURCE) && _BSD_SOURCE) || \
-    (defined (_SVID_SOURCE) && _SVID_SOURCE) || \
-    (defined (_XOPEN_SOURCE) && _XOPEN_SOURCE)
-# define CTYPE_FUNCTION_ISASCII X(isascii) \
-                                X(toascii)
-#else
-# define CTYPE_FUNCTION_ISASCII
-#endif
-
-#if (defined (_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600) || \
-    (defined (_ISOC99_SOURCE) && _ISOC99_SOURCE) || \
-    (defined (_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
-# define CTYPE_FUNCTIONS_C99 X(isblank)
-#else
-# define CTYPE_FUNCTIONS_C99
-#endif
-
-struct ctype_func { const char *name; int (*function) (int); };
-
-#define X(function) { #function, function },
-struct ctype_func functions[] =
-    { CTYPE_FUNCTIONS CTYPE_FUNCTION_ISASCII CTYPE_FUNCTIONS_C99 { NULL, 0} };
-#undef X
-
-
-int
-main () {
-    const char *copyright="\
-/*\n\
- * %s:  checks type of arguments and argument\n\
- *     values for each of the ctype functions\n\
- *\n\
- * Generated by etc/gen-ctype-checked.\n\
- *\n\
- * This code is Copyright (c) 2013, by the authors of nmh.\n\
- * See the COPYRIGHT file in the root directory of the nmh\n\
- * distribution for complete copyright information.\n\
- */\n\n";
-    char headername[] = "sbr/ctype-checked.h";
-    const char cfilename[] =  "sbr/ctype-checked.c";
-    FILE *header = fopen (headername, "w");
-    FILE *cfile = fopen (cfilename, "w");
-    int status = 0;
-
-    if (header != 0  &&  cfile != 0) {
-        struct ctype_func *f;
-
-        fprintf (header, copyright, headername);
-        fputs ("#ifndef CTYPE_CHECKED_H\n\
-#define CTYPE_CHECKED_H\n\
-#include <ctype.h>\n\
-\n", header);
-
-        fprintf (cfile, copyright, cfilename);
-        fputs ("#include <config.h>\n\n", cfile);
-        fputs ("#ifndef NDEBUG\n", cfile);
-        fputs ("#include <sbr/ctype-checked.h>\n\n", cfile);
-
-        for (f = functions; f->function; ++f) {
-            const char *cp = f->name;
-            unsigned int i;
-
-            fprintf (header, "extern int %s_type_checked[];\n", cp);
-            fprintf (header, "#ifdef %s\n#undef %s\n#endif\n", cp, cp);
-            fprintf (header, "#define %s(c) %s_type_checked[(c)]\n\n", cp, cp);
-
-            fprintf (cfile, "int %s_type_checked[] = {\n    ", cp);
-            for (i = 0; i < 256; ++i) {
-                fprintf (cfile, "%d", (*f->function) (i));
-                if ((i+1) % 8) {
-                    fputs (", ", cfile);
-                } else {
-                    if (i == 255) {
-                        fputs (" };\n\n", cfile);
-                    } else {
-                        fputs (",\n    ", cfile);
-                    }
-                }
-            }
-        }
-
-        /* Need to put a symbol in the .c file with NDEBUG so the
-           compilation unit isn't empty. */
-        fputs ("#else  /* NDEBUG */\n\nvoid ctype_checked();\n\n", cfile);
-        fputs ("#endif /* NDEBUG */\n", cfile);
-        fprintf (header, "#endif /* CTYPE_CHECKED_H */\n");
-    } else {
-        perror ("fopen in sbr/");
-        status = -1;
-    }
-
-    if (header) { fclose(header); }
-    if (cfile) { fclose(cfile); }
-
-    return status;
-}
diff --git a/sbr/ctype-checked.c b/sbr/ctype-checked.c
new file mode 100644 (file)
index 0000000..1cfdfae
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * sbr/ctype-checked.c:  checks char isn't used as the value for each of
+ *     the ctype functions
+ *
+ * This code is Copyright (c) 2016, by the authors of nmh.
+ * See the COPYRIGHT file in the root directory of the nmh
+ * distribution for complete copyright information.
+ */
+
+#include <config.h>
+
+#ifndef NDEBUG
+
+#include <stdio.h>
+#if EOF != -1
+#error "Please report this to nmh's authors."
+#endif
+
+#include <sbr/ctype-checked.h>
+
+/* ctype_identity returns its index less one allowing [EOF, 255] to be
+ * used as indexes to ctype_identity + 1. */
+int ctype_identity[257] = {
+    -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+    18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+    35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+    69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+    86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+    102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+    115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+    128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
+    141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
+    154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
+    167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
+    180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192,
+    193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
+    206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218,
+    219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231,
+    232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,
+    245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
+};
+
+#else
+
+/* Need to put a symbol in the .c file with NDEBUG so the compilation
+ * unit isn't empty. */
+void ctype_checked();
+
+#endif
diff --git a/sbr/ctype-checked.h b/sbr/ctype-checked.h
new file mode 100644 (file)
index 0000000..12dbc6f
--- /dev/null
@@ -0,0 +1,95 @@
+/* sbr/ctype-checked.h
+ *
+ * This code is Copyright (c) 2016, by the authors of nmh.
+ * See the COPYRIGHT file in the root directory of the nmh
+ * distribution for complete copyright information. */
+
+#ifndef CTYPE_CHECKED_H
+#define CTYPE_CHECKED_H
+#include <ctype.h>
+
+extern int ctype_identity[257];
+
+#define CTYPE_CHECK(f, c) ((f)((ctype_identity + 1)[c]))
+
+#ifdef isalnum
+#undef isalnum
+#endif
+#define isalnum(c) CTYPE_CHECK(isalnum, c)
+
+#ifdef isalpha
+#undef isalpha
+#endif
+#define isalpha(c) CTYPE_CHECK(isalpha, c)
+
+#ifdef iscntrl
+#undef iscntrl
+#endif
+#define iscntrl(c) CTYPE_CHECK(iscntrl, c)
+
+#ifdef isdigit
+#undef isdigit
+#endif
+#define isdigit(c) CTYPE_CHECK(isdigit, c)
+
+#ifdef isgraph
+#undef isgraph
+#endif
+#define isgraph(c) CTYPE_CHECK(isgraph, c)
+
+#ifdef islower
+#undef islower
+#endif
+#define islower(c) CTYPE_CHECK(islower, c)
+
+#ifdef isprint
+#undef isprint
+#endif
+#define isprint(c) CTYPE_CHECK(isprint, c)
+
+#ifdef ispunct
+#undef ispunct
+#endif
+#define ispunct(c) CTYPE_CHECK(ispunct, c)
+
+#ifdef isspace
+#undef isspace
+#endif
+#define isspace(c) CTYPE_CHECK(isspace, c)
+
+#ifdef isupper
+#undef isupper
+#endif
+#define isupper(c) CTYPE_CHECK(isupper, c)
+
+#ifdef isxdigit
+#undef isxdigit
+#endif
+#define isxdigit(c) CTYPE_CHECK(isxdigit, c)
+
+#ifdef tolower
+#undef tolower
+#endif
+#define tolower(c) CTYPE_CHECK(tolower, c)
+
+#ifdef toupper
+#undef toupper
+#endif
+#define toupper(c) CTYPE_CHECK(toupper, c)
+
+#ifdef isascii
+#undef isascii
+#endif
+#define isascii(c) CTYPE_CHECK(isascii, c)
+
+#ifdef toascii
+#undef toascii
+#endif
+#define toascii(c) CTYPE_CHECK(toascii, c)
+
+#ifdef isblank
+#undef isblank
+#endif
+#define isblank(c) CTYPE_CHECK(isblank, c)
+
+#endif