Author: pepeto
Date: Fri Nov 28 09:59:09 2014
New Revision: 27149

URL: http://svn.gna.org/viewcvs/freeciv?rev=27149&view=rev
Log:
Remove usage of switch statements in the specenum module.

See gna patch #5461

Modified:
    trunk/common/tech.c
    trunk/common/terrain.c
    trunk/common/unittype.c
    trunk/utility/generate_specenum.py

Modified: trunk/common/tech.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/tech.c?rev=27149&r1=27148&r2=27149&view=diff
==============================================================================
--- trunk/common/tech.c (original)
+++ trunk/common/tech.c Fri Nov 28 09:59:09 2014
@@ -329,7 +329,7 @@
 /**************************************************************************
   Tech flag name callback, called from specenum code.
 **************************************************************************/
-char *tech_flag_id_name_cb(enum tech_flag_id flag)
+const char *tech_flag_id_name_cb(enum tech_flag_id flag)
 {
   if (flag < TECH_USER_1 || flag > TECH_USER_LAST) {
     return NULL;

Modified: trunk/common/terrain.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/terrain.c?rev=27149&r1=27148&r2=27149&view=diff
==============================================================================
--- trunk/common/terrain.c      (original)
+++ trunk/common/terrain.c      Fri Nov 28 09:59:09 2014
@@ -908,7 +908,7 @@
 /**************************************************************************
   Terrain flag name callback, called from specenum code.
 **************************************************************************/
-char *terrain_flag_id_name_cb(enum terrain_flag_id flag)
+const char *terrain_flag_id_name_cb(enum terrain_flag_id flag)
 {
   if (flag < TER_USER_1 || flag > TER_USER_LAST) {
     return NULL;

Modified: trunk/common/unittype.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/unittype.c?rev=27149&r1=27148&r2=27149&view=diff
==============================================================================
--- trunk/common/unittype.c     (original)
+++ trunk/common/unittype.c     Fri Nov 28 09:59:09 2014
@@ -816,7 +816,7 @@
 /**************************************************************************
   Unit type flag name callback, called from specenum code.
 **************************************************************************/
-char *unit_type_flag_id_name_cb(enum unit_type_flag_id flag)
+const char *unit_type_flag_id_name_cb(enum unit_type_flag_id flag)
 {
   if (flag < UTYF_USER_FLAG_1 || flag > UTYF_LAST_USER_FLAG) {
     return NULL;

Modified: trunk/utility/generate_specenum.py
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/utility/generate_specenum.py?rev=27149&r1=27148&r2=27149&view=diff
==============================================================================
--- trunk/utility/generate_specenum.py  (original)
+++ trunk/utility/generate_specenum.py  Fri Nov 28 09:59:09 2014
@@ -207,6 +207,7 @@
     macros.append("SPECENUM_ZERO")
     macros.append("SPECENUM_MIN_VALUE")
     macros.append("SPECENUM_MAX_VALUE")
+    macros.append("SPECENUM_SIZE")
     macros.append("SPECENUM_NAMEOVERRIDE")
     macros.append("SPECENUM_BITVECTOR")
 
@@ -223,15 +224,19 @@
         file.write('''
 #ifdef SPECENUM_VALUE%d
   SPECENUM_VALUE%d = SPECENUM_VALUE(%d),
-#ifndef SPECENUM_MIN_VALUE
-#define SPECENUM_MIN_VALUE SPECENUM_VALUE%d
-#endif
-#ifdef SPECENUM_MAX_VALUE
-#undef SPECENUM_MAX_VALUE
-#endif
-#define SPECENUM_MAX_VALUE SPECENUM_VALUE%d
+#  ifndef SPECENUM_MIN_VALUE
+#    define SPECENUM_MIN_VALUE SPECENUM_VALUE%d
+#  endif
+#  ifdef SPECENUM_MAX_VALUE
+#    undef SPECENUM_MAX_VALUE
+#  endif
+#  define SPECENUM_MAX_VALUE SPECENUM_VALUE%d
+#  ifdef SPECENUM_SIZE
+#    undef SPECENUM_SIZE
+#  endif
+#  define SPECENUM_SIZE (%d + 1)
 #endif /* SPECENUM_VALUE%d */
-'''%(i,i,i,i,i,i))
+'''%(i,i,i,i,i,i,i))
 
     file.write('''
 #ifdef SPECENUM_COUNT
@@ -288,28 +293,51 @@
 **************************************************************************/
 static inline bool SPECENUM_FOO(_is_valid)(enum SPECENUM_NAME enumerator)
 {
-  switch (enumerator) {
-#ifdef SPECENUM_ZERO
-  case SPECENUM_ZERO:
-#endif
-''')
+#ifdef SPECENUM_BITWISE
+  static const unsigned long valid = (
+    0''')
 
     for i in range(max_enum_values):
         file.write('''
-#ifdef SPECENUM_VALUE%d
-  case SPECENUM_VALUE%d:
-#endif
-'''%(i,i))
-
-    file.write('''
+#  ifdef SPECENUM_VALUE%d
+    | SPECENUM_VALUE%d
+#  endif'''%(i,i))
+
+    file.write('''
+  );
+
+  FC_STATIC_ASSERT(sizeof(valid) * 8 >= SPECENUM_SIZE,
+                   valid_sizeof_check);
+
+#  ifdef SPECENUM_ZERO
+  if (enumerator == SPECENUM_ZERO) {
     return TRUE;
-#ifdef SPECENUM_COUNT
-  case SPECENUM_COUNT:
-    return FALSE;
-#endif /* SPECENUM_COUNT */
-  }
-
-  return FALSE;
+  }
+#  endif
+  return (enumerator & valid) == enumerator;
+#else
+  static const bool valid[] = {''')
+
+    for i in range(max_enum_values):
+        file.write('''
+#  if %d < SPECENUM_SIZE
+#    ifdef SPECENUM_VALUE%d
+       TRUE,
+#    else
+       FALSE,
+#    endif
+#  endif'''%(i,i))
+
+    file.write('''
+  };
+
+  FC_STATIC_ASSERT(ARRAY_SIZE(valid) == SPECENUM_SIZE,
+                   valid_array_size_check);
+
+  return (enumerator >= 0
+          && enumerator < ARRAY_SIZE(valid)
+          && valid[enumerator]);
+#endif /* SPECENUM_BITWISE */
 }
 ''')
 
@@ -374,7 +402,7 @@
 def make_name(file):
     file.write('''
 #ifdef SPECENUM_NAMEOVERRIDE
-char *SPECENUM_FOO(_name_cb)(enum SPECENUM_NAME value);
+const char *SPECENUM_FOO(_name_cb)(enum SPECENUM_NAME value);
 #endif /* SPECENUM_NAMEOVERRIDE */
 
 /**************************************************************************
@@ -382,53 +410,78 @@
 **************************************************************************/
 static inline const char *SPECENUM_FOO(_name)(enum SPECENUM_NAME enumerator)
 {
+#ifdef SPECENUM_COUNT
+  static const char *names[SPECENUM_SIZE + 1];
+#else
+  static const char *names[SPECENUM_SIZE];
+#endif
+  static bool initialized = FALSE;
+
 #ifdef SPECENUM_NAMEOVERRIDE
-  char *name = SPECENUM_FOO(_name_cb)(enumerator);
-
-  if (name != NULL) {
-    return skip_intl_qualifier_prefix(name);
+  {
+    const char *name = SPECENUM_FOO(_name_cb)(enumerator);
+
+    if (name != NULL) {
+      return Qn_(name);
+    }
   }
 #endif /* SPECENUM_NAMEOVERRIDE */
 
-  switch (enumerator) {
-#ifdef SPECENUM_ZERO
-  case SPECENUM_ZERO:
-#ifdef SPECENUM_ZERONAME
-    return skip_intl_qualifier_prefix(SPECENUM_ZERONAME);
-#else
-    return SPECENUM_STRING(SPECENUM_ZERO);
-#endif
-#endif /* SPECENUM_ZERO */
-''')
-    macros.append("SPECENUM_ZERONAME")
+  if (!initialized) {''')
 
     for i in range(max_enum_values):
         file.write('''
-#ifdef SPECENUM_VALUE%d
-  case SPECENUM_VALUE%d:
-#ifdef SPECENUM_VALUE%dNAME
-    return skip_intl_qualifier_prefix(SPECENUM_VALUE%dNAME);
+#if %d < SPECENUM_SIZE
+#  ifndef SPECENUM_VALUE%d
+     names[%d] = NULL;
+#  elif defined(SPECENUM_VALUE%dNAME)
+     names[%d] = Qn_(SPECENUM_VALUE%dNAME);
+#  else
+     names[%d] = SPECENUM_STRING(SPECENUM_VALUE%d);
+#  endif
+#endif'''%(i,i,i,i,i,i,i,i))
+        macros.append("SPECENUM_VALUE%dNAME"%i)
+
+    file.write('''
+#ifdef SPECENUM_COUNT
+#  ifdef SPECENUM_COUNTNAME
+  names[SPECENUM_COUNT] = Qn_(SPECENUM_COUNTNAME);
+#  else
+  names[SPECENUM_COUNT] = SPECENUM_STRING(SPECENUM_COUNT);
+#  endif
+#endif
+    initialized = TRUE;
+  }
+
+#ifdef SPECENUM_BITWISE
+#  ifdef SPECENUM_ZERO
+  if (enumerator == SPECENUM_ZERO) {
+#    ifdef SPECENUM_ZERONAME
+    return Qn_(SPECENUM_ZERONAME);
+#    else
+    return SPECENUM_STRING(SPECENUM_ZERO);
+#    endif
+  }
+#  endif
+  {
+    size_t i;
+
+    for (i = 0; i < ARRAY_SIZE(names); i++) {
+      if (1 << i == enumerator) {
+        return names[i];
+      }
+    }
+  }
 #else
-    return SPECENUM_STRING(SPECENUM_VALUE%d);
-#endif
-#endif /* SPECENUM_VALUE%d */
-'''%(i,i,i,i,i,i))
-        macros.append("SPECENUM_VALUE%dNAME"%i)
-
-    file.write('''
-#ifdef SPECENUM_COUNT
-  case SPECENUM_COUNT:
-#ifdef SPECENUM_COUNTNAME
-    return skip_intl_qualifier_prefix(SPECENUM_COUNTNAME);
-#else
-    return SPECENUM_STRING(SPECENUM_COUNT);
-#endif
-#endif /* SPECENUM_COUNT */
-  }
-
+  if (enumerator >= 0 && enumerator < ARRAY_SIZE(names)) {
+    return names[enumerator];
+  }
+#endif /* SPECENUM_BITWISE */
   return NULL;
 }
 ''')
+    macros.append("SPECENUM_COUNTNAME")
+    macros.append("SPECENUM_ZERONAME")
 
 def make_by_name(file):
     file.write('''
@@ -461,48 +514,73 @@
 static inline const char *
 SPECENUM_FOO(_translated_name)(enum SPECENUM_NAME enumerator)
 {
+#ifdef SPECENUM_COUNT
+  static const char *names[SPECENUM_SIZE + 1];
+#else
+  static const char *names[SPECENUM_SIZE];
+#endif
+  static bool initialized = FALSE;
+
 #ifdef SPECENUM_NAMEOVERRIDE
-  char *name = SPECENUM_FOO(_name_cb)(enumerator);
-
-  if (name != NULL) {
-    return Q_(name);
+  {
+    const char *name = SPECENUM_FOO(_name_cb)(enumerator);
+
+    if (name != NULL) {
+      return Q_(name);
+    }
   }
 #endif /* SPECENUM_NAMEOVERRIDE */
 
-  switch (enumerator) {
-#ifdef SPECENUM_ZERO
-  case SPECENUM_ZERO:
-#ifdef SPECENUM_ZERONAME
-    return Q_(SPECENUM_ZERONAME);
-#else
-    return SPECENUM_STRING(SPECENUM_ZERO);
-#endif
-#endif /* SPECENUM_ZERO */
-''')
+  if (!initialized) {''')
 
     for i in range(max_enum_values):
         file.write('''
-#ifdef SPECENUM_VALUE%d
-  case SPECENUM_VALUE%d:
-#ifdef SPECENUM_VALUE%dNAME
-    return Q_(SPECENUM_VALUE%dNAME);
+#if %d < SPECENUM_SIZE
+#  ifndef SPECENUM_VALUE%d
+     names[%d] = NULL;
+#  elif defined(SPECENUM_VALUE%dNAME)
+     names[%d] = Q_(SPECENUM_VALUE%dNAME);
+#  else
+     names[%d] = SPECENUM_STRING(SPECENUM_VALUE%d);
+#  endif
+#endif'''%(i,i,i,i,i,i,i,i))
+        macros.append("SPECENUM_VALUE%dNAME"%i)
+
+    file.write('''
+#ifdef SPECENUM_COUNT
+#  ifdef SPECENUM_COUNTNAME
+  names[SPECENUM_COUNT] = Q_(SPECENUM_COUNTNAME);
+#  else
+  names[SPECENUM_COUNT] = SPECENUM_STRING(SPECENUM_COUNT);
+#  endif
+#endif
+    initialized = TRUE;
+  }
+
+#ifdef SPECENUM_BITWISE
+#  ifdef SPECENUM_ZERO
+  if (enumerator == SPECENUM_ZERO) {
+#    ifdef SPECENUM_ZERONAME
+    return Q_(SPECENUM_ZERONAME);
+#    else
+    return SPECENUM_STRING(SPECENUM_ZERO);
+#    endif
+  }
+#  endif
+  {
+    size_t i;
+
+    for (i = 0; i < ARRAY_SIZE(names); i++) {
+      if (1 << i == enumerator) {
+        return names[i];
+      }
+    }
+  }
 #else
-    return SPECENUM_STRING(SPECENUM_VALUE%d);
-#endif
-#endif /* SPECENUM_VALUE%d */
-'''%(i,i,i,i,i,i))
-
-    file.write('''
-#ifdef SPECENUM_COUNT
-  case SPECENUM_COUNT:
-#ifdef SPECENUM_COUNTNAME
-    return Q_(SPECENUM_COUNTNAME);
-#else
-    return SPECENUM_STRING(SPECENUM_COUNT);
-#endif
-#endif /* SPECENUM_COUNT */
-  }
-
+  if (enumerator >= 0 && enumerator < ARRAY_SIZE(names)) {
+    return names[enumerator];
+  }
+#endif /* SPECENUM_BITWISE */
   return NULL;
 }
 ''')


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to