chiark / gitweb /
utils/macros.h: Add <ctype.h> and `foocmp' helper macros.
authorMark Wooding <mdw@distorted.org.uk>
Tue, 1 Oct 2019 17:41:17 +0000 (18:41 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 8 May 2020 12:44:29 +0000 (13:44 +0100)
Both of these have been a nuisance for years.  Do something about it.

The command

git grep -En '\<(is|to)[a-z]+\(|\<(str|mem)[a-z]*cmp\(' -- '*.[ch]'

finds code which it might be good to change.

The hairy Emacs command

(query-replace-regexp
 "\\<\\(\\(str\\|mem\\)\\sw*cmp\\)(\\([^,]*\\), \\([^)]*\\)) \\(==\\|!=\\|<\\|<=\\|>\\|>=\\) 0"
 '(replace-eval-replacement
   . (concat (replace-quote (upcase (match-string 1)))
     "(\\3, \\5, \\4)"))
 nil
 (if (and transient-mark-mode mark-active) (region-beginning))
 (if (and transient-mark-mode mark-active) (region-end))
 nil)

will convert easy cases of `foocmp' calls, but hard ones have to be done
by hand.

22 files changed:
codec/baseconv.c
codec/bincode.c
codec/url.c
hash/crc-mktab.c
hash/unihash-mkstatic.c
sel/bres-adns.c
sel/ident.c
struct/dstr-putf.c
struct/sym.c
struct/t/assoc-test.c
struct/t/da-test.c
struct/t/dstr-putf-test.c
struct/t/sym-test.c
sys/t/fdpass-test.c
sys/t/mdup-test.c
test/testrig.c
trace/trace.c
trace/traceopt.c
utils/macros.3
utils/macros.h
utils/str.c
utils/versioncmp.c

index bdb850f7d19ca53b2cbf4c9092e8fd7b6758852e..b7cb0a0618ebe0a893c2721c336429a9eb8cdb88 100644 (file)
@@ -35,6 +35,7 @@
 #include "alloc.h"
 #include "codec.h"
 #include "dstr.h"
 #include "alloc.h"
 #include "codec.h"
 #include "dstr.h"
+#include "macros.h"
 #include "sub.h"
 
 #include "base64.h"
 #include "sub.h"
 
 #include "base64.h"
@@ -279,7 +280,7 @@ enum {
 
 #define PUTWRAP(x) WRAP({                                              \
   char ch = encodemap[x];                                              \
 
 #define PUTWRAP(x) WRAP({                                              \
   char ch = encodemap[x];                                              \
-  if (f & CDCF_LOWERC) ch = tolower((unsigned char)ch);                        \
+  if (f & CDCF_LOWERC) ch = TOLOWER(ch);                               \
   DPUTC(d, ch);                                                                \
 })
 
   DPUTC(d, ch);                                                                \
 })
 
@@ -350,9 +351,9 @@ static int ctxn##_dodecode(ctxn##_ctx *ctx,                         \
        case 0:                                                         \
          break;                                                        \
        case CDCF_LOWERC:                                               \
        case 0:                                                         \
          break;                                                        \
        case CDCF_LOWERC:                                               \
-         if (isupper(ch)) goto badch;                                  \
+         if (ISUPPER(ch)) goto badch;                                  \
        default:                                                        \
        default:                                                        \
