From 08b13bc1cb693451c1e9f50f770acaddf42ed9da Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Wed, 19 Oct 2016 15:43:12 +0100 Subject: [PATCH] Alter ctype-checked to handle EOF and be hand-written. 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 | 1 - Makefile.am | 18 +----- etc/gen-ctype-checked.c | 132 ---------------------------------------- sbr/ctype-checked.c | 50 +++++++++++++++ sbr/ctype-checked.h | 95 +++++++++++++++++++++++++++++ 5 files changed, 147 insertions(+), 149 deletions(-) delete mode 100644 etc/gen-ctype-checked.c create mode 100644 sbr/ctype-checked.c create mode 100644 sbr/ctype-checked.h diff --git a/.gitignore b/.gitignore index c5410fb2..3515afe9 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/Makefile.am b/Makefile.am index 7cc5387b..92d9dde3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 index befd64a7..00000000 --- a/etc/gen-ctype-checked.c +++ /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 . 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 -#include - -#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 \n\ -\n", header); - - fprintf (cfile, copyright, cfilename); - fputs ("#include \n\n", cfile); - fputs ("#ifndef NDEBUG\n", cfile); - fputs ("#include \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 index 00000000..1cfdfae2 --- /dev/null +++ b/sbr/ctype-checked.c @@ -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 + +#ifndef NDEBUG + +#include +#if EOF != -1 +#error "Please report this to nmh's authors." +#endif + +#include + +/* 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 index 00000000..12dbc6fd --- /dev/null +++ b/sbr/ctype-checked.h @@ -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 + +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 -- 2.56.0