Reputation: 434
As part of my homework, I've been given this code to help with the task they've given us... to create a basic shell that supports piping, background processes, and a number of builtin commands, etc. I've read through the code they've given us for parsing...
I'm familiar with the #define
keyword in C, however, I've not seen it used like in the below code: namely, what is c
for? I'm guessing it has been assigned to mean a character but I'm not sure:
#define PIPE ('|')
#define BG ('&')
#define RIN ('<')
#define RUT ('>')
#define ispipe(c) ((c) == PIPE)
#define isbg(c) ((c) == BG)
#define isrin(c) ((c) == RIN)
#define isrut(c) ((c) == RUT)
#define isspec(c) (ispipe(c) || isbg(c) || isrin(c) || isrut(c))
Any help or advice much appreciated.
Upvotes: 0
Views: 285
Reputation: 198294
#define
is not a function, it is a preprocessor directive.
c
could be anything. If you write ispipe(42)
, then the preprocessor will change it into ((42) == PIPE)
. If you write ispipe(while(1);)
, then the preprocessor will change it into ((while(1);) == PIPE)
, which will dumbfound the compiler when it reads it.
The preprocessor is blind, and does not know much about C syntax, and nothing of its semantics; the only way to understand what c
is supposed to be is either to reverse-engineer the intended usage, or to ask whoever wrote the code without comments to tell you what they meant.
After the edit, it is rather reasonable to expect that c
should be a char
, in order to be meaningfully compared to '|'
and similar. But even passing 0xDEADBEEF
should compile correctly (returning FALSE
).
Upvotes: 3
Reputation: 51815
The last five #define
statements you give define macros, each taking an argument, which is here always called c
. Your first four #define
statements are also, technically, macros, but they don't need an argument - they are simply substituted for their 'values' when encountered; frequently, programmers refer to macros with no argument as tokens, with the PIPE
token here having a token value of ('|')
.
Later on in the file (possibly) there will be cases where one or more of these macros is called, and that call will have a value for the actual argument, like this, for example:
if (ispipe(test_arg)) ++npipes;
This macro "call" will be replaced (by the pre-processor) with the following expansion:
if (((test) == ('|')) ++npipes;
And, similarly, for the other #define XXX(c) macros.
Note: It is quite common to add (lots of) parentheses in macro definitions, just to be sure that the code does what you 'think' it will after the pre-processor has done its stuff.
Feel free to ask for further explanation and/or clarification.
Upvotes: 4