MACRO to capitalize first letter of a word in header.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • dissectcode
    New Member
    • Jul 2008
    • 66

    MACRO to capitalize first letter of a word in header.

    I know about toupper() and tolower() but I need to capitalize (or de-capitalize)the first letter of a word in a header file. I know there are no preprocessor functions that do that but is there another way?
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    I think I would be forced to ask why? and over how many files?

    For a small number of files then a text editor is probably your best bet.

    For more files you might be able to use an awk script to automate a lot of the process or a perl script.

    Ultimately you could write you own text processing program.

    Comment

    • dissectcode
      New Member
      • Jul 2008
      • 66

      #3
      This would be done over 50 files, and they are needed to be capitalized in order to feed the word in the proper format, as an input into another macro.

      I would like to keep this in a C header file.

      Comment

      • donbock
        Recognized Expert Top Contributor
        • Mar 2008
        • 2427

        #4
        I suggest you edit the header files to get the capitalization correct. You might have been able to alter 50 header files in the time since this thread was started.

        How many different words do you need to alter? The following is a really bad idea ... suppose you only need to change "big" to "Big" and "Small" to "small"
        Code:
        #define big Big
        #define Small small
        ...
        #include <header>
        ...
        call the macros that use "big" and "Small"
        ...
        #undef big
        #undef Small
        ...
        This is a bad idea because
        1. There may be instances of "big" and "Small" that you don't want to change.
        2. You are going out of your way to make your code hard for anybody to understand.
        3. Corollary to #1 and #2 above ... someday you may modify the program to insert the word "big" or "Small" without any desire for it to be changed.

        Comment

        • dissectcode
          New Member
          • Jul 2008
          • 66

          #5
          Originally posted by donbock
          This is a bad idea because
          1. There may be instances of "big" and "Small" that you don't want to change.
          2. You are going out of your way to make your code hard for anybody to understand.
          3. Corollary to #1 and #2 above ... someday you may modify the program to insert the word "big" or "Small" without any desire for it to be changed.

          This is definitely on the right track - to answer your question, I need to change to upper case, AND lower case in the same macro.

          For example:

          Code:
          #define mac(name, val)  (Name *)(name->myMember.anum) = val
          See how name input is Name AND name in the macro?

          Comment

          • donbock
            Recognized Expert Top Contributor
            • Mar 2008
            • 2427

            #6
            Originally posted by dissectcode
            I need to change to upper case, AND lower case in the same macro. For example:
            Code:
            #define mac(name, val)  (Name *)(name->myMember.anum) = val
            See how name input is Name AND name in the macro?
            How about this ...
            Code:
             
            typedef Name *ptr_name;
            ...
            #define mac(name, val) (ptr_##name)(name->myMember.anum) = val

            Comment

            • dissectcode
              New Member
              • Jul 2008
              • 66

              #7
              I need to change "name" to Name for the cast, and make sure it is in lower case for the structure name.

              Also - "name" is arbitrary so I couldn't typedef it to one thing ?

              Comment

              • donbock
                Recognized Expert Top Contributor
                • Mar 2008
                • 2427

                #8
                What I meant was ... suppose you have three "names" (foo, bar, and squid) ... that means you want the following code to appear after all macro expansions:
                Code:
                 
                Foo foo;
                Bar bar;
                Squid squid;
                ...
                (Foo *) (foo->myMember.anum) = fooVal;
                (Bar *) (bar->myMember.anum) = barVal;
                (Squid *) (squid->myMember.anum) = squidVal;
                My suggestion is to get the equivalent through the following ...
                Code:
                 
                typedef Foo *ptr_foo;
                typedef Bar *ptr_bar;
                typedef Squid *ptr_squid;
                ...
                #define mac(name, val) (ptr_ ## name)(name->myMember.anum) = val
                ...
                Foo foo;
                Bar bar;
                Squid squid;
                ...
                mac(foo, fooVal);
                mac(bar, barVal);
                mac(squid, squidVal);
                These macros expand into the three lines:
                Code:
                 
                (ptr_foo)(foo->myMember.anum) = fooVal;
                (ptr_bar)(bar->myMember.anum) = barVal;
                (ptr_squid)(squid->myMember.anum) = squidVal;
                Which, because of the typedefs, is equivalent to what you want.

                I haven't tried this out on a compiler, so there might be syntax issues for you to work out, but I'm pretty sure the concept is valid.

                Comment

                • dissectcode
                  New Member
                  • Jul 2008
                  • 66

                  #9
                  Originally posted by donbock
                  These macros expand into the three lines:
                  Code:
                   
                  (ptr_foo)(foo->myMember.anum) = fooVal;
                  (ptr_bar)(bar->myMember.anum) = barVal;
                  (ptr_squid)(squid->myMember.anum) = squidVal;

                  Thank you for your response. After looking through this code and concept - I am concerned that I cannot create a more general macro for any input during run-time....since it is a preprocessor thing, it does the concatenation at compile-time. Is this true?

                  Comment

                  • Tassos Souris
                    New Member
                    • Aug 2008
                    • 152

                    #10
                    Yes it is true.. this is done at compile time..

                    Can you give us a example of how you want this to work at run-time?

                    Comment

                    • donbock
                      Recognized Expert Top Contributor
                      • Mar 2008
                      • 2427

                      #11
                      Originally posted by dissectcode
                      Code:
                      #define mac(name, val)  (Name *)(name->myMember.anum) = val
                      See how name input is Name AND name in the macro?
                      Wait a minute ... why do you need the cast? The cast suggests that either the "name" argument to the macro or the "anum" field of the structure is not intrinsically the proper pointer type. Is it a void*?

                      In general, if you want run-time resolution of pointer types you have a table where each entry contains a void* pointer and an enumeration for all of the possible types that might be pointed to. You then have a big switch on the enumeration value with a case for each possible type. Within each case you explicitly cast the pointer to right kind of pointer type. However, realize that you have no safety net. You have almost no hope of getting a compiler warning/error if you mess up one of those cases by casting to the wrong type.

                      Comment

                      • Tassos Souris
                        New Member
                        • Aug 2008
                        • 152

                        #12
                        donbock is right..
                        can you give us please exactly how you need this to work?
                        I am very curious... what must the name and Name be?
                        It seems to be that you must follow A LOT OF naming conventions... which of course is only a burden for your mind... things that the compiler cannot check can be tricky..

                        Comment

                        • dissectcode
                          New Member
                          • Jul 2008
                          • 66

                          #13
                          Originally posted by Tassos Souris
                          donbock is right..
                          can you give us please exactly how you need this to work?
                          I am very curious... what must the name and Name be?
                          It seems to be that you must follow A LOT OF naming conventions... which of course is only a burden for your mind... things that the compiler cannot check can be tricky..

                          I think what I am trying to do can only be done using actual C code in functions since the name will depend on run-time inputs. I am using to it access HW registers. Please look at how the word "name" has certain letters in CAPS, or not.

                          Code:
                          #define REG_ADDR            ((void *) (0x00054000))
                          
                          #define REG_CASTADDR   ((Name *)(REG_ADDR))
                          
                          #define RD_REG(name, reg)    NAME##_CASTADDR->name##reg.myUint)
                          #define WR_REG(name, reg, val)  /
                          ((NAME_REG_BASE->name##reg.myUint) = val)
                          and then from a C program I call the macros:

                          Code:
                          int registerState = RD_REG(Regtest, Interrupt_stat);
                          So I need it to turn into :

                          Code:
                          REGTEST_CASTADDR->regtestInterrupt_stat.myUint;
                          It looks messy but I made is as general as possible

                          Comment

                          Working...