countof() has stronger type-safety constraints than a sizeof division.
It also results in significantly more readable code.

Signed-off-by: Alejandro Colomar <a...@kernel.org>
---
 src/devices/grolbp/lbp.cpp        |  3 ++-
 src/devices/grolj4/lj4.cpp        |  4 ++--
 src/libs/libgroff/font.cpp        |  4 ++--
 src/libs/libgroff/uniglyph.cpp    |  6 +++---
 src/preproc/eqn/delim.cpp         |  9 +++++----
 src/preproc/eqn/lex.cpp           | 10 ++++++----
 src/preproc/eqn/text.cpp          |  6 +++---
 src/preproc/pic/lex.cpp           |  3 ++-
 src/preproc/preconv/preconv.cpp   |  6 +++---
 src/preproc/refer/command.cpp     |  5 +++--
 src/preproc/refer/ref.cpp         |  4 +++-
 src/utils/addftinfo/addftinfo.cpp |  6 +++---
 src/utils/hpftodit/hpftodit.cpp   |  6 +++---
 src/utils/hpftodit/hpuni.cpp      |  6 +++---
 src/utils/tfmtodit/tfmtodit.cpp   |  9 ++++-----
 15 files changed, 47 insertions(+), 40 deletions(-)

diff --git a/src/devices/grolbp/lbp.cpp b/src/devices/grolbp/lbp.cpp
index 64d60f2cd..12a3d6b41 100644
--- a/src/devices/grolbp/lbp.cpp
+++ b/src/devices/grolbp/lbp.cpp
@@ -31,6 +31,7 @@ TODO
 #include <errno.h>
 #include <limits.h> // INT_MAX
 #include <math.h> // fabs(), sqrt()
+#include <stdcountof.h>
 #include <stdlib.h> // abs(), EXIT_SUCCESS, exit(), strtol()
 #include <string.h> // strcmp(), strcpy(), strlen(), strncpy()
 #include <strings.h> // strcasecmp()
@@ -599,7 +600,7 @@ static int set_papersize(const char *paperformat)
   unsigned int i;
   // First, test for a standard (i.e. supported directly by the printer)
   // paper format.
