Thank you James, that inspired me!
If everything else fails, add one more level of indirection!
OK, so I took this idea and optimized it a little. This is best I can get in RobotC:
programs.h (to be edited):
#define PROGRAMS \
AUTO_PROGRAM("Sample", autoSample(50)) \
AUTO_PROGRAM("Sample 60", autoSample(60))
include/program-names.h (fixed, part of project template):
define AUTO_PROGRAM(name, code) \
name,
PROGRAMS
#undef AUTO_PROGRAM
include/program-dispatch.h (fixed, part of project template):
#define AUTO_PROGRAM(name, code) \
if (index-- == 0) { \
code; \
} else
PROGRAMS;
#undef AUTO_PROGRAM
Usage (in main.c):
#include "auto-programs.h"
// generated list of all declared autonomous programs
string programs] = {
#include "include/program-names.h"
};
task autonomous(){
// generated dispatch code for all declared autonomous
// programs, including the arguments
int index = autonomousProgramIndex;
#include "include/program-dispatch.h"
}
Now, when working towards this, I actually added one more level of indirection and had the following framework:
programs.h (user edited to add more programs):
define PROGRAMS(AUTO_PROGRAM) \
AUTO_PROGRAM("Sample", autoSample(50)) \
AUTO_PROGRAM("Sample 60", autoSample(60))
include/program-macros.h (fixed, part of project template):
#define _PROGRAM_DISPATCH(name, code) \
if (_index-- == 0) { \
code; \
} else
#define DISPATCH(indexVar) \
int _index = indexVar; \
PROGRAMS(_PROGRAM_DISPATCH)
#define _PROGRAM_NAME(name, code) \
name,
#define PROGRAM_NAMES PROGRAMS(_PROGRAM_NAME)
The usage is then very simple and intuitive:
#include "programs.h"
#include "include/program-macros.h"
// generated list of all declared autonomous programs
string programs] = { PROGRAM_NAMES };
void autonomous(){
// generated dispatch code for all declared autonomous programs with arguments
DISPATCH(autonomousProgramIndex);
}
But while the above works well with gcc’s preprocessor, RobotC doesn’t like it no matter how I slice it.
I have tried adding another level of indirection and plenty of other tricks, but RobotC either doesn’t evaluate the macro at all, or ends up complaining about wrong number of arguments somewhere.
Does anyone here see another trick that might get us close to this form in RobotC?