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