-         ch = toupper(ch);                                             \
+         ch = TOUPPER(ch);                                             \
       }                                                                        \
       x = decodemap[ch];                                               \
       switch (x) {                                                     \
       }                                                                        \
       x = decodemap[ch];                                               \
       switch (x) {                                                     \
index af1e677242fc955c452486993dc88370d3df4247..77d24570e51db875e95052b17a8fd2c2884ed324 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "codec.h"
 #include "dstr.h"
 
 #include "codec.h"
 #include "dstr.h"
+#include "macros.h"
 #include "mdwopt.h"
 #include "quis.h"
 #include "report.h"
 #include "mdwopt.h"
 #include "quis.h"
 #include "report.h"
@@ -195,7 +196,7 @@ int main(int argc, char *argv[])
          n = strcspn(p, ",");
          for (i = 0; flagtab[i].name; i++) {
            if (strlen(flagtab[i].name) == n &&
          n = strcspn(p, ",");
          for (i = 0; flagtab[i].name; i++) {
            if (strlen(flagtab[i].name) == n &&
-               strncmp(flagtab[i].name, p, n) == 0)
+               STRNCMP(flagtab[i].name, ==, p, n))
              goto found;
          }
          die(EXIT_FAILURE, "unknown flag `%.*s'", (int)n, p);
              goto found;
          }
          die(EXIT_FAILURE, "unknown flag `%.*s'", (int)n, p);
@@ -215,7 +216,7 @@ int main(int argc, char *argv[])
 
   for (cc = cctab;; cc++) {
     if (!*cc) die(EXIT_FAILURE, "unknown codec `%s'", *argv);
 
   for (cc = cctab;; cc++) {
     if (!*cc) die(EXIT_FAILURE, "unknown codec `%s'", *argv);
-    else if (strcmp(*argv, (*cc)->name) == 0) break;
+    else if (STRCMP(*argv, ==, (*cc)->name)) break;
   }
   argv++; argc--;
 
   }
   argv++; argc--;
 
@@ -267,7 +268,7 @@ int main(int argc, char *argv[])
   if (!argc)
     code(c, "<stdin>", stdin, ofp);
   else for (i = 0; i < argc; i++) {
   if (!argc)
     code(c, "<stdin>", stdin, ofp);
   else for (i = 0; i < argc; i++) {
-    if (strcmp(argv[i], "-") == 0)
+    if (STRCMP(argv[i], ==, "-"))
       code(c, "<stdin>", stdin, ofp);
     else if ((ifp = fopen(argv[i], imode)) == 0) {
       die(EXIT_FAILURE, "couldn't open `%s' for reading: %s",
       code(c, "<stdin>", stdin, ofp);
     else if ((ifp = fopen(argv[i], imode)) == 0) {
       die(EXIT_FAILURE, "couldn't open `%s' for reading: %s",
index 0de87ae1fff337ab5244ed8a348908d694de71f7..eecfe820dd0180ac8cb31b68e19ad7a3d1b2b095 100644 (file)
@@ -33,6 +33,7 @@
 #include <string.h>
 
 #include "dstr.h"
 #include <string.h>
 
 #include "dstr.h"
+#include "macros.h"
 #include "url.h"
 
 /*----- Main code ---------------------------------------------------------*/
 #include "url.h"
 
 /*----- Main code ---------------------------------------------------------*/
@@ -66,8 +67,8 @@ static void encode(url_ectx *ctx, dstr *d, const char *p)
       case ' ': DPUTC(d, '+');
        break;
       default:
       case ' ': DPUTC(d, '+');
        break;
       default:
-       if (isspace((unsigned char)*p)) goto unsafe;
-       else if (isalnum((unsigned char)*p)) goto safe;
+       if (ISSPACE(*p)) goto unsafe;
+       else if (ISALNUM(*p)) goto safe;
        else if (ctx->f&URLF_LAX) goto safe;
        else goto unsafe;
       case '/': case '~':
        else if (ctx->f&URLF_LAX) goto safe;
        else goto unsafe;
       case '/': case '~':
index 4453cf36d87c42468ccb0256fd9003383daac26a..a176d161192493597633ff18f9ddebe2f1a6efd8 100644 (file)
@@ -37,6 +37,7 @@
 #include <stdlib.h>
 #include <string.h>
 
 #include <stdlib.h>
 #include <string.h>
 
+#include "macros.h"
 #include "mdwopt.h"
 #include "quis.h"
 #include "report.h"
 #include "mdwopt.h"
 #include "quis.h"
 #include "report.h"
@@ -266,8 +267,8 @@ int main(int argc, char *argv[])
        die(EXIT_FAILURE, "not enough memory");
       guard = p;
       for (q = file; *q; p++, q++) {
        die(EXIT_FAILURE, "not enough memory");
       guard = p;
       for (q = file; *q; p++, q++) {
-       if (isalnum((unsigned char)*q))
-         *p = toupper((unsigned char)*q);
+       if (ISALNUM(*q))
+         *p = TOUPPER(*q);
        else
          *p = '_';
       }
        else
          *p = '_';
       }
index 0505fcff3e45fdf28ca162ce526f65846ff27a96..958b3d7fe28e9b04e3b6e035652141e90e9f3f90 100644 (file)
@@ -187,8 +187,8 @@ int main(int argc, char *argv[])
        die(EXIT_FAILURE, "not enough memory");
       guard = p;
       for (q = file; *q; p++, q++) {
        die(EXIT_FAILURE, "not enough memory");
       guard = p;
       for (q = file; *q; p++, q++) {
-       if (isalnum((unsigned char)*q))
-         *p = toupper((unsigned char)*q);
+       if (ISALNUM(*q))
+         *p = TOUPPER(*q);
        else
          *p = '_';
       }
        else
          *p = '_';
       }
index 03fafa4f12a9935a717b9940431101e280227633..491a9a8659aeb926bafb05b84ab6525638567ff0 100644 (file)
@@ -215,7 +215,7 @@ static void report(bres_client *rc, adns_answer *a,
   if (a->cname) n[j++] = a->cname;
   else { n[j++] = *nv; nv++; nn--; }
   for (i = 0; i < nn && j < N(n) - 1; i++)
   if (a->cname) n[j++] = a->cname;
   else { n[j++] = *nv; nv++; nn--; }
   for (i = 0; i < nn && j < N(n) - 1; i++)
-    if (strcmp(n[0], nv[i]) != 0) n[j++] = nv[i];
+    if (STRCMP(n[0], !=, nv[i])) n[j++] = nv[i];
   n[j++] = 0;
   for (i = j = 0; i < an && j < N(aa) - 1; i++) {
     if (av[i].addr.sa.sa_family == AF_INET)
   n[j++] = 0;
   for (i = j = 0; i < an && j < N(aa) - 1; i++) {
     if (av[i].addr.sa.sa_family == AF_INET)
index 0017f0a3877faef70c4d36d975245caa47b22f07..a59cd229fa7148375e3d0029c289e8089317c56d 100644 (file)
@@ -44,6 +44,7 @@
 #include "dstr.h"
 #include "exc.h"
 #include "ident.h"
 #include "dstr.h"
 #include "exc.h"
 #include "ident.h"
+#include "macros.h"
 #include "selbuf.h"
 
 /*----- Main code ---------------------------------------------------------*/
 #include "selbuf.h"
 
 /*----- Main code ---------------------------------------------------------*/
@@ -77,13 +78,13 @@ static char *next(char **pp)
 
   /* --- Skip past any leading whitespace --- */
 
 
   /* --- Skip past any leading whitespace --- */
 
-  while (isspace((unsigned char)*p))
+  while (ISSPACE(*p))
     p++;
 
   /* --- Now start work on the string itself --- */
 
   for (;;) {
     p++;
 
   /* --- Now start work on the string itself --- */
 
   for (;;) {
-    if (*p == 0 || *p == ':' || *p == ',' || isspace((unsigned char)*p))
+    if (*p == 0 || *p == ':' || *p == ',' || ISSPACE(*p))
       break;
     else if (*p == '\\') {
       p++;
       break;
     else if (*p == '\\') {
       p++;
@@ -97,7 +98,7 @@ static char *next(char **pp)
 
   /* --- Tidy up afterwards --- */
 
 
   /* --- Tidy up afterwards --- */
 
-  while (isspace((unsigned char)*p))
+  while (ISSPACE(*p))
     p++;
   if (*p == 0)
     *pp = 0;
     p++;
   if (*p == 0)
     *pp = 0;
@@ -132,11 +133,11 @@ static void parse(char *p, ident_reply *i)
   /* --- Find out what sort of a reply this is --- */
 
   q = next(&p);
   /* --- Find out what sort of a reply this is --- */
 
   q = next(&p);
-  if (strcmp(q, "USERID") == 0) {
+  if (STRCMP(q, ==, "USERID")) {
     i->type = IDENT_USERID;
     i->u.userid.os = next(&p);
     i->u.userid.user = next(&p);
     i->type = IDENT_USERID;
     i->u.userid.os = next(&p);
     i->u.userid.user = next(&p);
-  } else if (strcmp(q, "ERROR") == 0) {
+  } else if (STRCMP(q, ==, "ERROR")) {
     i->type = IDENT_ERROR;
     i->u.error = next(&p);
   } else
     i->type = IDENT_ERROR;
     i->u.error = next(&p);
   } else
index e097968a875d7e9ceaa2ed8268b8e03f3a91c8e1..270f9a3f84bdd96e4cdf83c772c6da86daaf6ee7 100644 (file)
@@ -47,6 +47,7 @@
 
 #include "darray.h"
 #include "dstr.h"
 
 #include "darray.h"
 #include "dstr.h"
+#include "macros.h"
 
 /*----- Tunable constants -------------------------------------------------*/
 
 
 /*----- Tunable constants -------------------------------------------------*/
 
@@ -247,7 +248,7 @@ int dstr_vputf(dstr *d, const char *p, va_list *ap)
 
   done_flags:
     i = 0;
 
   done_flags:
     i = 0;
-    while (isdigit((unsigned char)*p)) i = 10*i + *p++ - '0';
+    while (ISDIGIT(*p)) i = 10*i + *p++ - '0';
 
     /* --- Snag: this might have been an argument position indicator --- */
 
 
     /* --- Snag: this might have been an argument position indicator --- */
 
@@ -269,11 +270,11 @@ int dstr_vputf(dstr *d, const char *p, va_list *ap)
       fs->wd = i;
     } else if (*p == '*') {
       p++;
       fs->wd = i;
     } else if (*p == '*') {
       p++;
-      if (!isdigit((unsigned char)*p))
+      if (!ISDIGIT(*p))
        i = anext++;
       else {
        i = *p++ - '0';
        i = anext++;
       else {
        i = *p++ - '0';
-       while (isdigit((unsigned char)*p)) i = 10*i + *p++ - '0';
+       while (ISDIGIT(*p)) i = 10*i + *p++ - '0';
        assert(*p == '$'); p++;
        assert(i > 0); i--;
       }
        assert(*p == '$'); p++;
        assert(i > 0); i--;
       }
@@ -286,19 +287,19 @@ int dstr_vputf(dstr *d, const char *p, va_list *ap)
     if (*p == '.') {
       p++;
       f |= f_prec;
     if (*p == '.') {
       p++;
       f |= f_prec;
-      if (isdigit((unsigned char)*p)) {
+      if (ISDIGIT(*p)) {
        i = *p++ - '0';
        i = *p++ - '0';
-       while (isdigit((unsigned char)*p)) i = 10*i + *p++ - '0';
+       while (ISDIGIT(*p)) i = 10*i + *p++ - '0';
        fs->prec = i;
       } else if (*p != '*')
        fs->prec = 0;
       else {
        p++;
        fs->prec = i;
       } else if (*p != '*')
        fs->prec = 0;
       else {
        p++;
-       if (!isdigit((unsigned char)*p))
+       if (!ISDIGIT(*p))
          i = anext++;
        else {
          i = *p++ - '0';
          i = anext++;
        else {
          i = *p++ - '0';
-         while (isdigit((unsigned char)*p)) i = 10*i + *p++ - '0';
+         while (ISDIGIT(*p)) i = 10*i + *p++ - '0';
          assert(*p == '$'); p++;
          assert(i > 0); i--;
        }
          assert(*p == '$'); p++;
          assert(i > 0); i--;
        }
index 4543811676af87d303f88dbe0f3fd0e0a1fedf6c..2eb309c175ec20de8f87343ee0361bf13c236283 100644 (file)
@@ -40,6 +40,7 @@
 #include "bits.h"
 #include "exc.h"
 #include "hash.h"
 #include "bits.h"
 #include "exc.h"
 #include "hash.h"
+#include "macros.h"
 #include "sub.h"
 #include "sym.h"
 #include "unihash.h"
 #include "sub.h"
 #include "sym.h"
 #include "unihash.h"
@@ -136,7 +137,8 @@ void *sym_find(sym_table *t, const char *n, long l, size_t sz, unsigned *f)
 
   for (p = bin; *p; p = &(*p)->next) {
     q = (sym_base *)*p;
 
   for (p = bin; *p; p = &(*p)->next) {
     q = (sym_base *)*p;
-    if (hash == q->b.hash && len == q->len && !memcmp(n, SYM_NAME(q), len)) {
+    if (hash == q->b.hash && len == q->len &&
+       MEMCMP(n, ==, SYM_NAME(q), len)) {
 
       /* --- Found a match --- *
        *
 
       /* --- Found a match --- *
        *
index bd1bab4e45564595d31a445c99bc15f8b985ff92..a727bbf38de65e0eea5b342382d73c8ad4a04712 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "assoc.h"
 #include "atom.h"
 
 #include "assoc.h"
 #include "atom.h"
+#include "macros.h"
 
 typedef struct word {
   assoc_base _b;
 
 typedef struct word {
   assoc_base _b;
@@ -34,7 +35,7 @@ int main(void)
     buf[strlen(buf) - 1] = 0;
     p = strtok(buf, " ");
 
     buf[strlen(buf) - 1] = 0;
     p = strtok(buf, " ");
 
-    if (strcmp(p, "set") == 0) {
+    if (STRCMP(p, ==, "set")) {
       char *k = strtok(0, " ");
       int i = atoi(strtok(0, " "));
       unsigned f;
       char *k = strtok(0, " ");
       int i = atoi(strtok(0, " "));
       unsigned f;
@@ -42,14 +43,14 @@ int main(void)
       w->i = i;
       if (!f)
        n++;
       w->i = i;
       if (!f)
        n++;
-    } else if (strcmp(p, "get") == 0) {
+    } else if (STRCMP(p, ==, "get")) {
       char *k = strtok(0, " ");
       word *w = assoc_find(&t, atom_intern(&at, k), 0, 0);
       if (w)
        printf("%i\n", w->i);
       else
        puts("*MISSING*");
       char *k = strtok(0, " ");
       word *w = assoc_find(&t, atom_intern(&at, k), 0, 0);
       if (w)
        printf("%i\n", w->i);
       else
        puts("*MISSING*");
-    } else if (strcmp(p, "del") == 0) {
+    } else if (STRCMP(p, ==, "del")) {
       char *k = strtok(0, " ");
       word *w = assoc_find(&t, atom_intern(&at, k), 0, 0);
       if (w) {
       char *k = strtok(0, " ");
       word *w = assoc_find(&t, atom_intern(&at, k), 0, 0);
       if (w) {
@@ -57,9 +58,9 @@ int main(void)
        n--;
       } else
        puts("*MISSING*");
        n--;
       } else
        puts("*MISSING*");
-    } else if (strcmp(p, "count") == 0) {
+    } else if (STRCMP(p, ==, "count")) {
       printf("%lu\n", (unsigned long)n);
       printf("%lu\n", (unsigned long)n);
-    } else if (strcmp(p, "show") == 0) {
+    } else if (STRCMP(p, ==, "show")) {
       assoc_iter i;
       word *w;
       word **v, **vv;
       assoc_iter i;
       word *w;
       word **v, **vv;
index 0f3e6253c071d823397de7516da3265916eef334..ba86a8d936f495a4433c847581d60aad1c41e528 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "darray.h"
 #include "exc.h"
 
 #include "darray.h"
 #include "exc.h"
+#include "macros.h"
 
 DA_DECL(vec, int);
 
 
 DA_DECL(vec, int);
 
@@ -49,18 +50,18 @@ int main(void)
     p = strtok(buf, " ");
 
     TRY {
     p = strtok(buf, " ");
 
     TRY {
-      if (strcmp(p, "push") == 0) {
+      if (STRCMP(p, ==, "push")) {
        int n = atoi(strtok(0, " "));
        DA_PUSH(&v, n);
        int n = atoi(strtok(0, " "));
        DA_PUSH(&v, n);
-      } else if (strcmp(p, "unshift") == 0) {
+      } else if (STRCMP(p, ==, "unshift")) {
        int n = atoi(strtok(0, " "));
        DA_UNSHIFT(&v, n);
        int n = atoi(strtok(0, " "));
        DA_UNSHIFT(&v, n);
-      } else if (strcmp(p, "pop") == 0) {
+      } else if (STRCMP(p, ==, "pop")) {
        printf("%i\n", DA_POP(&v));
        printf("%i\n", DA_POP(&v));
-      } else if (strcmp(p, "shift") == 0) {
+      } else if (STRCMP(p, ==, "shift")) {
        printf("%i\n", DA_SHIFT(&v));
        printf("%i\n", DA_SHIFT(&v));
-      } else if (strcmp(p, "insert") == 0 ||
-                strcmp(p, "append") == 0) {
+      } else if (STRCMP(p, ==, "insert") ||
+                STRCMP(p, ==, "append")) {
        vec vv;
        char *q = p;
        DA_CREATE(&vv);
        vec vv;
        char *q = p;
        DA_CREATE(&vv);
@@ -69,7 +70,7 @@ int main(void)
          int n = atoi(p);
          DA_PUSH(&vv, n);
        }
          int n = atoi(p);
          DA_PUSH(&vv, n);
        }
-       if (strcmp(q, "insert") == 0) {
+       if (STRCMP(q, ==, "insert")) {
          DA_SHUNT(&v, DA_LEN(&vv));
          DA_SLIDE(&v, DA_LEN(&vv));
          memcpy(DA(&v), DA(&vv), DA_LEN(&vv) * sizeof(int));
          DA_SHUNT(&v, DA_LEN(&vv));
          DA_SLIDE(&v, DA_LEN(&vv));
          memcpy(DA(&v), DA(&vv), DA_LEN(&vv) * sizeof(int));
@@ -80,13 +81,13 @@ int main(void)
          memcpy(DA(&v) + l, DA(&vv), DA_LEN(&vv) * sizeof(int));
        }
        DA_DESTROY(&vv);
          memcpy(DA(&v) + l, DA(&vv), DA_LEN(&vv) * sizeof(int));
        }
        DA_DESTROY(&vv);
-      } else if (strcmp(p, "delete") == 0) {
+      } else if (STRCMP(p, ==, "delete")) {
        int n = atoi(strtok(0, " "));
        DA_UNSLIDE(&v, n);
        int n = atoi(strtok(0, " "));
        DA_UNSLIDE(&v, n);
-      } else if (strcmp(p, "reduce") == 0) {
+      } else if (STRCMP(p, ==, "reduce")) {
        int n = atoi(strtok(0, " "));
        DA_SHRINK(&v, n);
        int n = atoi(strtok(0, " "));
        DA_SHRINK(&v, n);
-      } else if (strcmp(p, "set") == 0) {
+      } else if (STRCMP(p, ==, "set")) {
        size_t i = atoi(strtok(0, " "));
        int n = atoi(strtok(0, " "));
        size_t l = DA_LEN(&v);
        size_t i = atoi(strtok(0, " "));
        int n = atoi(strtok(0, " "));
        size_t l = DA_LEN(&v);
@@ -97,23 +98,23 @@ int main(void)
            DA(&v)[j] = -1;
        }
        DA(&v)[i] = n;
            DA(&v)[j] = -1;
        }
        DA(&v)[i] = n;
-      } else if (strcmp(p, "get") == 0) {
+      } else if (STRCMP(p, ==, "get")) {
        size_t i = atoi(strtok(0, " "));
        if (i >= DA_LEN(&v))
          puts("*RANGE*");
        else
          printf("%i\n", DA(&v)[i]);
        size_t i = atoi(strtok(0, " "));
        if (i >= DA_LEN(&v))
          puts("*RANGE*");
        else
          printf("%i\n", DA(&v)[i]);
-      } else if (strcmp(p, "first") == 0) {
+      } else if (STRCMP(p, ==, "first")) {
        if (DA_LEN(&v))
          printf("%i\n", DA_FIRST(&v));
        else
          puts("*RANGE*");
        if (DA_LEN(&v))
          printf("%i\n", DA_FIRST(&v));
        else
          puts("*RANGE*");
-      } else if (strcmp(p, "last") == 0) {
+      } else if (STRCMP(p, ==, "last")) {
        if (DA_LEN(&v))
          printf("%i\n", DA_LAST(&v));
        else
          puts("*RANGE*");
        if (DA_LEN(&v))
          printf("%i\n", DA_LAST(&v));
        else
          puts("*RANGE*");
-      } else if (strcmp(p, "show") == 0) {
+      } else if (STRCMP(p, ==, "show")) {
        if (DA_LEN(&v) == 0)
          puts("*EMPTY*");
        else {
        if (DA_LEN(&v) == 0)
          puts("*EMPTY*");
        else {
index 5de787075b8f74a4bbcefae3a0476d8ce915d08f..462371d5e8d37b92908da475246093d3b499500e 100644 (file)
@@ -8,6 +8,7 @@
 #include <string.h>
 
 #include "dstr.h"
 #include <string.h>
 
 #include "dstr.h"
+#include "macros.h"
 
 static int win = 0, lose = 0;
 static dstr d = DSTR_INIT;
 
 static int win = 0, lose = 0;
 static dstr d = DSTR_INIT;
@@ -15,7 +16,7 @@ static char buf[1024];
 
 static void check(const char *what, const char *want)
 {
 
 static void check(const char *what, const char *want)
 {
-  if (strcmp(want, d.buf) == 0)
+  if (STRCMP(want, ==, d.buf))
     win++;
   else {
     lose++;
     win++;
   else {
     lose++;
index 8a9435f563ff2b1144cb0e8f16082e4121b28d95..dfc2391220e1562bfb79fbf2311cc58d96e99159 100644 (file)
@@ -3,6 +3,7 @@
 #include <stdlib.h>
 #include <string.h>
 
 #include <stdlib.h>
 #include <string.h>
 
+#include "macros.h"
 #include "sym.h"
 
 typedef struct word {
 #include "sym.h"
 
 typedef struct word {
@@ -31,7 +32,7 @@ int main(void)
     buf[strlen(buf) - 1] = 0;
     p = strtok(buf, " ");
 
     buf[strlen(buf) - 1] = 0;
     p = strtok(buf, " ");
 
-    if (strcmp(p, "set") == 0) {
+    if (STRCMP(p, ==, "set")) {
       char *k = strtok(0, " ");
       int i = atoi(strtok(0, " "));
       unsigned f;
       char *k = strtok(0, " ");
       int i = atoi(strtok(0, " "));
       unsigned f;
@@ -39,14 +40,14 @@ int main(void)
       w->i = i;
       if (!f)
        n++;
       w->i = i;
       if (!f)
        n++;
-    } else if (strcmp(p, "get") == 0) {
+    } else if (STRCMP(p, ==, "get")) {
       char *k = strtok(0, " ");
       word *w = sym_find(&t, k, -1, 0, 0);
       if (w)
        printf("%i\n", w->i);
       else
        puts("*MISSING*");
       char *k = strtok(0, " ");
       word *w = sym_find(&t, k, -1, 0, 0);
       if (w)
        printf("%i\n", w->i);
       else
        puts("*MISSING*");
-    } else if (strcmp(p, "del") == 0) {
+    } else if (STRCMP(p, ==, "del")) {
       char *k = strtok(0, " ");
       word *w = sym_find(&t, k, -1, 0, 0);
       if (w) {
       char *k = strtok(0, " ");
       word *w = sym_find(&t, k, -1, 0, 0);
       if (w) {
@@ -54,9 +55,9 @@ int main(void)
        n--;
       } else
        puts("*MISSING*");
        n--;
       } else
        puts("*MISSING*");
-    } else if (strcmp(p, "count") == 0) {
+    } else if (STRCMP(p, ==, "count")) {
       printf("%lu\n", (unsigned long)n);
       printf("%lu\n", (unsigned long)n);
-    } else if (strcmp(p, "show") == 0) {
+    } else if (STRCMP(p, ==, "show")) {
       sym_iter i;
       word *w;
       word **v, **vv;
       sym_iter i;
       word *w;
       word **v, **vv;
index 01966381688fdb35a5405da23bcecd404f0c88e9..54fc8dc707b1608623460f49ba70bfeeb9baa997 100644 (file)
@@ -63,7 +63,7 @@ int main(int argc, char *argv[])
 
   ego(argv[0]);
 
 
   ego(argv[0]);
 
-  if (argc == 3 && strcmp(argv[1], "server") == 0) {
+  if (argc == 3 && STRCMP(argv[1], ==, "server")) {
     set_unix_addr(&sun, argv[2]);
     lsk = socket(PF_UNIX, SOCK_STREAM, 0);
     if (lsk < 0) die(2, "socket: %s", strerror(errno));
     set_unix_addr(&sun, argv[2]);
     lsk = socket(PF_UNIX, SOCK_STREAM, 0);
     if (lsk < 0) die(2, "socket: %s", strerror(errno));
@@ -77,14 +77,14 @@ int main(int argc, char *argv[])
     if (n < 0) die(2, "fdrecv: %s", strerror(errno));
     close(sk);
     if (fd == -1) die(2, "no fd found");
     if (n < 0) die(2, "fdrecv: %s", strerror(errno));
     close(sk);
     if (fd == -1) die(2, "no fd found");
-    if (n != sizeof(sockmsg) || strcmp(buf, sockmsg) != 0)
+    if (n != sizeof(sockmsg) || STRCMP(buf, !=, sockmsg))
       die(2, "socket message mismatch (found `%.*s')", (int)n, buf);
     n = read(fd, buf, sizeof(buf));
     if (n < 0) die(2, "read: %s", strerror(errno));
       die(2, "socket message mismatch (found `%.*s')", (int)n, buf);
     n = read(fd, buf, sizeof(buf));
     if (n < 0) die(2, "read: %s", strerror(errno));
-    if (n != sizeof(pipemsg) || strcmp(buf, pipemsg) != 0)
+    if (n != sizeof(pipemsg) || STRCMP(buf, !=, pipemsg))
       die(2, "pipe message mismatch (found `%.*s')", (int)n, buf);
     close(fd);
       die(2, "pipe message mismatch (found `%.*s')", (int)n, buf);
     close(fd);
-  } else if (argc == 3 && strcmp(argv[1], "client") == 0) {
+  } else if (argc == 3 && STRCMP(argv[1], ==, "client")) {
     set_unix_addr(&sun, argv[2]);
     if (pipe(pfd)) die(2, "pipe: %s", strerror(errno));
     sk = socket(PF_UNIX, SOCK_STREAM, 0);
     set_unix_addr(&sun, argv[2]);
     if (pipe(pfd)) die(2, "pipe: %s", strerror(errno));
     sk = socket(PF_UNIX, SOCK_STREAM, 0);
index 43aa45d8d05584f8cba09283b4bf08aa437b3788..6597b3323fa7e6ad4a0bfebb96c71c629ebf5194 100644 (file)
@@ -6,6 +6,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include "macros.h"
 #include "mdup.h"
 
 #define MAXFD 256
 #include "mdup.h"
 
 #define MAXFD 256
@@ -33,7 +34,7 @@ int main(int argc, char *argv[])
   int verbose = 0;
 
   for (i = 1, j = 0; i < argc; i++) {
   int verbose = 0;
 
   for (i = 1, j = 0; i < argc; i++) {
-    if (strcmp(argv[i], "-v") == 0) { verbose++; continue; }
+    if (STRCMP(argv[i], ==, "-v")) { verbose++; continue; }
     if (j >= MAXFD) { fprintf(stderr, "too many\n"); exit(1); }
     if (sscanf(argv[i], "%d:%d", &fds[j].cur, &fds[j].want) < 2 ||
        fds[j].cur >= MAXFD)
     if (j >= MAXFD) { fprintf(stderr, "too many\n"); exit(1); }
     if (sscanf(argv[i], "%d:%d", &fds[j].cur, &fds[j].want) < 2 ||
        fds[j].cur >= MAXFD)
index c85276f330dd7210f91512de8327b69df04475ad..c7dea673490ceee746afdaf4a45352b1cd403dff 100644 (file)
@@ -34,6 +34,7 @@
 #include <string.h>
 
 #include "dstr.h"
 #include <string.h>
 
 #include "dstr.h"
+#include "macros.h"
 #include "report.h"
 #include "quis.h"
 #include "testrig.h"
 #include "report.h"
 #include "quis.h"
 #include "testrig.h"
@@ -99,7 +100,7 @@ again:
 
   /* --- Skip leading whitespace --- */
 
 
   /* --- Skip leading whitespace --- */
 
-  while (isspace((unsigned char)ch))
+  while (ISSPACE(ch))
     ch = getc(fp);
 
   /* --- Trap some special characters --- */
     ch = getc(fp);
 
   /* --- Trap some special characters --- */
@@ -163,7 +164,7 @@ again:
          case '`':
            goto done;
          default:
          case '`':
            goto done;
          default:
-           if (isspace((unsigned char)ch))
+           if (ISSPACE(ch))
              goto done;
        }
        if (ch == '\\') {
              goto done;
        }
        if (ch == '\\') {
@@ -328,7 +329,7 @@ int test_do(const test_suite suites[], FILE *fp, test_results *results)
       goto done;
     }
 
       goto done;
     }
 
-    if (strcmp(tok.buf, "SUITE") == 0) {
+    if (STRCMP(tok.buf, ==, "SUITE")) {
       t = gettok(fp);
       if (t != TOK_WORD) {
        moan("expected <word>; found `%s'", decode(t));
       t = gettok(fp);
       if (t != TOK_WORD) {
        moan("expected <word>; found `%s'", decode(t));
@@ -339,7 +340,7 @@ int test_do(const test_suite suites[], FILE *fp, test_results *results)
          chunks = 0;
          break;
        }
          chunks = 0;
          break;
        }
-       if (strcmp(tok.buf, ss->name) == 0) {
+       if (STRCMP(tok.buf, ==, ss->name)) {
          chunks = ss->chunks;
          break;
        }
          chunks = ss->chunks;
          break;
        }
@@ -354,7 +355,7 @@ int test_do(const test_suite suites[], FILE *fp, test_results *results)
     for (cch = chunks; ; cch++) {
       if (!cch->name)
        goto skip_chunk;
     for (cch = chunks; ; cch++) {
       if (!cch->name)
        goto skip_chunk;
-      if (strcmp(tok.buf, cch->name) == 0)
+      if (STRCMP(tok.buf, ==, cch->name))
        break;
     }
 
        break;
     }
 
@@ -479,7 +480,7 @@ void test_run(int argc, char *argv[],
        if (i >= argc - 1)
          break;
        p = argv[++i];
        if (i >= argc - 1)
          break;
        p = argv[++i];
-       if (strcmp(p, "--") == 0) {
+       if (STRCMP(p, ==, "--")) {
          i++;
          break;
        }
          i++;
          break;
        }
index 2681cd32e456c6f621f96862ea1fac993f21d324..e06bf7bd2ce09fecbe7e3447184f831f15334ef2 100644 (file)
@@ -38,6 +38,7 @@
 /* --- Local headers --- */
 
 #include "dstr.h"
 /* --- Local headers --- */
 
 #include "dstr.h"
+#include "macros.h"
 #include "quis.h"
 #include "trace.h"
 
 #include "quis.h"
 #include "trace.h"
 
@@ -132,7 +133,7 @@ void trace_block(unsigned l, const char *s, const void *b, size_t sz)
     dstr_puts(&d, ": ");
     for (i = 0; i < 8; i++) {
       if (i < sz)
     dstr_puts(&d, ": ");
     for (i = 0; i < 8; i++) {
       if (i < sz)
-       dstr_putc(&d, isprint(p[i]) ? p[i] : '.');
+       dstr_putc(&d, ISPRINT(p[i]) ? p[i] : '.');
       else
        dstr_putc(&d, '*');
     }
       else
        dstr_putc(&d, '*');
     }
index 78d82bdbe04f80808967ac142ad51a15dcd90623..bbb8b02361bb91d7ea889c26db7af5a778826dca 100644 (file)
@@ -31,6 +31,7 @@
 #include <string.h>
 #include <stdlib.h>
 
 #include <string.h>
 #include <stdlib.h>
 
+#include "macros.h"
 #include "report.h"
 #include "trace.h"
 
 #include "report.h"
 #include "trace.h"
 
@@ -57,7 +58,7 @@ unsigned traceopt(const trace_opt *t, const char *p,
 
   /* --- Dump out help text --- */
 
 
   /* --- Dump out help text --- */
 
-  if (!p || !strcmp(p, "?")) {
+  if (!p || STRCMP(p, ==, "?")) {
     const trace_opt *tt;
     puts("Trace options:");
     for (tt = t; tt->ch; tt++) {
     const trace_opt *tt;
     puts("Trace options:");
     for (tt = t; tt->ch; tt++) {
index 98ab23861629d91f2e4025e194bf29a942d46839..2d17fa6ab9d2094191c6f40df9150da0338cfd39 100644 (file)
@@ -6,6 +6,25 @@ macros \- useful macros
 .\" @STR
 .\" @GLUE
 .\" @STATIC_ASSERT
 .\" @STR
 .\" @GLUE
 .\" @STATIC_ASSERT
+.\" @ISALNUM
+.\" @ISALPHA
+.\" @ISASCII
+.\" @ISBLANK
+.\" @ISCNTRL
+.\" @ISDIGIT
+.\" @ISGRAPH
+.\" @ISLOWER
+.\" @ISPRINT
+.\" @ISPUNCT
+.\" @ISSPACE
+.\" @ISUPPER
+.\" @ISXDIGIT
+.\" @TOASCII
+.\" @TOLOWER
+.\" @TOUPPER
+.\" @MEMCMP
+.\" @STRCMP
+.\" @STRNCMP
 .\" @DISCARD
 .\" @IGNORE
 .\" @DEPRECATED
 .\" @DISCARD
 .\" @IGNORE
 .\" @DEPRECATED
@@ -27,6 +46,27 @@ macros \- useful macros
 .BI "GLUE(" tokens\fR... ", " tokens\fR... ")"
 .BI "STATIC_ASSERT(" cond ", " msg ");"
 
 .BI "GLUE(" tokens\fR... ", " tokens\fR... ")"
 .BI "STATIC_ASSERT(" cond ", " msg ");"
 
+.BI "ISALNUM(int " ch ");"
+.BI "ISALPHA(int " ch ");"
+.BI "ISASCII(int " ch ");"
+.BI "ISBLANK(int " ch ");"
+.BI "ISCNTRL(int " ch ");"
+.BI "ISDIGIT(int " ch ");"
+.BI "ISGRAPH(int " ch ");"
+.BI "ISLOWER(int " ch ");"
+.BI "ISPRINT(int " ch ");"
+.BI "ISPUNCT(int " ch ");"
+.BI "ISSPACE(int " ch ");"
+.BI "ISUPPER(int " ch ");"
+.BI "ISXDIGIT(int " ch ");"
+.BI "TOASCII(int " ch ");"
+.BI "TOLOWER(int " ch ");"
+.BI "TOUPPER(int " ch ");"
+
+.BI "MEMCMP(const void *" x ", " op ", const void *" y ", size_t " n ");"
+.BI "STRCMP(const char *" x ", " op ", const char *" y ");"
+.BI "STRNCMP(const char *" x ", " op ", const char *" y ", size_t " n ");"
+
 .BI "void DISCARD(" scalar ");"
 .BI "void IGNORE(" variable ");"
 
 .BI "void DISCARD(" scalar ");"
 .BI "void IGNORE(" variable ");"
 
@@ -78,6 +118,40 @@ falls back to a somewhat ugly hack which currently ignores the
 .IR msg .
 .PP
 The
 .IR msg .
 .PP
 The
+.BR IS ...\&
+and
+.BR TO ...\&
+macros are wrappers around the corresponding standard
+.B <ctype.h>
+macros with the corresponding lowercase names.  They take care of
+forcing the character argument
+.I ch
+to
+.BR "unsigned char" :
+this conversion is necessary on platforms with signed
+.B char
+to avoid passing negative values into the standard macros.
+.PP
+The
+.BR MEMCMP ,
+.BR STRCMP ,
+and
+.B STRNCMP
+macros are wrappers around the standard
+.B <string.h>
+functions with the corresponding lowercase names.  They take an
+additional argument
+.I op
+which is a equality or ordering operator (e.g.,
+.B ==
+or
+.BR > )
+inserted between the two operands.  The standard functions return a
+false value if and only if the operands are equal, which is
+counterintuitive and leads to mistakes; requiring an explicit relational
+operator should reduce the number of such mistakes.
+.PP
+The
 .B DISCARD
 macro discards its argument, which must be of some scalar type.  This
 can be useful in muffling warnings about ignoring return codes in cases
 .B DISCARD
 macro discards its argument, which must be of some scalar type.  This
 can be useful in muffling warnings about ignoring return codes in cases
index 9e27a4813a4b3f8997e2ba85784d587023d87778..a5263e19ed319ef09d795284a52370706450e28b 100644 (file)
        IGNORABLE extern char static_assert_failed[2*!!(cond) - 1]
 #endif
 
        IGNORABLE extern char static_assert_failed[2*!!(cond) - 1]
 #endif
 
+/*----- String and character hacks ----------------------------------------*/
+
+#define CTYPE_HACK(func, ch) (func((unsigned char)(ch)))
+
+#define ISALNUM(ch) CTYPE_HACK(isalnum, ch)
+#define ISALPHA(ch) CTYPE_HACK(isalpha, ch)
+#define ISASCII(ch) CTYPE_HACK(isascii, ch)
+#define ISBLANK(ch) CTYPE_HACK(isblank, ch)
+#define ISCNTRL(ch) CTYPE_HACK(iscntrl, ch)
+#define ISDIGIT(ch) CTYPE_HACK(isdigit, ch)
+#define ISGRAPH(ch) CTYPE_HACK(isgraph, ch)
+#define ISLOWER(ch) CTYPE_HACK(islower, ch)
+#define ISPRINT(ch) CTYPE_HACK(isprint, ch)
+#define ISPUNCT(ch) CTYPE_HACK(ispunct, ch)
+#define ISSPACE(ch) CTYPE_HACK(isspace, ch)
+#define ISUPPER(ch) CTYPE_HACK(isupper, ch)
+#define ISXDIGIT(ch) CTYPE_HACK(isxdigit, ch)
+
+#define TOASCII(ch) CTYPE_HACK(toascii, ch)
+#define TOLOWER(ch) CTYPE_HACK(tolower, ch)
+#define TOUPPER(ch) CTYPE_HACK(toupper, ch)
+
+#define MEMCMP(x, op, y, n) (memcmp((x), (y), (n)) op 0)
+#define STRCMP(x, op, y) (strcmp((x), (y)) op 0)
+#define STRNCMP(x, op, y, n) (strncmp((x), (y), (n)) op 0)
+
 /*----- Compiler diagnostics ----------------------------------------------*/
 
 /* --- Compiler-specific definitions --- */
 /*----- Compiler diagnostics ----------------------------------------------*/
 
 /* --- Compiler-specific definitions --- */
index 51ca3236d5af3a63dee27fac3f8f45d2960d9a6a..e7598284564c9f85382d6915e9a7a1f22d93dbcb 100644 (file)
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #include <string.h>
 
 #include <stdlib.h>
 #include <string.h>
 
+#include "macros.h"
 #include "str.h"
 
 /*----- Main code ---------------------------------------------------------*/
 #include "str.h"
 
 /*----- Main code ---------------------------------------------------------*/
@@ -58,7 +59,7 @@ char *str_qword(char **pp, unsigned f)
 
   if (!p)
     return (0);
 
   if (!p)
     return (0);
-  while (isspace((unsigned char)*p))
+  while (ISSPACE(*p))
     p++;
   if (!*p) {
     *pp = 0;
     p++;
   if (!*p) {
     *pp = 0;
@@ -83,8 +84,8 @@ char *str_qword(char **pp, unsigned f)
          *qq++ = *q;
        break;
       default:
          *qq++ = *q;
        break;
       default:
-       if (isspace((unsigned char)*q)) {
-         do q++; while (*q && isspace((unsigned char)*q));
+       if (ISSPACE(*q)) {
+         do q++; while (*q && ISSPACE(*q));
          goto done;
        } else if (!(f & STRF_QUOTE))
          goto stdchar;
          goto done;
        } else if (!(f & STRF_QUOTE))
          goto stdchar;
@@ -312,7 +313,7 @@ void str_sanitize(char *d, const char *p, size_t sz)
   sz--;
   while (*p && sz) {
     int ch = *p++;
   sz--;
   while (*p && sz) {
     int ch = *p++;
-    if (!isgraph((unsigned char)ch))
+    if (!ISGRAPH(ch))
       ch = '_';
     *d++ = ch;
     sz--;
       ch = '_';
     *d++ = ch;
     sz--;
index 3556916be2f7f8ea4833eaa2e4ac092c40d525bd..e8bf9ae473d56c173f8ff49238ca2213fd012a38 100644 (file)
@@ -30,6 +30,7 @@
 #include <ctype.h>
 #include <string.h>
 
 #include <ctype.h>
 #include <string.h>
 
+#include "macros.h"
 #include "versioncmp.h"
 
 /*----- Main code ---------------------------------------------------------*/
 #include "versioncmp.h"
 
 /*----- Main code ---------------------------------------------------------*/
@@ -79,7 +80,7 @@ static int vint(const char **vv, const char *vl)
 
   while (v < vl) {
     ch = *v;
 
   while (v < vl) {
     ch = *v;
-    if (!isdigit((unsigned char)ch))
+    if (!ISDIGIT(ch))
       break;
     v++;
     n = n * 10 + (ch - '0');
       break;
     v++;
     n = n * 10 + (ch - '0');
@@ -96,7 +97,7 @@ static const char *vchr(const char **vv, const char *vl)
 
   while (v < vl) {
     ch = *v;
 
   while (v < vl) {
     ch = *v;
-    if (isdigit((unsigned char)ch))
+    if (ISDIGIT(ch))
       break;
     v++;
   }
       break;
     v++;
   }
@@ -124,12 +125,12 @@ static int vcmp(const char *va, const char *val,
     pa = vchr(&va, val); pb = vchr(&vb, vbl);
     for (;;) {
       if (pa == va) ia = 1;
     pa = vchr(&va, val); pb = vchr(&vb, vbl);
     for (;;) {
       if (pa == va) ia = 1;
-      else if (isalpha((unsigned char)*pa)) ia = 2;
+      else if (ISALPHA(*pa)) ia = 2;
       else if (*pa == '~') ia = 0;
       else ia = 3;
 
       if (pb == vb) ib = 1;
       else if (*pa == '~') ia = 0;
       else ia = 3;
 
       if (pb == vb) ib = 1;
-      else if (isalpha((unsigned char)*pb)) ib = 2;
+      else if (ISALPHA(*pb)) ib = 2;
       else if (*pb == '~') ib = 0;
       else ib = 3;
 
       else if (*pb == '~') ib = 0;
       else ib = 3;