24 /**************************************************************************
25 * THIS FILE WAS GENERATED *
26 * Script: utility/generate_specenum.py *
27 * DO NOT CHANGE THIS FILE *
28 **************************************************************************/
30 /* Copyright (c) 1996-2021 Freeciv21 and Freeciv
31 # ,_, contributors. This file is part of Freeciv21.
32 # (0_0)_----------_ Freeciv21 is free software: you can
33 # (_____) |~' redistribute it and/or modify it under the
34 # `-"-"-' / terms of the GNU General Public License
35 # `|__|~-----~|__| as published by the Free Software Foundation,
36 # either version 3 of the License,
37 # or (at your option) any later version. You should
38 # have received a copy of the GNU General Public License along
39 # with Freeciv21. If not, see https://www.gnu.org/licenses/.*/
45 * Include this file to define tools to manage enumerators. First of all,
46 * before including this file, you *MUST* define the following macros:
47 * - SPECENUM_NAME: is the name of the enumeration (e.g. 'foo' for defining
49 * - SPECENUM_VALUE%d: define like this all values of your enumeration type
50 * (e.g. '#define SPECENUM_VALUE0 FOO_FIRST').
52 * The following macros *CAN* be defined:
53 * - SPECENUM_INVALID: specifies a value that your 'foo_invalid()' function
54 * will return. Note it cannot be a declared value with SPECENUM_VALUE%d.
55 * - SPECENUM_BITWISE: defines if the enumeration should be like
56 * [1, 2, 4, 8, etc...] instead of the default of [0, 1, 2, 3, etc...].
57 * - SPECENUM_ZERO: can be defined only if SPECENUM_BITWISE was also defined.
58 * It defines a 0 value. Note that if you don't declare this value, 0 passed
59 * to the 'foo_is_valid()' function will return 0.
60 * - SPECENUM_COUNT: a name for the maximum enumeration number plus 1. For
61 * enums where every element from 0 to the maximum is defined, this is the
62 * number of elements in the enum. This value is suitable to size an array
63 * indexed by the enum. It can not be used in combination with
64 * SPECENUM_BITWISE. SPECENUM_is_valid() will return the invalid element
67 * SPECENUM_VALUE%dNAME, SPECENUM_ZERONAME, SPECENUM_COUNTNAME: Can be used
68 * to bind a string to the particular enumerator to be returned by
69 * SPECENUM_name(), etc. If not defined, the default name for 'FOO_FIRST'
70 * is '"FOO_FIRST"'. A name can be qualified. The qualification will only
71 * be used for its translation. The returned name will be unqualified. To
72 * mark a name as translatable use N_().
74 * SPECENUM_NAMEOVERRIDE: call callback function foo_name_cb(enum foo),
75 * defined by specnum user, to get name of the enum value. If the function
76 * returns NULL, compiled in names are used.
78 * SPECENUM_BITVECTOR: specifies the name of a bit vector for the enum
79 * values. It can not be used in combination with SPECENUM_BITWISE.
81 * Assuming SPECENUM_NAME were 'foo', including this file would provide
82 * the definition for the enumeration type 'enum foo', and prototypes for
83 * the following functions:
84 * bool foo_is_bitwise(void);
85 * enum foo foo_min(void);
86 * enum foo foo_max(void);
87 * enum foo foo_invalid(void);
88 * bool foo_is_valid(enum foo);
90 * enum foo foo_begin(void);
91 * enum foo foo_end(void);
92 * enum foo foo_next(enum foo);
94 * const char *foo_name(enum foo);
95 * const char *foo_translated_name(enum foo);
96 * enum foo foo_by_name(const char *name,
97 * int (*strcmp_func)(const char *, const char *));
100 * #define SPECENUM_NAME test
101 * #define SPECENUM_BITWISE
102 * #define SPECENUM_VALUE0 TEST0
103 * #define SPECENUM_VALUE1 TEST1
104 * #define SPECENUM_VALUE3 TEST3
105 * #include "specenum_gen.h"
108 * static const char *strings[] = {
109 * "TEST1", "test3", "fghdf", NULL
114 * qDebug("enum test [%d; %d]%s",
115 * test_min(), test_max(), test_bitwise ? " bitwise" : "");
117 * for (e = test_begin(); e != test_end(); e = test_next(e)) {
118 * qDebug("Value %d is %s", e, test_name(e));
121 * for (i = 0; strings[i]; i++) {
122 * e = test_by_name(strings[i], mystrcasecmp);
123 * if (test_is_valid(e)) {
124 * qDebug("Value is %d for %s", e, strings[i]);
126 * qDebug("%s is not a valid name", strings[i]);
132 * enum test [1, 8] bitwise
136 * Value is 2 for TEST1
137 * Value is 8 for test3
138 * fghdf is not a valid name
147 #include "fcintl.h" // translation
148 #include "log.h" // fc_assert
149 #include "shared.h" // ARRAY_SIZE
151 #ifndef SPECENUM_NAME
152 #error Must define a SPECENUM_NAME to use this header
155 #define SPECENUM_PASTE_(x, y) x ## y
156 #define SPECENUM_PASTE(x, y) SPECENUM_PASTE_(x, y)
158 #define SPECENUM_STRING_(x) #x
159 #define SPECENUM_STRING(x) SPECENUM_STRING_(x)
161 #define SPECENUM_FOO(suffix) SPECENUM_PASTE(SPECENUM_NAME, suffix)
163 #ifndef SPECENUM_INVALID
164 #define SPECENUM_INVALID ((enum SPECENUM_NAME) -1)
167 #ifdef SPECENUM_BITWISE
168 #ifdef SPECENUM_COUNT
169 #error Cannot define SPECENUM_COUNT when SPECENUM_BITWISE is defined.
171 #define SPECENUM_VALUE(value) (1 << value)
172 #else /* SPECENUM_BITWISE */
174 #error Cannot define SPECENUM_ZERO when SPECENUM_BITWISE is not defined.
176 #define SPECENUM_VALUE(value) (value)
177 #endif /* SPECENUM_BITWISE */
179 #ifdef SPECENUM_BITVECTOR
180 #include "bitvector.h"
181 #ifdef SPECENUM_BITWISE
182 #error SPECENUM_BITWISE and SPECENUM_BITVECTOR cannot both be defined.
183 #endif /* SPECENUM_BITWISE */
184 #endif /* SPECENUM_BITVECTOR */
186 #undef SPECENUM_MIN_VALUE
187 #undef SPECENUM_MAX_VALUE
189 macros.append(
"SPECENUM_NAME")
190 macros.append(
"SPECENUM_PASTE_")
191 macros.append(
"SPECENUM_PASTE")
192 macros.append(
"SPECENUM_STRING_")
193 macros.append(
"SPECENUM_STRING")
194 macros.append(
"SPECENUM_FOO")
195 macros.append(
"SPECENUM_INVALID")
196 macros.append(
"SPECENUM_BITWISE")
197 macros.append(
"SPECENUM_VALUE")
198 macros.append(
"SPECENUM_ZERO")
199 macros.append(
"SPECENUM_MIN_VALUE")
200 macros.append(
"SPECENUM_MAX_VALUE")
201 macros.append(
"SPECENUM_SIZE")
202 macros.append(
"SPECENUM_NAMEOVERRIDE")
203 macros.append(
"SPECENUM_BITVECTOR")
207 /* Enumeration definition. */
214 for i
in range(max_enum_values):
216 #ifdef SPECENUM_VALUE%d
217 SPECENUM_VALUE%d = SPECENUM_VALUE(%d),
218 # ifndef SPECENUM_MIN_VALUE
219 # define SPECENUM_MIN_VALUE SPECENUM_VALUE%d
221 # ifdef SPECENUM_MAX_VALUE
222 # undef SPECENUM_MAX_VALUE
224 # define SPECENUM_MAX_VALUE SPECENUM_VALUE%d
225 # ifdef SPECENUM_SIZE
226 # undef SPECENUM_SIZE
228 # define SPECENUM_SIZE (%d + 1)
229 #endif /* SPECENUM_VALUE%d */
233 #ifdef SPECENUM_COUNT
234 SPECENUM_COUNT = (SPECENUM_MAX_VALUE + 1),
235 #endif /* SPECENUM_COUNT */
239 macros.append(
"SPECENUM_COUNT")
240 for i
in range(max_enum_values):
241 macros.append(
"SPECENUM_VALUE%d"%i)
245 /**************************************************************************
246 Returns TRUE if this enumeration is in bitwise mode.
247 **************************************************************************/
248 fc__attribute((const))
249 static inline bool SPECENUM_FOO(_is_bitwise)(void)
251 #ifdef SPECENUM_BITWISE
261 /**************************************************************************
262 Returns the value of the minimal enumerator.
263 **************************************************************************/
264 fc__attribute((const))
265 static inline enum SPECENUM_NAME SPECENUM_FOO(_min)(void)
267 return SPECENUM_MIN_VALUE;
273 /**************************************************************************
274 Returns the value of the maximal enumerator.
275 **************************************************************************/
276 fc__attribute((const))
277 static inline enum SPECENUM_NAME SPECENUM_FOO(_max)(void)
279 return SPECENUM_MAX_VALUE;
285 /**************************************************************************
286 Returns TRUE if this enumerator was defined.
287 **************************************************************************/
288 fc__attribute((const))
289 static inline bool SPECENUM_FOO(_is_valid)(enum SPECENUM_NAME enumerator)
291 #ifdef SPECENUM_BITWISE
292 static const unsigned long valid = (
295 for i
in range(max_enum_values):
297 # ifdef SPECENUM_VALUE%d
304 FC_STATIC_ASSERT(sizeof(valid) * 8 >= SPECENUM_SIZE,
307 # ifdef SPECENUM_ZERO
308 if (enumerator == SPECENUM_ZERO) {
312 return (enumerator & valid) == enumerator;
314 static const bool valid[] = {''')
316 for i
in range(max_enum_values):
318 # if %d < SPECENUM_SIZE
319 # ifdef SPECENUM_VALUE%d
329 FC_STATIC_ASSERT(ARRAY_SIZE(valid) == SPECENUM_SIZE,
330 valid_array_size_check);
332 return (enumerator >= 0 && enumerator < ARRAY_SIZE(valid)
333 && valid[enumerator]);
334 #endif /* SPECENUM_BITWISE */
340 /**************************************************************************
341 Returns an invalid enumerator value.
342 **************************************************************************/
343 fc__attribute((const))
344 static inline enum SPECENUM_NAME SPECENUM_FOO(_invalid)(void)
346 fc_assert(!SPECENUM_FOO(_is_valid(SPECENUM_INVALID)));
347 return SPECENUM_INVALID;
353 /**************************************************************************
354 Beginning of the iteration of the enumerators.
355 **************************************************************************/
356 fc__attribute((const))
357 static inline enum SPECENUM_NAME SPECENUM_FOO(_begin)(void)
359 return SPECENUM_FOO(_min)();
365 /**************************************************************************
366 End of the iteration of the enumerators.
367 **************************************************************************/
368 fc__attribute((const))
369 static inline enum SPECENUM_NAME SPECENUM_FOO(_end)(void)
371 return SPECENUM_FOO(_invalid)();
377 /**************************************************************************
378 Find the next valid enumerator value.
379 **************************************************************************/
380 fc__attribute((const))
381 static inline enum SPECENUM_NAME SPECENUM_FOO(_next)(enum SPECENUM_NAME e)
384 #ifdef SPECENUM_BITWISE
385 e = (enum SPECENUM_NAME)(e << 1);
387 e = (enum SPECENUM_NAME)(e + 1);
390 if (e > SPECENUM_FOO(_max)()) {
391 /* End of the iteration. */
392 return SPECENUM_FOO(_invalid)();
394 } while (!SPECENUM_FOO(_is_valid)(e));
402 #ifdef SPECENUM_NAMEOVERRIDE
403 const char *SPECENUM_FOO(_name_cb)(enum SPECENUM_NAME value);
404 #endif /* SPECENUM_NAMEOVERRIDE */
406 /**************************************************************************
407 Returns the name of the enumerator.
408 **************************************************************************/
409 #ifndef SPECENUM_NAMEOVERRIDE
410 fc__attribute((const))
412 static inline const char *SPECENUM_FOO(_name)(enum SPECENUM_NAME enumerator)
414 #ifdef SPECENUM_COUNT
415 static const char *names[SPECENUM_SIZE + 1];
417 static const char *names[SPECENUM_SIZE];
419 static bool initialized = false;
421 #ifdef SPECENUM_NAMEOVERRIDE
423 const char *name = SPECENUM_FOO(_name_cb)(enumerator);
429 #endif /* SPECENUM_NAMEOVERRIDE */
431 if (!initialized) {''')
433 for i
in range(max_enum_values):
435 #if %d < SPECENUM_SIZE
436 # ifndef SPECENUM_VALUE%d
438 # elif defined(SPECENUM_VALUE%dNAME)
439 names[%d] = Qn_(SPECENUM_VALUE%dNAME);
441 names[%d] = SPECENUM_STRING(SPECENUM_VALUE%d);
443 #endif'''%(i,i,i,i,i,i,i,i))
444 macros.append(
"SPECENUM_VALUE%dNAME"%i)
447 #ifdef SPECENUM_COUNT
448 # ifdef SPECENUM_COUNTNAME
449 names[SPECENUM_COUNT] = Qn_(SPECENUM_COUNTNAME);
451 names[SPECENUM_COUNT] = SPECENUM_STRING(SPECENUM_COUNT);
457 #ifdef SPECENUM_BITWISE
458 # ifdef SPECENUM_ZERO
459 if (enumerator == SPECENUM_ZERO) {
460 # ifdef SPECENUM_ZERONAME
461 return Qn_(SPECENUM_ZERONAME);
463 return SPECENUM_STRING(SPECENUM_ZERO);
470 for (i = 0; i < ARRAY_SIZE(names); i++) {
471 if (1 << i == enumerator) {
477 if (enumerator < ARRAY_SIZE(names)) {
478 return names[enumerator];
480 #endif /* SPECENUM_BITWISE */
484 macros.append(
"SPECENUM_COUNTNAME")
485 macros.append(
"SPECENUM_ZERONAME")
489 /**************************************************************************
490 Returns the enumerator for the name or *_invalid() if not found.
491 **************************************************************************/
492 static inline enum SPECENUM_NAME SPECENUM_FOO(_by_name)
493 (const char *name, int (*strcmp_func)(const char *, const char *))
495 enum SPECENUM_NAME e;
496 const char *enum_name;
498 for (e = SPECENUM_FOO(_begin)(); e != SPECENUM_FOO(_end)();
499 e = SPECENUM_FOO(_next)(e)) {
500 if ((enum_name = SPECENUM_FOO(_name)(e))
501 && 0 == strcmp_func(name, enum_name)) {
506 return SPECENUM_FOO(_invalid)();
512 /**************************************************************************
513 Returns the translated name of the enumerator.
514 **************************************************************************/
515 #ifndef SPECENUM_NAMEOVERRIDE
516 fc__attribute((const))
518 static inline const char *
519 SPECENUM_FOO(_translated_name)(enum SPECENUM_NAME enumerator)
521 #ifdef SPECENUM_COUNT
522 static const char *names[SPECENUM_SIZE + 1];
524 static const char *names[SPECENUM_SIZE];
526 static bool initialized = false;
528 #ifdef SPECENUM_NAMEOVERRIDE
530 const char *name = SPECENUM_FOO(_name_cb)(enumerator);
536 #endif /* SPECENUM_NAMEOVERRIDE */
538 if (!initialized) {''')
540 for i
in range(max_enum_values):
542 #if %d < SPECENUM_SIZE
543 # ifndef SPECENUM_VALUE%d
545 # elif defined(SPECENUM_VALUE%dNAME)
546 names[%d] = Q_(SPECENUM_VALUE%dNAME);
548 names[%d] = SPECENUM_STRING(SPECENUM_VALUE%d);
550 #endif'''%(i,i,i,i,i,i,i,i))
551 macros.append(
"SPECENUM_VALUE%dNAME"%i)
554 #ifdef SPECENUM_COUNT
555 # ifdef SPECENUM_COUNTNAME
556 names[SPECENUM_COUNT] = Q_(SPECENUM_COUNTNAME);
558 names[SPECENUM_COUNT] = SPECENUM_STRING(SPECENUM_COUNT);
564 #ifdef SPECENUM_BITWISE
565 # ifdef SPECENUM_ZERO
566 if (enumerator == SPECENUM_ZERO) {
567 # ifdef SPECENUM_ZERONAME
568 return Q_(SPECENUM_ZERONAME);
570 return SPECENUM_STRING(SPECENUM_ZERO);
577 for (i = 0; i < ARRAY_SIZE(names); i++) {
578 if (1 << i == enumerator) {
584 if (enumerator < ARRAY_SIZE(names)) {
585 return names[enumerator];
587 #endif /* SPECENUM_BITWISE */
594 #ifdef SPECENUM_BITVECTOR
595 BV_DEFINE(SPECENUM_BITVECTOR, (SPECENUM_MAX_VALUE + 1));
596 #endif /* SPECENUM_BITVECTOR */
609 target_name=sys.argv[1]
611 output=open(target_name,
"w")
def make_is_bitwise(file)
def make_translated_name(file)
def make_documentation(file)