-  for (i = 0 ; i < sizeof(lbp_papersizes) / sizeof(lbp_papersizes[0]); i++)
+  for (i = 0 ; i < countof(lbp_papersizes); i++)
   {
     if (strcasecmp(lbp_papersizes[i].name,paperformat) == 0)
       return lbp_papersizes[i].code;
diff --git a/src/devices/grolj4/lj4.cpp b/src/devices/grolj4/lj4.cpp
index ff60965ec..8434f9435 100644
--- a/src/devices/grolj4/lj4.cpp
+++ b/src/devices/grolj4/lj4.cpp
@@ -37,6 +37,7 @@ X command to include bitmap graphics
 #include <assert.h>
 #include <locale.h> // setlocale()
 #include <math.h> // atan2(), floor()
+#include <stdcountof.h>
 #include <stdio.h> // EOF, FILE, fflush(), fprintf(), printf(),
                   // setbuf(), stderr, stdout
 #include <stdlib.h> // exit(), EXIT_SUCCESS, strtol()
@@ -612,8 +613,7 @@ printer *make_printer()
 static
 int lookup_paper_size(const char *s)
 {
-  for (unsigned int i = 0;
-       i < sizeof(paper_table)/sizeof(paper_table[0]); i++) {
+  for (unsigned int i = 0; i < countof(paper_table); i++) {
     // FIXME Perhaps allow unique prefix.
     if (strcasecmp(s, paper_table[i].name) == 0)
       return i;
diff --git a/src/libs/libgroff/font.cpp b/src/libs/libgroff/font.cpp
index c0d428963..3aa5b665b 100644
--- a/src/libs/libgroff/font.cpp
+++ b/src/libs/libgroff/font.cpp
@@ -25,6 +25,7 @@ along with this program.  If not, see 
<http://www.gnu.org/licenses/>. */
 #include <errno.h>
 #include <limits.h> // INT_MAX, INT_MIN, LONG_MAX
 #include <math.h>
+#include <stdcountof.h>
 #include <stdlib.h>
 #include <string.h> // strerror()
 #include <wchar.h>
@@ -1283,8 +1284,7 @@ const char *font::load_desc()
     assert(p != 0 /* nullptr */);
     bool numeric_directive_found = false;
     unsigned int idx;
-    for (idx = 0; !numeric_directive_found
-                 && idx < sizeof(table) / sizeof(table[0]); idx++)
+    for (idx = 0; !numeric_directive_found && idx < countof(table); idx++)
       if (strcmp(table[idx].numeric_directive, p) == 0)
        numeric_directive_found = true;
     if (numeric_directive_found) {
diff --git a/src/libs/libgroff/uniglyph.cpp b/src/libs/libgroff/uniglyph.cpp
index c6b54ed24..3790c3568 100644
--- a/src/libs/libgroff/uniglyph.cpp
+++ b/src/libs/libgroff/uniglyph.cpp
@@ -20,6 +20,8 @@ along with this program.  If not, see 
<http://www.gnu.org/licenses/>. */
 #include <config.h>
 #endif
 
+#include <stdcountof.h>
+
 #include "lib.h"
 
 #include "stringclass.h"
@@ -431,9 +433,7 @@ static struct unicode_to_glyph_init {
 
 unicode_to_glyph_init::unicode_to_glyph_init()
 {
-  for (unsigned int i = 0;
-       i < sizeof(unicode_to_glyph_list)/sizeof(unicode_to_glyph_list[0]);
-       i++) {
+  for (unsigned int i = 0; i < countof(unicode_to_glyph_list); i++) {
     unicode_to_glyph *utg = new unicode_to_glyph[1];
     utg->value = (char *)unicode_to_glyph_list[i].value;
     unicode_to_glyph_table.define(unicode_to_glyph_list[i].key, utg);
diff --git a/src/preproc/eqn/delim.cpp b/src/preproc/eqn/delim.cpp
index 452826c13..dfe98d2f0 100644
--- a/src/preproc/eqn/delim.cpp
+++ b/src/preproc/eqn/delim.cpp
@@ -20,6 +20,8 @@ along with this program.  If not, see 
<http://www.gnu.org/licenses/>. */
 #include <config.h>
 #endif
 
+#include <stdcountof.h>
+
 #include <assert.h>
 
 #include "eqn.h"
@@ -162,8 +164,6 @@ struct delimiter {
   },
 };
 
-const int DELIM_TABLE_SIZE = int(sizeof(delim_table)/sizeof(delim_table[0]));
-
 class delim_box : public box {
 private:
   char *left;
@@ -301,11 +301,12 @@ static void define_extensible_string(char *delim, int uid,
   delimiter *d = delim_table;
   size_t delim_len = strlen(delim);
   int i;
-  for (i = 0; i < DELIM_TABLE_SIZE; i++, d++)
+
+  for (i = 0; i < int(countof(delim_table)); i++, d++)
     if (strncmp(delim, d->name, delim_len) == 0 
        && (left_or_right & d->flags) != 0)
       break;
-  if (i >= DELIM_TABLE_SIZE) {
+  if (i >= int(countof(delim_table))) {
     error("there is no '%1' delimiter", delim);
     printf(".nr " DELIM_WIDTH_REG " 0\n");
     return;
diff --git a/src/preproc/eqn/lex.cpp b/src/preproc/eqn/lex.cpp
index d8304f34c..9fbf72c34 100644
--- a/src/preproc/eqn/lex.cpp
+++ b/src/preproc/eqn/lex.cpp
@@ -20,6 +20,8 @@ along with this program.  If not, see 
<http://www.gnu.org/licenses/>. */
 #include <config.h>
 #endif
 
+#include <stdcountof.h>
+
 #include "eqn.h"
 #include "eqn.hpp"
 #include "stringclass.h"
@@ -283,13 +285,13 @@ static struct builtin_def mathml_defs[] = {
 void init_table(const char *device)
 {
   unsigned int i;
-  for (i = 0; i < sizeof(token_table)/sizeof(token_table[0]); i++) {
+  for (i = 0; i < countof(token_table); i++) {
     definition *def = new definition[1];
     def->is_macro = 0;
     def->tok = token_table[i].token;
     macro_table.define(token_table[i].name, def);
   }
-  for (i = 0; i < sizeof(common_defs)/sizeof(common_defs[0]); i++) {
+  for (i = 0; i < countof(common_defs); i++) {
     definition *def = new definition[1];
     def->is_macro = 1;
     def->contents = strsave(common_defs[i].def);
@@ -297,7 +299,7 @@ void init_table(const char *device)
     macro_table.define(common_defs[i].name, def);
   }
   if (output_format == troff) {
-    for (i = 0; i < sizeof(troff_defs)/sizeof(troff_defs[0]); i++) {
+    for (i = 0; i < countof(troff_defs); i++) {
       definition *def = new definition[1];
       def->is_macro = 1;
       def->contents = strsave(troff_defs[i].def);
@@ -306,7 +308,7 @@ void init_table(const char *device)
     }
   }
   else if (output_format == mathml) {
-    for (i = 0; i < sizeof(mathml_defs)/sizeof(mathml_defs[0]); i++) {
+    for (i = 0; i < countof(mathml_defs); i++) {
       definition *def = new definition[1];
       def->is_macro = 1;
       def->contents = strsave(mathml_defs[i].def);
diff --git a/src/preproc/eqn/text.cpp b/src/preproc/eqn/text.cpp
index 59e39e698..082711016 100644
--- a/src/preproc/eqn/text.cpp
+++ b/src/preproc/eqn/text.cpp
@@ -21,7 +21,9 @@ along with this program.  If not, see 
<http://www.gnu.org/licenses/>. */
 #endif
 
 #include <ctype.h>
+#include <stdcountof.h>
 #include <stdlib.h>
+
 #include "eqn.h"
 #include "pbox.h"
 #include "ptable.h"
@@ -396,9 +398,7 @@ struct map entity_table[] = {
 const char *special_to_entity(const char *sp)
 {
   struct map *mp;
-  for (mp = entity_table; 
-       mp < entity_table + sizeof(entity_table)/sizeof(entity_table[0]); 
-       mp++) {
+  for (mp = entity_table; mp < entity_table + countof(entity_table)); mp++) {
     if (strcmp(mp->from, sp) == 0)
       return mp->to;
   }
diff --git a/src/preproc/pic/lex.cpp b/src/preproc/pic/lex.cpp
index 43131c6a8..e19e5c6a3 100644
--- a/src/preproc/pic/lex.cpp
+++ b/src/preproc/pic/lex.cpp
@@ -23,6 +23,7 @@ along with this program.  If not, see 
<http://www.gnu.org/licenses/>. */
 #include <assert.h>
 #include <errno.h>
 #include <math.h> // pow()
+#include <stdcountof.h>
 #include <stdio.h> // EOF, FILE, fclose(), fopen(), getc(), ungetc()
 #include <string.h> // strerror()
 
@@ -571,7 +572,7 @@ int lookup_keyword(const char *str, int len)
   };
   
   const keyword *start = table;
-  const keyword *end = table + sizeof(table)/sizeof(table[0]);
+  const keyword *end = table + countof(table);
   while (start < end) {
     // start <= target < end
     const keyword *mid = start + (end - start)/2;
diff --git a/src/preproc/preconv/preconv.cpp b/src/preproc/preconv/preconv.cpp
index c81ddbc6d..623abce0d 100644
--- a/src/preproc/preconv/preconv.cpp
+++ b/src/preproc/preconv/preconv.cpp
@@ -31,6 +31,7 @@ along with this program.  If not, see 
<http://www.gnu.org/licenses/>. */
 # endif
 #endif
 #include <locale.h> // setlocale()
+#include <stdcountof.h>
 #include <stdio.h> // EOF, FILE, fclose(), ferror(), fflush(), fileno(),
                   // fopen(), fprintf(), fread(), fseek(), ftell(),
                   // getc(), printf(), putchar(), rewind(), SEEK_SET,
@@ -804,7 +805,6 @@ get_BOM(FILE *fp, string &BOM, string &data)
     {2, "\xFE\xFF", "UTF-16"},
     {2, "\xFF\xFE", "UTF-16"},
   };
-  const int BOM_table_len = sizeof (BOM_table) / sizeof (BOM_table[0]);
   char BOM_string[4];
   const char *retval = NULL;
   int len;
@@ -815,13 +815,13 @@ get_BOM(FILE *fp, string &BOM, string &data)
     BOM_string[len] = char(c);
   }
   int i;
-  for (i = 0; i < BOM_table_len; i++) {
+  for (i = 0; i < countof(BOM_table); i++) {
     if (BOM_table[i].len <= len
        && memcmp(BOM_string, BOM_table[i].str, BOM_table[i].len) == 0)
       break;
   }
   int j = 0;
-  if (i < BOM_table_len) {
+  if (i < countof(BOM_table)) {
     for (; j < BOM_table[i].len; j++)
       BOM += BOM_string[j];
     retval = BOM_table[i].name;
diff --git a/src/preproc/refer/command.cpp b/src/preproc/refer/command.cpp
index f24a08111..eef7ca3af 100644
--- a/src/preproc/refer/command.cpp
+++ b/src/preproc/refer/command.cpp
@@ -20,6 +20,8 @@ along with this program.  If not, see 
<http://www.gnu.org/licenses/>. */
 #include <config.h>
 #endif
 
+#include <stdcountof.h>
+
 #include "refer.h"
 #include "refid.h"
 #include "search.h"
@@ -758,8 +760,7 @@ static int check_args(const char *types, const char *name,
 
 static void execute_command(const char *name, int argc, argument *argv)
 {
-  for (unsigned int i = 0;
-       i < sizeof(command_table)/sizeof(command_table[0]); i++)
+  for (unsigned int i = 0; i < countof(command_table); i++)
     if (strcmp(name, command_table[i].name) == 0) {
       if (check_args(command_table[i].arg_types, name, argc, argv))
        (*command_table[i].func)(argc, argv);
diff --git a/src/preproc/refer/ref.cpp b/src/preproc/refer/ref.cpp
index 0cb9f632e..64e9817a4 100644
--- a/src/preproc/refer/ref.cpp
+++ b/src/preproc/refer/ref.cpp
@@ -20,6 +20,8 @@ along with this program.  If not, see 
<http://www.gnu.org/licenses/>. */
 #include <config.h>
 #endif
 
+#include <stdcountof.h>
+
 #include "refer.h"
 #include "refid.h"
 #include "ref.h"
@@ -955,7 +957,7 @@ static int find_month(const char *start, const char *end)
     while (ptr < end && csalpha(*ptr))
       ptr++;
     if (ptr - start >= 3) {
-      for (unsigned int i = 0; i < sizeof(months)/sizeof(months[0]); i++) {
+      for (unsigned int i = 0; i < countof(months); i++) {
        const char *q = months[i];
        const char *p = start;
        for (; p < ptr; p++, q++)
diff --git a/src/utils/addftinfo/addftinfo.cpp 
b/src/utils/addftinfo/addftinfo.cpp
index 7f6090d9d..604dc452c 100644
--- a/src/utils/addftinfo/addftinfo.cpp
+++ b/src/utils/addftinfo/addftinfo.cpp
@@ -21,6 +21,7 @@ along with this program.  If not, see 
<http://www.gnu.org/licenses/>. */
 #endif
 
 #include <errno.h>
+#include <stdcountof.h>
 #include <stdlib.h> // exit(), EXIT_SUCCESS, strtol()
 
 #include "lib.h"
@@ -115,7 +116,7 @@ int main(int argc, char **argv)
       usage("option requires argument");
     size_t j;
     for (j = 0;; j++) {
-      if (j >= sizeof(param_table)/sizeof(param_table[0]))
+      if (j >= countof(param_table))
        fatal("parameter '%1' not recognized", argv[i] + 1);
       if (strcmp(param_table[j].name, argv[i] + 1) == 0)
        break;
@@ -137,8 +138,7 @@ int main(int argc, char **argv)
 static void usage(FILE *stream)
 {
   fprintf(stream, "usage: %s", program_name);
-  size_t len = sizeof(param_table)/sizeof(param_table[0]);
-  for (size_t i = 0; i < len; i++)
+  for (size_t i = 0; i < countof(param_table); i++)
     fprintf(stream, " [-%s n]", param_table[i].name);
   fputs(" resolution unit-width font\n", stream);
   fprintf(stream, "usage: %s {-v | --version}\n"
diff --git a/src/utils/hpftodit/hpftodit.cpp b/src/utils/hpftodit/hpftodit.cpp
index 2cc107640..30408edc5 100644
--- a/src/utils/hpftodit/hpftodit.cpp
+++ b/src/utils/hpftodit/hpftodit.cpp
@@ -30,6 +30,7 @@ put filename in error messages (or fix lib)
 #include <assert.h>
 #include <errno.h>
 #include <math.h> // cos(), sin()
+#include <stdcountof.h>
 #include <stdio.h> // FILE, fclose(), fgets(), fopen(), fprintf(),
                   // freopen(), printf(), sprintf()
 #include <stdlib.h> // atoi(), exit(), EXIT_FAILURE, EXIT_SUCCESS,
@@ -51,7 +52,6 @@ put filename in error messages (or fix lib)
 extern "C" const char *Version_string;
 extern const char *hp_msl_to_unicode_code(const char *);
 
-#define SIZEOF(v) (sizeof(v)/sizeof(v[0]))
 #define equal(a, b) (strcmp(a, b) == 0)
 // only valid if is_uname(c) has returned true
 #define is_decomposed(c) strchr(c, '_')
@@ -818,7 +818,7 @@ output_ligatures()
     if (charcode < charcode_name_table_size
        && char_table[i].symbol_set != NO_SYMBOL_SET) {
       for (name_list *p = charcode_name_table[charcode]; p; p = p->next)
-       for (unsigned int j = 0; j < SIZEOF(ligature_chars); j++)
+       for (unsigned int j = 0; j < countof(ligature_chars); j++)
          if (strcmp(p->name, ligature_chars[j]) == 0) {
            ligature_mask |= 1 << j;
            break;
@@ -827,7 +827,7 @@ output_ligatures()
     }
   if (ligature_mask) {
     printf("ligatures");
-    for (i = 0; i < SIZEOF(ligature_names); i++)
+    for (i = 0; i < countof(ligature_names); i++)
       if (ligature_mask & (1 << i))
        printf(" %s", ligature_names[i]);
     printf(" 0\n");
diff --git a/src/utils/hpftodit/hpuni.cpp b/src/utils/hpftodit/hpuni.cpp
index b1b17d650..7fc5ad9d0 100644
--- a/src/utils/hpftodit/hpuni.cpp
+++ b/src/utils/hpftodit/hpuni.cpp
@@ -20,6 +20,8 @@ along with this program.  If not, see 
<http://www.gnu.org/licenses/>. */
 #include <config.h>
 #endif
 
+#include <stdcountof.h>
+
 #include "lib.h"
 
 #include "stringclass.h"
@@ -685,9 +687,7 @@ static struct hp_msl_to_unicode_init {
 } _hp_msl_to_unicode_init;
 
 hp_msl_to_unicode_init::hp_msl_to_unicode_init() {
-  for (unsigned int i = 0;
-       i < sizeof(hp_msl_to_unicode_list)/sizeof(hp_msl_to_unicode_list[0]);
-       i++) {
+  for (unsigned int i = 0; i < countof(hp_msl_to_unicode_list); i++) {
     hp_msl_to_unicode *ptu = new hp_msl_to_unicode[1];
     ptu->value = (char *)hp_msl_to_unicode_list[i].value;
     hp_msl_to_unicode_table.define(hp_msl_to_unicode_list[i].key, ptu);
diff --git a/src/utils/tfmtodit/tfmtodit.cpp b/src/utils/tfmtodit/tfmtodit.cpp
index 54675deb3..40b45a44f 100644
--- a/src/utils/tfmtodit/tfmtodit.cpp
+++ b/src/utils/tfmtodit/tfmtodit.cpp
@@ -53,6 +53,7 @@ both be zero. */
 #include <assert.h>
 #include <errno.h>
 #include <math.h> // atan2()
+#include <stdcountof.h>
 #include <stdlib.h> // exit(), EXIT_SUCCESS, strtol()
 
 #include <getopt.h> // getopt_long()
@@ -807,10 +808,8 @@ int main(int argc, char **argv)
   // Print the list of ligatures.
   // First find the indices of each character that can participate in
   // a ligature.
-  size_t lig_char_entries = sizeof(lig_chars)/sizeof(lig_chars[0]);
-  size_t lig_table_entries = sizeof(lig_table)/sizeof(lig_table[0]);
   for (i = 0; i < 256; i++)
-    for (unsigned int j = 0; j < lig_char_entries; j++)
+    for (unsigned int j = 0; j < countof(lig_chars); j++)
       for (char_list *p = table[i]; p; p = p->next)
        if (strcmp(lig_chars[j].ch, p->ch) == 0)
          lig_chars[j].i = i;
@@ -818,7 +817,7 @@ int main(int argc, char **argv)
   // and it appears as a ligature in the tfm file, include in
   // the list of ligatures.
   int started = 0;
-  for (i = 0; i < lig_table_entries; i++) {
+  for (i = 0; i < countof(lig_table); i++) {
     int i1 = lig_chars[lig_table[i].c1].i;
     int i2 = lig_chars[lig_table[i].c2].i;
     int r = lig_chars[lig_table[i].res].i;
@@ -869,7 +868,7 @@ int main(int argc, char **argv)
       m[5] = g.get_right_adjustment(i);
       printf("%s\t%d", p->ch, m[0]*MULTIPLIER);
       int j;
-      for (j = int(sizeof(m)/sizeof(m[0])) - 1; j > 0; j--)
+      for (j = int(countof(m)) - 1; j > 0; j--)
        if (m[j] != 0)
          break;
       for (k = 1; k <= j; k++)
-- 
2.50.0


Reply via email to