Here's the thing:
Let's say I have two function defined in C:
test_1() {};
test_2() {};
I would like to have a macro (e.g. NUM_TEST) that will refer to test number. Best way is to show it in code:
#define NUM_TEST 1
test_1() {};
test_2() {};
int main() {
test_ ## NUM_TEST ## ()
}
I would appreciate, if someone would help, to find a solution, how to concat name of function with macro.
EDIT:
To make it more clear. I would like to just by changing of "macro NUM_TEST" change invoked function between test_1() and test_2().
Yes I know there are more easier ways to do that, but this is just an example to more general problem: How to concat macro with text in C without adding new lines or new macro functions.
EDIT 2:
Obviously I was now clear enough. Let's say I wrote a program. It has two (or more) run types. I have one macro called NUM_TEST. By setting mentioned macro to 1 or 2 a want to choose run type between test_1() or test_2()
Thank you!
Is this what you're looking for?
#include <stdio.h>
#define TEST(NUM) test_ ## NUM ()
test_1() { printf ("Hello "); }
test_2() { printf ("World!\n"); }
int main (void)
{
TEST(1);
TEST(2);
// Prints "Hello World!\n"
return 0;
}
Rather than creating a Macro that determines this, it is better to just pass command line argument to it which represents the test number. Like this:
#include <stdio.h>
int main( int argc, char *argv[] )
{
switch(argv[1])
{
case "1" :
Test_1();
break;
case "2" :
Test_2();
break;
default :
printf("Test ID not found");
}
}
If you are, however, just looking to alias a name, you can have your functions Test_1, Test_2, etc. Then just have a generic TESTTORUN wherever you want the selected test to run. On compilation have the preprocessor replace it with the function name you want:
#define TESTTORUN Test_1 //Or Test_2 or whatever
This will cause the compiler to replace TESTTORUN everywhere in the program with Test_1.
Related
I want to pass values to the macro through for loop,but when i try to pass values it gives error, please help m as fast as possible. When values of i are passed to macro as Valve(i) it gives error
my code given below:
#define Valve(x) stTest.bValve##x##_Cmd
typedef struct OperationFlags
{
int bValve1_Cmd;
int bValve2_Cmd;
}FLAGS_TypeDef;
void main(void)
{
FLAGS_TypeDef stTest;
int j,i;
stTest.bValve1_Cmd = 4;
stTest.bValve2_Cmd = 9;
for(i=1;i<=2;i++)
{
j=Valve(1);
printf("%d",j);
}
}
It is normal!
The preprocessor (the "thing" that processes the macros) is run BEFORE the C compiler. So, it is only valid when it produces compilable code.
In your case, if you use the code you show
j=Valve(1)
it will work for that value, since it will produce:
j=stTest.bValve1_Cmd
but it will do the entire loop only with that value.
When you change the parameter "1" with the "i" for actually doing the loop, then it will produce:
j=stTest.bValvei_Cmd
which is invalid.
To do what you want, just use a vector:
typedef struct OperationFlags
{
int bValve_Cmd[2];
}FLAGS_TypeDef;
#define Valve(x) stTest.bValve_Cmd[x]
//....
for(i=1;i<=2;i++)
{
j=Valve(1);
printf("%d",j);
}
Macro replacement is done well before runtime, so you cannot use a variable X containing the value 2 to get stTest.bValve2_Cmd. Instead, you will get stTest.bValveX_Cmd, for which no symbol exists.
You will have to find another way of doing this, such as having an array of values for which you can use X to select:
#define Valve(x) stTest.bValveX_Cmd[x]
typedef struct OperationFlags {
int bValveX_Cmd[2];
} FLAGS_TypeDef;
try this #define Valve(x) (x == 1 ? stTest.bValve1_Cmd : stTest.bValve2_Cmd)
#define Valve(x) (*(&stTest.bValve1_Cmd + (x-1)))
note : It may not work if the environment changes. Also it can not be used in the bit field.
add check
#define Valve(x) (*(&stTest.bValve1_Cmd + (x-1))); \
assert(offsetof(FLAGS_TypeDef, bValve2_Cmd) == sizeof(int))
Is it possible to silence a function?
For example:
#include <stdio.h>
int function(){
printf("BLAH!");
return 10;
}
int main(){
printf("%d", silence( function()) );
return 0;
}
And instead of:
BLAH!
10
I would get:
10
Is it possible? If positive how to do it?
An awfully complicated way to do almost what you want is to use the dup2() system call. This requires executing fflush(stdout); dup2(silentfd, stdout); before function() is called, and copying back afterwards: fflush(stdout); dup2(savedstdoutfd, stdout);. So it is not possible to do as just silence(function()), since this construct only allows to execute code after function() has already been executed.
The file descriptors silentfd and savedstdoutfd have to be prepared in advance (untested code):
int silentfd = open("/dev/null",O_WRONLY);
int savedstdoutfd = dup(stdout);
This is almost certainly not what you really want, but inasmuch as your question is phrased as “is it possible?”, the answer is “almost”.
use macro function and null device.
E.g. for windows
#include <stdio.h>
#define silence(x) (_stream = freopen("NUL:", "w", stdout), _ret_value = x,_stream = freopen("CON:", "w", stdout),_ret_value)
int _ret_value;
FILE *_stream;
int function(){
printf("BLAH!");
return 10;
}
int main(void){
printf("%d", silence( function()) );
return 0;
}
No its not possible. You could however try to temporarily redirect the stdout to something else. That may come close to what you want.
You can use this macro instead of printf to be able to prevent printing:
int flag=0;
#define PRINT(...) if(flag){printf(...)}
then use PRINT macro by considering the variable flag. If flag==1, the function will print and if flag==0, the function will not print.
With GCC extensions, you might consider having macros like
bool silent;
#define silence(X) ({int _x; quiet(); _x = (X); verbose(); _x; })
#define printf(Fmt,...) \
do{if (!silent) printf(Fmt,##__VA_ARGS__);}while(0)
that silence macro would work only if its argument X is a int expression (or use typeof) I also assume that the result of printf is never used. Recall that "recursive" macros are specially pre-processed, the inside occurrence of printf (in that printf macro) is left verbatim without macro-expansion.
Notice that silence cannot be a function (otherwise, its argument would have been evaluated before calling it). And you need GCC statement expressions extension to "remember" the result of the argument in some variable _x (you could generate that name using __COUNTER__ and preprocessor concatenation), to give it back as the value of silence macro invocation.
Then you need to define your functions quiet() and verbose(), perhaps something like
void quiet()
{
silent = true;
}
void verbose()
{
silent = false,
}
if you don't want to define printf as your macro, you could use freopen(3) on stdout (perhaps with "/dev/null" etc...) or do dup2(2) tricks (like suggested by Pascal Cuoq).
If your code base is huge, and you want something more serious and are willing to spend days or weeks of work, consider customizing your GCC compiler with a plugin or a MELT extension (or ask someone to do it). Notice that printf is known to GCC.
In reality, you should define your own macro like
#define myprintf(Fmt, ...) do{if (!silent) \
printf(Fmt,__VA_ARGS__);}while(0)
and just use myprintf instead of printf everywhere, this is a portable trick. Of course, I assume you are not passing printf as a function pointer.
For debugging, I actually recommend
#define dbgprintf(Fmt,...) do{if (wantdebug) \
printf("%s:%d:" Fmt "\n", __FILE__, __LINE__, \
##__VA_ARGS__);}while(0)
and then I use dbgprintf("i=%d",i) or simply dbgprintf("foo here") in my code.
I'm using ##__VA_ARGS__ which is a GCC extension to accept no variable arguments to a variadic macro. If you want strict C99, you will just say __VA_ARGS__ and every dbgprintf would need one argument after the format.
You could also re-implement your own printf function, but I don't advise doing that.
(Notice that things could be more complex, you can print using fputs not printf ....)
If you're designing the function do the following:
int function(void (*printer)(char *)){
if (!printer)
printer = printf;
printer("BLAH!");
return 10;
}
void silence(char *s){
return;
}
int main(int argc, char **argv){
printf("%d\n", function(silence));
return 0;
}
That should do what you're looking for. Unfortunately, I didn't test it and my C is probably a little bit rusty.
Of course if function isn't something you have control over, the answers already posted are all correct solutions.
Actually, if you're designing the function yourself, just do:
int function(int print){
if (print)
printf("BLAH!");
return 10;
}
function(0); /* Won't print anything */
function(!0); /* Will print "BLAH!" */
because 0 is false and any non-zero (or !0) value is true. My above suggestion is error prone since you'll have to be able to mimic the printf signature for silence or for any other function you wish to use.
Unfortunately if you have the function explicitly printing and call it like this then it will always print. if you want to silence the function completely you could simply comment out that line.You could even use a control statement so that it only prints IF and when a condition is met otherwise it stays blank and only returns the number.
I have some 20 to 30 functions, i have to call wsse_authenticate, in ever function for, and this wsse_authenticate function returns a value based on that value i send the fault message, Is there any way i can improve this code, so that i just call the function wsse_authenticate(soap) in every function and the switch case be replaced by some better code, i want to make it much efficient, Pls give me some inputs
wsse_ret = (wsse_authenticate(soap));
if(wsse_ret)
{
switch(wsse_ret)
{
case 1: onvif_fault(soap,"ter:NoSecuritytoken","ter:Failed_wsse_Aunthentication");
case 2: onvif_fault(soap,"ter:InvalidUserName","ter:FailedAunthentication");
case 3: onvif_fault(soap,"ter:InvalidPassword","ter:FailedAunthentication");
}
}
From the above code, I see that you are calling same function for all the cases expect for the "failure message" passed as an argument to function onvif_fault. And also there is no break after each case statement which would not give you result as expected.
Explanation for using break statement:
Suppose ret value is 1, then all the three cases would be executed since there is break statement at the end. Which means onvif_fault will be called three times with different parameters which is not expected.
Solution for you question
You can create a table using structures in c which actually has the list of the faults.
This was you can replace your Switch statements with only one line of code.
EX:
typedef struct _fault_messages
{
char msg1[254];
char msg2[254];
} fault_messages;
fault_messages msg_table[3] = {
{"ter:NoSecuritytoken", "ter:Failed_wsse_Aunthentication"},
{"ter:error1", "ter:fault1"},
{"ter:error2", "ter:fault2"}
};
Now, your fault messages in the above table are mapped. You can optimize your code as mentioned below:
wsse_ret = (wsse_authenticate(soap));
if(wsse_ret)
{
onvif_fault(soap, msg_table[wsse_ret-1].msg1, msg_table[wsse_ret-1].msg2);
}
If I understood correctly - your main problem is that you don't want to repeat security checking code in each and every function from 30 function set :-)
If that is the case you can try to use such pattern:
#include <stdio.h>
#include <string.h>
int isUserPasswordValid(char * password) {
return strcmp(password, "MyBigPassword") == 0;
}
#define callFunctionWithAuthentication(password, secPayload, execPayload) \
do {\
if (!isUserPasswordValid(password)) {\
secPayload\
}\
else {\
execPayload\
}\
} while(0);
int myTestFunction(int x) {
return x;
}
int main(int argc,char* argv[]){
// bad password - executes only authentication
callFunctionWithAuthentication(
"randomPassword",
printf("oops - bad password - can't continue\n");,
int a = myTestFunction(10); printf("function returned %d\n",a);)
// good password - executes authentication AND code after
callFunctionWithAuthentication(
"MyBigPassword",
printf("oops - bad password - can't continue\n");,
int a = myTestFunction(10); printf("function returned %d\n",a);)
return 0;
}
Only drawback that you must replace the call of each 30 function into the call of callFunctionWithAuthentication. But this is one-time task. Further you must always call this macro instead of plain function.
While adapting some given interface, I came across the problem of extending the use of a header file with a lot of #defines.
What I have is something like this:
#define STATUS_OK 0x00
#define STATUS_FAIL 0x01
#define STATUS_WAIT 0x02
#define STATUS_ILLEGAL 0x03
#define STATUS_FULL 0x04
...
There are a lot of definitions like this, and I am quite happy about it, because I didn't had to write them all.
However, while I can nicely use them for switch, if and other statements as a replacement for 0x00 and so on, I now would like to have the opposide direction.
So, having 0x00, I would like to print out the identifier "STATUS_OK".
As far as I know, this is not possible, but what would be a good workaround to make it possible?! Would it be possible to setup an array like this:
arrayNames[STATUS_OK] = _STATUS_OK_
Whereby STATUS_OK would resolve to 0x00 and _STATUS_OK_ would resolve to "STATUS_OK"?
Further, I am looking for a solution, which uses as little memory, as possible to do this.
This would be what I would like to be able to do:
prinf("%s",resolve(0x00));
-> "STATUS_OK"
I hope, I made clear what I am looking for.
Edit:
Thanks to all for, the quick and useful responses! I'll work with Larsmans solution and might try to combine it with the one of qrdl. May take a while, I'll replace this edit, when it is done.
You can use a little macro wizardry and a stringize operator of the preprocessor to do it. Take a look:
#include <stdio.h>
#define STATUS_OK 0x05
#define STATUS_BAD 0x09
#define LOOKUP_CASE(x) case x: return #x
const char *lookup_name(int val) {
switch(val) {
LOOKUP_CASE(STATUS_OK);
LOOKUP_CASE(STATUS_BAD);
default: return "<UNDEFINED>";
}
return NULL;
}
int main(void) {
printf("%s\n", lookup_name(STATUS_OK));
printf("%s\n", lookup_name(STATUS_BAD));
return 0;
}
The example is self-explanatory, except for the LOOKUP_CASE macro. It uses the # operator to produce a string constant that corresponds to its operand, letting you avoid repeating the name of the #define-d constant twice.
Here is a link to ideone with this working example.
Use X-Macros, although it will require changing your original header file
You can do something like this:
const char *status_str(int s)
{
switch(s)
{
case STATUS_OK:
return "STATUS_OK";
/* And so on and so forth */
}
}
It's not possible to get name of the identifier from its value. Because the identifiers are no longer available after the pre-processing and compiler has no knowledge about them.
However, you can try to store their names in an array or some other trick similar to that.
One easy solution is to write two very simple code generators. If you store your identifiers in a text file with the simple format
identifier value
e.g.
STATUS_OK 0x00
STATUS_FAIL 0x01
then two simple Awk scripts can generate a header with the #defines and a C module with the strings from that. For the headers:
BEGIN {
print("#ifndef _STATUSCODES_H");
print("#define _STATUSCODES_H");
}
{ printf("#define %s %s\n", $1, $2) }
END { print("#endif"); }
For the mapping back to strings:
BEGIN {
print("#include \"statuscodes.h\"");
print("char const *status_string(int status)");
print("{");
print(" switch (status) {");
}
{ printf(" case %s: \"%s\"\n", $2, $1); }
END {
print(" }");
print("}");
}
Then let your Makefile generate the module and header when the table of identifiers changes.
I don't think there is a solution for your problem without using switch to check for every value or making a full list with the names:
char *s_names[] = {
"STATUS_OK",
"STATUS_FAIL",
...
}
Now you can simply access the strings by the index (which is the error code):
printf("%s", s_names[0x00]); // prints "STATUS_OK"
printf("%s", s_names[STATUS_OK]); // prints "STATUS_OK" too
This will work if you have the value (or the macro) but if you don't want to waste so much space for a whole list you can use this macro:
#define MACRO_TO_STRING(x) #x
Now you can convert the macro to a string but not the value to a string:
printf("%s", MACRO_TO_STRING(STATUS_OK)); // prints "STATUS_OK"
printf("%s", MACRO_TO_STRING(0x00)); // but this doesn't work: prints "0x00"
If I use the macro:
#define AND
in the following way:
if(...)
{
...
}
elseANDif(...)
{
...
}
What output does the preprocessor produce?
Edit:
I intend to use:
#define TEST(params) if(...){...}else
the ... in if(...) is a complicated expression using params
the ... in {...} performs some operations & is independent of params
#define AND
TEST(x1) AND TEST(x2)
{
//the code for the final else
}
Is the AND helping here or can I do without it?
No, this isn't going to work as you expect. And you can test what the preprocessor does by running your code through cpp.
eliben#eliben-desktop:~/temp$ cat z.c
#define AND
if(...)
{
...
}
elseANDif(...)
{
...
}
eliben#eliben-desktop:~/temp$ cpp z.c
# 1 "z.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "z.c"
if(...)
{
...
}
elseANDif(...)
{
...
}
The technical reason is that when cpp expands macros it looks for a complete identifier token matching this macro's name. I.e. in your case, it looks for the identifier AND. However when it parses the code it doesn't find such an identifier. It finds elseANDif which is quite a different identifier. It has no way to break elseANDif into constituents, and that's a good thing because otherwise macros would work very badly. Imagine:
const int FUSIONDEBUG = 5;
Whatever that means, in real C code this would break awfully, since NDEBUG is almost always defined in production code to be empty (google on what NDEBUG means).
Regarding your edit, the best advice I can give you on such matters is DON'T DO IT. (ab)Using macros like this may appear at first to make the code more readable, but in the long term it makes it much less readable, with the added peril that macros are tricky to get perfectly right and with certain combination of tokens can blow up on you badly.
So you can definitely do without the AND as well as without the TEST altogether.
This:
#define TEST(condn) if(...){...}else
is nonsense; what do you expect the ellipses (...) to do!?
the example usage you gave would expand to
if(...){...} else if(...){...}else
{
//the code for the final else
}
which is patently nonsense; where is the condn argument used?. Either way whatever you really intended the AND has no effect other than dummy readability. If you are trying to invent a new language, the C preprocessor is not the way to do this. I can see no advantage to what you appear to be trying to achieve over more straightforward code.
If you intended:
#define TEST(condn) if(condn){/*some code*/}else
then how is the resultant:
if(a==b){/*some code*/} else if(b==c){/*some code*/}else
{
//the code for the final else
}
better than:
if(a==b || b==c)
{
/*some code*/
}
else
{
//the code for the final else
}
where /*some code*/ is not unnecessarily duplicated?
Note that here the single condition chained by || is equivalent to your multiple conditions chained by else if, so even if you use the TEST macro, there is no need to use it that way when:
TEST( a==b || b==c)
{
//the code for the final else
}
will suffice.
Macros are often ill-advised at the best of times, but you have chosen a particularly prime example of macro abuse! Consider for example how you might debug such code in a source-level debugger.
The short answer to your question is "yes". You can certainly do what you are suggesting. Here is a basic, working example:
#include <stdio.h>
#define AND
#define TEST(params) if (!params) { printf(#params " was false\n"); } else
int main(int argc, char ** argv)
{
int param_1 = 1;
int param_2 = 0;
TEST(param_1) AND TEST(param_2)
{
printf("success!\n");
}
}
After macro expansion, the code would essentially look like this:
int main(int argc, char ** argv)
{
int param_1 = 1;
int param_2 = 0;
if (!param_1) { printf("param_1 was false\n"); } else
if (!param_2) { printf("param_2 was false\n"); } else
{
printf("success!\n");
}
}
As pointed out by others, doing something like this is questionable because it messes with the way people read code and can make future debugging difficult. In a case such as this, I would definitely recommend using a function call if at all possible. This is the approach that Secure recommends in his comment:
int test_parameters(int params)
{
if (!params) { printf("bad parameters"); return 0; }
else { return 1; }
}
int main(int argc, char ** argv)
{
int param_1 = 1;
int param_2 = 0;
if (test_parameters(param_1) && test_parameters(param_2))
{
printf("success!\n");
}
}