Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - alternative to #ifdef

I'm trying to streamline large chunk of legacy C code in which, even today, before doing the build guy who maintains it takes a source file(s) and manually modifies the following section before the compilation based on the various types of environment.

The example follows but here's the question. I'm rusty on my C but I do recall that using #ifdef is discouraged. Can you guys offer better alternative? Also - I think some of it (if not all of it) can be set as environment variable or passed in as a parameter and if so - what would be a good way of defining these and then accessing from the source code?

Here's snippet of the code I'm dealing with

#define DAN          NO
#define UNIX         NO
#define LINUX        YES
#define WINDOWS_ES   NO
#define WINDOWS_RB   NO

/* Later in the code */
#if ((DAN==1) || (UNIX==YES))
#include <sys/param.h>
#endif

#if ((WINDOWS_ES==YES) || (WINDOWS_RB==YES) || (WINDOWS_TIES==YES))
#include <param.h>
#include <io.h>
#include <ctype.h>
#endif

/* And totally insane harcoded paths */
#if (DAN==YES)
char MasterSkipFile[MAXSTR] = "/home/dp120728/tools/testarea/test/MasterSkipFile";
#endif

#if (UNIX==YES)
char MasterSkipFile[MAXSTR] = "/home/tregrp/tre1/tretools/MasterSkipFile";
#endif

#if (LINUX==YES)
char MasterSkipFile[MAXSTR] = "/ptehome/tregrp/tre1/tretools/MasterSkipFile";
#endif

/* So on for every platform and combination */
like image 264
Bostone Avatar asked Nov 27 '22 08:11

Bostone


2 Answers

Sure, you can pass -DWHATEVER on the command line. Or -DWHATEVER_ELSE=NO, etc. Maybe for the paths you could do something like

char MasterSkipFile[MAXSTR] = SOME_COMMAND_LINE_DEFINITION;

and then pass

-DSOME_COMMAND_LINE_DEFINITION="/home/whatever/directory/filename"

on the command line.

like image 120
Carl Norum Avatar answered Dec 15 '22 09:12

Carl Norum


One thing we used to do is have a generated .h file with these definitions, and generate it with a script. That helped us get rid of a lot of brittle #ifs and #ifdefs

You need to be careful about what you put there, but machine-specific parameters are good candidates - this is how autoconf/automake work.

EDIT: in your case, an example would be to use the generated .h file to define INCLUDE_SYS_PARAM and INCLUDE_PARAM, and in the code itself use:

#ifdef INCLUDE_SYS_PARAM
#include <sys/param.h>
#endif

#ifdef INCLUDE_PARAM
#include <param.h>
#endif

Makes it much easier to port to new platforms - the existence of a new platform doesn't trickle into the code, only to the generated .h file.

like image 44
orip Avatar answered Dec 15 '22 07:12

orip