Home > Net >  Preprocessor to reformat each variadic argument to their each string value value
Preprocessor to reformat each variadic argument to their each string value value

Time:01-08

I would like to expand each argument with their name, following by the value, for example:

#define LOG_VARIABLES(FORMAT, ...) NSLog(FORMAT, ##__VA_ARGS__) //Not sure what to do with ##__VA_ARGS__ here to make it expands like as described below

LOG_VARIABLES(@"%@: %@, %@: %@, %@: %@", arg1, arg2, arg3)

would expand to

STRING_VALUE__(arg1), arg1, STRING_VALUE__(arg2), arg2, STRING_VALUE__(arg3), arg3

so the NSLog print:

arg1: <arg1_value>, arg2: <arg2_value>, arg3: <arg3_value>

CodePudding user response:

With a bit of help from Overloading Macro on Number of Arguments you could do it something like this.

#define LOG_VARIABLES( FORMAT, ...) NSLog( FORMAT, __VA_ARGS__ )

#define STR(X) #X
#define VAL(X) @(STR(X)), X

#define LOG1( FORMAT, A )                LOG_VARIABLES( FORMAT, VAL( A ) )
#define LOG2( FORMAT, A, B )             LOG_VARIABLES( FORMAT, VAL( A ), VAL( B ) )
#define LOG3( FORMAT, A, B, C )          LOG_VARIABLES( FORMAT, VAL( A ), VAL( B ), VAL( C ) )
#define LOG4( FORMAT, A, B, C, D )       LOG_VARIABLES( FORMAT, VAL( A ), VAL( B ), VAL( C ), VAL( D ) )
#define LOG5( FORMAT, A, B, C, D, E )    LOG_VARIABLES( FORMAT, VAL( A ), VAL( B ), VAL( C ), VAL( D ), VAL( E ) )
#define LOG6( FORMAT, A, B, C, D, E, F ) LOG_VARIABLES( FORMAT, VAL( A ), VAL( B ), VAL( C ), VAL( D ), VAL( E ), VAL( F ) )

#define GET_MACRO( FORMAT, _1, _2, _3, _4, _5, _6, NAME, ... ) NAME
#define LOG_X(FORMAT,...) GET_MACRO(_0, ##__VA_ARGS__, LOG6, LOG5, LOG4, LOG3, LOG2, LOG1 )(FORMAT,__VA_ARGS__)

int main ( int argc, const char * argv [] ) {
    @autoreleasepool
    {
        // insert code here...
        NSLog(@"Hello, World!");

        NSString * a = @"aa";
        NSString * b = @"bb";
        NSString * c = @"cc";
        NSString * d = @"dd";
        NSString * e = @"ee";
        NSString * f = @"ff";

        LOG_X(@"%@:%@",a);
        LOG_X(@"%@:%@ and %@:%@",a,b);
        LOG_X(@"%@:%@ and %@:%@ and %@:%@",a,b,c);
        LOG_X(@"%@:%@ and %@:%@ and %@:%@ and %@:%@",a,b,c,d);
        LOG_X(@"%@:%@ and %@:%@ and %@:%@ and %@:%@ and %@:%@",a,b,c,d,e);
        LOG_X(@"%@:%@ and %@:%@ and %@:%@ and %@:%@ and %@:%@ and %@:%@",a,b,c,d,e,f);

    }
    return 0;
}

Let me hasten to add that there are probably better ways to accomplish what you are trying to do and this is just a sample that only works to 6 arguments, but you get the idea ... also, I started out with your LOG_VARIABLES but along the way it morphed into LOG_X.

  •  Tags:  
  • Related