Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get rid of awful useless macros

I've got a quite large C and C++ code (~200k loc) which makes extensive use of awful macros:

/* ... */
#define PRIVATE static
#define BEGIN           {
#define END             }
/* ... */
#define WHILE(e)        while (e) {
#define DO /* yep, it's empty */
#define ENDWHILE        }
/* and it goes on and on, for every keyword of the language */

Here is the thing, I want to get rid of that stupid header, clean the code, and indent it properly.

At first, I wanted to use a simple sed to replace all those macros, but it seems it's not that simple.

The case of the WHILE is quite problematic (and it is the same for other statements). I can't juste replace WHILE by while, because the opening curly bracket will be missing. And of course, as the DO macro doesn't do anything, it's not always present in the code. Hence, replacing DO by { won't do the trick.

I can't use the endline either, because conditions are often split into multiple lines:

WHILE (clsr_calibragedf_tabdisque.tab_disque[indice_disque].tab_date[indice_date] NE
                   clsr_calibragedf_tabdate [indice].date) DO
                indice ++;
            ENDWHILE

The best solution I can think of would be a C preprocessor which could replace only thoses specific macros, and not expand the #include directives, or the others macros. But I can't find anything like that.

Any idea?

like image 427
MouleMan Avatar asked Apr 03 '14 12:04

MouleMan


1 Answers

Yuck! How about:

  1. Run your program through some perl to comment out #include directives in a distinctive way (e.g. /*FIXSTUFF #include <blah.h> FIXSTUFF*/). You might want to comment out other preprocessor stuff (e.g. #define) in a similar way.

  2. Check each file #includes the definition of the weird macros (only).

  3. Now run gcc -E on each file, which will preprocess the macros.

  4. Reverse step 1.

  5. Run indent for good measure.

Note, C Preprocessing does the following (stolen from here):

  1. Trigraph replacement: The preprocessor replaces trigraph sequences with the characters they represent.
  2. Line splicing: Physical source lines that are continued with escaped newline sequences are spliced to form logical lines.
  3. Tokenization: The preprocessor breaks the result into preprocessing tokens and whitespace. It replaces comments with whitespace.
  4. Macro expansion and directive handling: Preprocessing directive lines, including file inclusion and conditional compilation, are executed. The preprocessor simultaneously expands macros and, in the 1999 version of the C standard, handles _Pragma operators.

You are thus in theory going to lose trigraphs in the source code (some would suggest this is a bonus), and potentially alter line splicing (fixed at step 5 with indent). You will need to protect any other preprocessor directices as per step (1).

Good luck!

like image 192
abligh Avatar answered Sep 28 '22 05:09

abligh