diff options
Diffstat (limited to 'Build/source/texk/gregorio/gregorio-src/src/enum_generator.h')
-rw-r--r-- | Build/source/texk/gregorio/gregorio-src/src/enum_generator.h | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/Build/source/texk/gregorio/gregorio-src/src/enum_generator.h b/Build/source/texk/gregorio/gregorio-src/src/enum_generator.h new file mode 100644 index 00000000000..e6c6ae1049e --- /dev/null +++ b/Build/source/texk/gregorio/gregorio-src/src/enum_generator.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2006-2015 The Gregorio Project (see CONTRIBUTORS.md) + * + * This file is part of Gregorio. + * + * Gregorio is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Gregorio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Gregorio. If not, see <http://www.gnu.org/licenses/>. + */ + +/* These macros are used for generating enum code. This is based on the + * technique described in http://stackoverflow.com/a/202511 + * + * Two of these macros are meant for use outside this set of macros: + * + * - ENUM declares the enum itself and a prototype for the function that + * returns the string value of the enum's numeric value. This is meant to be + * used from a header file. + * - ENUM_TO_STRING defines the function whose prototype was declared by ENUM. + * This is meant to be used from a code file. + * + * These two macros both take the following two arguments: + * + * - TYPE is the name to use for the enum. + * - DEF is the name of a macro that generates the bodies of the enum and the + * to-string function. DEF should take four arguments, in the following + * order (with suggested names): + * - A is a macro that generates an enum value with a specifiec numeric + * value. It takes two arguments, the name and the numeric value. + * - E is a macro that generates an enum value that has no specific numeric + * value. It takes one argument, the name. + * - X is a macro that generates the last enum value when it has a specific + * numeric value. It takes the same two arguments as A. + * - L is a macro that generates the last enum value when it has no specific + * numeric value. It takes the same argument as E. + * + * Note: If we were supporting C11, we could take empty macro arguments and + * would be able to get away with only two arguments to DEF. + */ + +#ifndef ENUM_GENERATOR_H +#define ENUM_GENERATOR_H + +/* for enum values */ +#define ENUM_VALUE(NAME,VALUE) NAME = VALUE, +#define ENUM_ENTRY(NAME) NAME, +#define ENUM_LAST_VALUE(NAME,VALUE) NAME = VALUE +#define ENUM_LAST_ENTRY(NAME) NAME + +/* for enum case */ +#define ENUM_VALUE_CASE(NAME,VALUE) case NAME: return #NAME; +#define ENUM_ENTRY_CASE(NAME) case NAME: return #NAME; + +/* enum declaration */ +#define ENUM(TYPE,DEF) \ + typedef enum TYPE { \ + DEF(ENUM_VALUE, ENUM_ENTRY, ENUM_LAST_VALUE, ENUM_LAST_ENTRY) \ + } TYPE; \ + const char *TYPE##_to_string(TYPE value) + +/* enum *_to_string function defintiion */ +#define ENUM_TO_STRING(TYPE,DEF) \ + const char *TYPE##_to_string(TYPE value) \ + { \ + switch(value) { \ + DEF(ENUM_VALUE_CASE, ENUM_ENTRY_CASE, ENUM_VALUE_CASE, ENUM_ENTRY_CASE) \ + default: return gregorio_unknown(value); \ + } \ + } + +#endif |