Stripping tokens in the C preprocessor

Discussion in 'C Programming' started by dov.levenglick@gmail.com, Aug 5, 2012.

  1. Guest

    Hi,
    I am looking for a way to strip tokens using the C preprocessor. I looked in the GNU documentation and found nothing that would help me.
    Specifically, I would like to strip parenthesis "(" and ")". For example, if I would to feed the macro STRIP with "This string contains parenthesis right around here)"; I would like the output to be "This string contains parenthesis right around here".
    Can anyone point me towards the proper documentation and/or a working example?

    Thanks
    , Aug 5, 2012
    #1
    1. Advertising

  2. Eric Sosman Guest

    On 8/5/2012 7:39 AM, wrote:
    > Hi,
    > I am looking for a way to strip tokens using the C preprocessor. I looked in the GNU documentation and found nothing that would help me.
    > Specifically, I would like to strip parenthesis "(" and ")". For example, if I would to feed the macro STRIP with "This string contains parenthesis right around here)"; I would like the output to be "This string contains parenthesis right around here".
    > Can anyone point me towards the proper documentation and/or a working example?


    If I understand your intent correctly, you're out of luck.
    A quote-enclosed literal is a single preprocessing token as far
    as the preprocessor is concerned, and there's no way to look
    inside; tokens are indivisible. The preprocessor can suppress
    tokens, duplicate them, splice them together, and rearrange
    them, but it operates at the level of the token, not of the
    token's interior parts.

    What's your overall goal? Maybe there's a different approach.

    --
    Eric Sosman
    d
    Eric Sosman, Aug 5, 2012
    #2
    1. Advertising

  3. Guest

    On Sunday, August 5, 2012 3:07:05 PM UTC+3, Eric Sosman wrote:
    > On 8/5/2012 7:39 AM, d wrote:
    >
    > > Hi,

    >
    > > I am looking for a way to strip tokens using the C preprocessor. I looked in the GNU documentation and found nothing that would help me.

    >
    > > Specifically, I would like to strip parenthesis "(" and ")". For example, if I would to feed the macro STRIP with "This string contains parenthesis right around here)"; I would like the output to be "This string contains parenthesis right around here".

    >
    > > Can anyone point me towards the proper documentation and/or a working example?

    >
    >
    >
    > If I understand your intent correctly, you're out of luck.
    >
    > A quote-enclosed literal is a single preprocessing token as far
    >
    > as the preprocessor is concerned, and there's no way to look
    >
    > inside; tokens are indivisible. The preprocessor can suppress
    >
    > tokens, duplicate them, splice them together, and rearrange
    >
    > them, but it operates at the level of the token, not of the
    >
    > token's interior parts.
    >
    >
    >
    > What's your overall goal? Maybe there's a different approach.
    >
    >
    >
    > --
    >
    > Eric Sosman
    >
    > d


    Thanks,
    I inherited an existing (and awkward) implementation where, in order to abstract the underlying implementation of printf; a macro was introduced:
    #define PRINTF(message) os_printf message

    For each OS, os_printf would be redeclared - 99% of the time as a plain old printf.

    The ramification of this implementation is that in order to feed a regular printf, such as: printf ( const char * format, ... ); both format and __VA_ARGS__ would be fed as a single literal (if I understand you properly).

    Now, I want to implement this differently without breaking backward compatibility. Towards this, I want to separate the format from the arguments.

    Another option that came to mind would be to feed the message into sprintf; however that faces the same problem since I would have to call sprintf(buf, message); where message would be the mangled format/args tuple.

    I hope that I am clear.
    , Aug 5, 2012
    #3
  4. writes:
    <snip>
    > Thanks, I inherited an existing (and awkward) implementation where, in
    > order to abstract the underlying implementation of printf; a macro was
    > introduced: #define PRINTF(message) os_printf message
    >
    > For each OS, os_printf would be redeclared - 99% of the time as a
    > plain old printf.
    >
    > The ramification of this implementation is that in order to feed a
    > regular printf, such as: printf ( const char * format, ... ); both
    > format and __VA_ARGS__ would be fed as a single literal (if I
    > understand you properly).
    >
    > Now, I want to implement this differently without breaking backward
    > compatibility. Towards this, I want to separate the format from the
    > arguments.


    Ah. That's not what I got from your original post but no matter...
    Is this the sort of thing you want to do:

    #define PRINTF(m) PRINTF2 m
    #define PRINTF2(...) fprintf(stderr, __VA_ARGS__)

    so that an old invocation like: PRINTF(("x=%d\n", 42)); expands to
    fprintf(stderr, "x=%d\n", 42); ?

    If this is not along the right lines, you need to say exactly what "I
    want to implement this differently" means.

    <snip>
    --
    Ben.
    Ben Bacarisse, Aug 5, 2012
    #4
  5. Guest

    On Sunday, August 5, 2012 3:33:32 PM UTC+3, Ben Bacarisse wrote:
    > writes:
    >
    > <snip>
    >
    > > Thanks, I inherited an existing (and awkward) implementation where, in

    >
    > > order to abstract the underlying implementation of printf; a macro was

    >
    > > introduced: #define PRINTF(message) os_printf message

    >
    > >

    >
    > > For each OS, os_printf would be redeclared - 99% of the time as a

    >
    > > plain old printf.

    >
    > >

    >
    > > The ramification of this implementation is that in order to feed a

    >
    > > regular printf, such as: printf ( const char * format, ... ); both

    >
    > > format and __VA_ARGS__ would be fed as a single literal (if I

    >
    > > understand you properly).

    >
    > >

    >
    > > Now, I want to implement this differently without breaking backward

    >
    > > compatibility. Towards this, I want to separate the format from the

    >
    > > arguments.

    >
    >
    >
    > Ah. That's not what I got from your original post but no matter...
    >
    > Is this the sort of thing you want to do:
    >
    >
    >
    > #define PRINTF(m) PRINTF2 m
    >
    > #define PRINTF2(...) fprintf(stderr, __VA_ARGS__)
    >
    >
    >
    > so that an old invocation like: PRINTF(("x=%d\n", 42)); expands to
    >
    > fprintf(stderr, "x=%d\n", 42); ?
    >
    >
    >
    > If this is not along the right lines, you need to say exactly what "I
    >
    > want to implement this differently" means.
    >
    >
    >
    > <snip>
    >
    > --
    >
    > Ben.


    My existing functions are as follows:

    <file_os.h>
    #define os_printf printf
    <file.h>
    #define PRINTF(msg) os_printf msg

    <file.c>
    PRINTF(("Var equals %d", var));

    I am looking for a way, without changing the macro signature in file.h; to have PRINTF call in to a new function:
    int global_printf(const char * fmt, ...);
    , Aug 5, 2012
    #5
  6. Eric Sosman Guest

    On 8/5/2012 9:40 AM, wrote:
    >
    > My existing functions are as follows:
    >
    > <file_os.h>
    > #define os_printf printf
    > <file.h>
    > #define PRINTF(msg) os_printf msg
    >
    > <file.c>
    > PRINTF(("Var equals %d", var));
    >
    > I am looking for a way, without changing the macro signature in file.h; to have PRINTF call in to a new function:
    > int global_printf(const char * fmt, ...);


    What's wrong with changing <file_os.h> to say

    #define os_printf global_printf

    ? Isn't that precisely why the os_printf macro was introduced
    in the first place? What am I missing ?

    --
    Eric Sosman
    d
    Eric Sosman, Aug 5, 2012
    #6
  7. writes:

    <snip>
    > My existing functions are as follows:
    >
    > <file_os.h>
    > #define os_printf printf
    > <file.h>
    > #define PRINTF(msg) os_printf msg
    >
    > <file.c>
    > PRINTF(("Var equals %d", var));
    >
    > I am looking for a way, without changing the macro signature in
    > file.h; to have PRINTF call in to a new function: int
    > global_printf(const char * fmt, ...);


    From my reading of your original post, you seem to know how the above
    works, so there must be some unstated reason why the obvious

    #define os_printf global_printf

    is not suitable.

    --
    Ben.
    Ben Bacarisse, Aug 5, 2012
    #7
  8. Guest

    On Sunday, August 5, 2012 5:04:41 PM UTC+3, Ben Bacarisse wrote:
    > <dov> writes:
    >
    >
    >
    > <snip>
    >
    > > My existing functions are as follows:

    >
    > >

    >
    > > <file_os.h>

    >
    > > #define os_printf printf

    >
    > > <file.h>

    >
    > > #define PRINTF(msg) os_printf msg

    >
    > >

    >
    > > <file.c>

    >
    > > PRINTF(("Var equals %d", var));

    >
    > >

    >
    > > I am looking for a way, without changing the macro signature in

    >
    > > file.h; to have PRINTF call in to a new function: int

    >
    > > global_printf(const char * fmt, ...);

    >
    >
    >
    > From my reading of your original post, you seem to know how the above
    >
    > works, so there must be some unstated reason why the obvious
    >
    >
    >
    > #define os_printf global_printf
    >
    >
    >
    > is not suitable.
    >
    >
    >
    > --
    >
    > Ben.


    I mistyped the API for global_printf - sorry.
    I want to implement global_printf such that it can take a FILE* handle:
    global_printf(FILE* file, const char * fmt, ...);
    , Aug 5, 2012
    #8
  9. writes:

    > On Sunday, August 5, 2012 5:04:41 PM UTC+3, Ben Bacarisse wrote:
    >> <dov> writes:
    >>
    >>
    >>
    >> <snip>
    >>
    >> > My existing functions are as follows:

    >>
    >> >

    >>
    >> > <file_os.h>

    >>
    >> > #define os_printf printf

    >>
    >> > <file.h>

    >>
    >> > #define PRINTF(msg) os_printf msg

    >>
    >> >

    >>
    >> > <file.c>

    >>
    >> > PRINTF(("Var equals %d", var));

    >>
    >> >

    >>
    >> > I am looking for a way, without changing the macro signature in

    >>
    >> > file.h; to have PRINTF call in to a new function: int

    >>
    >> > global_printf(const char * fmt, ...);

    >>
    >>
    >>
    >> From my reading of your original post, you seem to know how the above
    >>
    >> works, so there must be some unstated reason why the obvious
    >>
    >>
    >>
    >> #define os_printf global_printf
    >>
    >>
    >>
    >> is not suitable.
    >>
    >>
    >>
    >> --
    >>
    >> Ben.


    Can you do anything to avoid all these extra blanks lines? If not,
    please switch back to Google's old interface which is less broken than
    the new one.

    > I mistyped the API for global_printf - sorry.
    > I want to implement global_printf such that it can take a FILE* handle:
    > global_printf(FILE* file, const char * fmt, ...);


    Now all I need to know is why the example I posted one reply previously
    is not suitable. Sure, it used the name "PRINTF2" rather than
    "os_printf" but the structure is not changed by using another name. To
    recap, what's wrong with:

    #define os_printf(...) global_printf(stderr, __VA_ARGS__)

    ?

    --
    Ben.
    Ben Bacarisse, Aug 5, 2012
    #9
  10. Guest

    <snip>
    > >>

    >
    > >> Ben.

    >
    > Can you do anything to avoid all these extra blanks lines? If not,
    > please switch back to Google's old interface which is less broken than
    > the new one.
    >
    >
    >
    > > I mistyped the API for global_printf - sorry.
    > > I want to implement global_printf such that it can take a FILE* handle:
    > > global_printf(FILE* file, const char * fmt, ...);

    >
    >
    >
    > Now all I need to know is why the example I posted one reply previously
    > is not suitable. Sure, it used the name "PRINTF2" rather than
    > "os_printf" but the structure is not changed by using another name. To
    > recap, what's wrong with:
    >
    > #define os_printf(...) global_printf(stderr, __VA_ARGS__)
    >
    > --
    >
    > Ben.


    Existing API:
    #define PRINTF printf
    #define LOG(logpoint, severity, msg) PRINTF msg

    LOG(WARN, ("this is a warning, this is a var %d\n", var) );

    I want to convert LOG to somehow call into a function:
    int new_printf(int logpoint, int severity, const char* fmt, ...)
    {
    va_list ap;

    va_start(ap,fmt);
    os_printf("Logpoint %d, severity %d reporting this: ", logpoint, severity);
    os_printf(fmp, ap);
    va_end(ap);
    }

    I tried changing
    #define LOG(logpoint, severity, ...) new_printf(logpoint, severity, __VA_ARGS__)

    However, I am getting the following warning from the compiler:
    'function' : 'const char *' differs in levels of indirection from 'unsigned long'

    The reason is because ("this is a warning, this is a var %d\n", var) is being parsed as an unsigned long rather than the {format, args} tuple.
    , Aug 5, 2012
    #10
  11. writes:
    <snip>
    > Existing API:
    > #define PRINTF printf
    > #define LOG(logpoint, severity, msg) PRINTF msg
    >
    > LOG(WARN, ("this is a warning, this is a var %d\n", var) );


    Slowly we are getting closer and closer to the problem that needs to be
    solved! We're not quite there yet, because the above is obviously not
    the existing API, but I think the typo is obvious. You presumably meant

    LOG(XXX, WARN, ("this is a warning, this is a var %d\n", var) );

    > I want to convert LOG to somehow call into a function:
    > int new_printf(int logpoint, int severity, const char* fmt, ...)
    > {

    <snip>
    > }
    >
    > I tried changing
    > #define LOG(logpoint, severity, ...) new_printf(logpoint, severity,
    > __VA_ARGS__)


    #define LOG(lp, s, args) new_printf(lp, s, X args)
    #define X(fmt, ...) fmt, __VA_ARGS__

    Pick better names, but you get the idea.

    <snip>
    --
    Ben.
    Ben Bacarisse, Aug 5, 2012
    #11
  12. Jens Gustedt Guest

    Am 05.08.2012 16:43, schrieb :
    > I tried changing
    > #define LOG(logpoint, severity, ...) new_printf(logpoint, severity, __VA_ARGS__)



    you have to keep the interface of LOG as it was before, receiving three
    arguments.

    just do

    #define EAT_PAREN(...) __VA_ARGS__
    #define LOG_(logpoint, severity, ...) new_printf(logpoint, severity,
    __VA_ARGS__)
    #define LOG(logpoint, severity, msg) new_printf(logpoint, severity,
    EAT_PAREN msg)

    Jens
    Jens Gustedt, Aug 5, 2012
    #12
  13. Guest

    On Sunday, August 5, 2012 6:25:03 PM UTC+3, Jens Gustedt wrote:
    > Am 05.08.2012 16:43, schrieb <dov>:
    >
    > > I tried changing

    >
    > > #define LOG(logpoint, severity, ...) new_printf(logpoint, severity, __VA_ARGS__)

    >
    >
    > you have to keep the interface of LOG as it was before, receiving three
    > arguments.
    >
    >
    >
    > just do
    >
    >
    >
    > #define EAT_PAREN(...) __VA_ARGS__
    >
    > #define LOG_(logpoint, severity, ...) new_printf(logpoint, severity,
    > __VA_ARGS__)
    >
    > #define LOG(logpoint, severity, msg) new_printf(logpoint, severity,
    > EAT_PAREN msg)
    >
    >
    >
    > Jens



    Hi all,
    Thank you all for assisting. The EAT_PAREN macro seems to be doing the trick.

    I am extremely sorry for having dragged out the discussion instead of spelling out the exact problematic API - I thought that stating it as a general problem would be more beneficial to other in the forum, but I was wrong.

    Dov
    , Aug 6, 2012
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ben Holness
    Replies:
    0
    Views:
    5,419
    Ben Holness
    Jan 6, 2006
  2. =?Utf-8?B?RWx0b24gVw==?=

    RE: string into tokens

    =?Utf-8?B?RWx0b24gVw==?=, Oct 13, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    418
    =?Utf-8?B?RWx0b24gVw==?=
    Oct 13, 2005
  3. =?Utf-8?B?TFc=?=

    string into tokens

    =?Utf-8?B?TFc=?=, Oct 13, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    383
    =?Utf-8?B?TFc=?=
    Oct 13, 2005
  4. Dale

    Struts Tokens - Newbie

    Dale, Feb 8, 2004, in forum: Java
    Replies:
    1
    Views:
    3,553
    Matt Parker
    Feb 10, 2004
  5. Cronus
    Replies:
    1
    Views:
    643
    Paul Mensonides
    Jul 15, 2004
Loading...

Share This Page