К сожалению openwatcom реально стар. Это код для условно современного C-компилятора, поддерживающего C99. У openwatcom не полнофункциональный макро-процесор -- это самая большая проблема. К тому же он C89, а не C99 (невозможны декларации переменных кроме как в начале блока). Для старого компилятора можно переписать примерно вот так:
#include <stdio.h>
#define _CONCAT(a, b) a##b
#define CONCAT(a, b) _CONCAT(a, b)
#define _NARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9_, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, N, ...) N
#define NARG(...) _NARG(__VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define _MAP1(F, x, ...) F(x)
#define _MAP2(F, x, ...) F(x) _MAP1(F, __VA_ARGS__)
#define _MAP3(F, x, ...) F(x) _MAP2(F, __VA_ARGS__)
#define _MAP4(F, x, ...) F(x) _MAP3(F, __VA_ARGS__)
#define _MAP5(F, x, ...) F(x) _MAP4(F, __VA_ARGS__)
#define _MAP6(F, x, ...) F(x) _MAP5(F, __VA_ARGS__)
#define _MAP7(F, x, ...) F(x) _MAP6(F, __VA_ARGS__)
#define _MAP8(F, x, ...) F(x) _MAP7(F, __VA_ARGS__)
#define _MAP9(F, x, ...) F(x) _MAP8(F, __VA_ARGS__)
#define _MAP10(F, x, ...) F(x) _MAP9(F, __VA_ARGS__)
#define _MAP11(F, x, ...) F(x) _MAP10(F, __VA_ARGS__)
#define _MAP12(F, x, ...) F(x) _MAP11(F, __VA_ARGS__)
#define _MAP13(F, x, ...) F(x) _MAP12(F, __VA_ARGS__)
#define _MAP14(F, x, ...) F(x) _MAP13(F, __VA_ARGS__)
#define _MAP15(F, x, ...) F(x) _MAP14(F, __VA_ARGS__)
#define _MAP16(F, x, ...) F(x) _MAP15(F, __VA_ARGS__)
#define _MAP17(F, x, ...) F(x) _MAP16(F, __VA_ARGS__)
#define _MAP18(F, x, ...) F(x) _MAP17(F, __VA_ARGS__)
#define _MAP19(F, x, ...) F(x) _MAP18(F, __VA_ARGS__)
#define _MAP20(F, x, ...) F(x) _MAP19(F, __VA_ARGS__)
#define MAP(F, ...) CONCAT(_MAP, NARG(__VA_ARGS__))(F, __VA_ARGS__)
#define CASE_STRINGIFY(v) case v: return #v;
#define SUPER_ENUM(_name_, ...) \
typedef enum _name_ { __VA_ARGS__ } _name_; \
const char *_name_##_tostr(const _name_ *_v_) { \
switch (*_v_) { \
MAP(CASE_STRINGIFY, __VA_ARGS__); \
default: return "unknown"; \
} \
}
/* Hint: add option "-E" to command line (at bottom of page) and
* press "Compile..." to see the code after unwinding macro. */
SUPER_ENUM(Numbers, zero, first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth)
SUPER_ENUM(Colors, red, green, blue)
int main()
{
Numbers i;
Colors c = red;
for (i = zero; i<= tenth; i++)
printf("%-3d", i), puts(Numbers_tostr(&i));
puts(Colors_tostr(&c));
puts(Numbers_tostr(&c)); // this gives only warning
return 0;
}
Отдельно нужно ещё сказать про Visual Studio. Она тоже не может, тоже по причине, что у ней собственное представление об работе макропроцессора. Она раскрывает аргументы в другом порядке (за деталями в google...), исправить под студию можно, но это разумеется не совместимо с нормальными компипляторами.
Да, по сборке openwatcom: брать отсюда (
https://github.com …com/open-watcom-v2.git), потом поставить dosbox, потом export OWDOSBOX=/usr/bin/dosbox и ./build.sh. Потом ./bld/cc/386/linuxx64/binbuild/wcc386.exe -I./bld/hdr/linux source.c