Extract Argument from C Macro

890 Views Asked by At

I have a number of definitions consisting of two comma-separated expressions, like this:

#define PIN_ALARM  GPIOC,14

I want to pass the second expression of those definitions (14 in the case above) to unary macros like the following:

#define _PIN_MODE_OUTPUT(n)          (1U << ((n) * 2U))

How can I extract the second number? I want a macro, call it "PICK_RIGHT", which will do this for me:

#define PICK_RIGHT(???)   ???

So that I can make a new macro that can take my "PIN" definitions:

#define PIN_MODE_OUTPUT(???) _PIN_MODE_OUTPUT(PICK_RIGHT(???))

And I can simply do:

#define RESULT   PIN_MODE_OUTPUT(PIN_ALARM)
1

There are 1 best solutions below

4
On BEST ANSWER

Do not use macros for this. If you must, the following will work by throwing away the left part first so just the number remains. Use with care. No guarantees.

#define PIN_ALARM  GPIOC,14
#define RIGHTPART_ONLY(a,b) b

#define PIN_MODE_OUTPUT(a) RIGHTPART_ONLY(a)

#define RESULT   PIN_MODE_OUTPUT(PIN_ALARM)

int main (void)
{
    printf ("we'll pick ... %d\n", PIN_MODE_OUTPUT(PIN_ALARM));
    printf ("or maybe %d\n", RESULT);

    return 0;
}

If you want the left part as a string, you can use this (with the same warnings as above), where the left part gets converted to a string by #:

#define LEFTPART_ONLY(a,b) #a
#define PIN_MODE_NAME(a) LEFTPART_ONLY(a)

There is a practical reason this is not entirely without problems. GPIOC is a symbol and as such it is possibly defined elsewhere. Fortunately, it is not a problem if it is undefined, or it is but to a simple type - after all, first thing the macros do is "throw away the left part". But as Jonathan Leffler comments

Note that if GPIOC maps to a macro containing commas, you're likely to get compilation errors.