Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I generate a list of #define values from C code?

I have code that has a lot of complicated #define error codes that are not easy to decode since they are nested through several levels.

Is there any elegant way I can get a list of #defines with their final numerical values (or whatever else they may be)?

As an example:

<header1.h>
#define CREATE_ERROR_CODE(class, sc, code) ((class << 16) & (sc << 8) & code)
#define EMI_MAX 16

<header2.h>
#define MI_1 EMI_MAX

<header3.h>
#define MODULE_ERROR_CLASS MI_1
#define MODULE_ERROR_SUBCLASS 1
#define ERROR_FOO CREATE_ERROR_CODE(MODULE_ERROR_CLASS, MODULE_ERROR_SUBCLASS, 1)

I would have a large number of similar #defines matching ERROR_[\w_]+ that I'd like to enumerate so that I always have a current list of error codes that the program can output. I need the numerical value because that's all the program will print out (and no, it's not an option to print out a string instead).

Suggestions for gcc or any other compiler would be helpful.

like image 427
djs Avatar asked Dec 30 '10 17:12

djs


People also ask

How do you make a list of numbers 1 to 100 in Python?

Using the range() function to create a list from 1 to 100 in Python. In Python, we can use the range() function to create an iterator sequence between two endpoints. We can use this function to create a list from 1 to 100 in Python. The function accepts three parameters start , stop , and step .

How can you make a list with numbers?

To start a numbered list, type 1, a period (.), a space, and some text. Word will automatically start a numbered list for you. Type* and a space before your text, and Word will make a bulleted list. To complete your list, press Enter until the bullets or numbering switch off.

How do I make a list of items in Python?

In Python, a list is created by placing elements inside square brackets [] , separated by commas. A list can have any number of items and they may be of different types (integer, float, string, etc.). A list can also have another list as an item. This is called a nested list.


4 Answers

GCC's -dM preprocessor option might get you what you want.

like image 71
nmichaels Avatar answered Nov 15 '22 03:11

nmichaels


I think the solution is a combo of @nmichaels and @aschepler's answers.

Use gcc's -dM option to get a list of the macros. Use perl or awk or whatever to create 2 files from this list:

1) Macros.h, containing just the #defines.

2) Codes.c, which contains

#include "Macros.h"

ERROR_FOO = "ERROR_FOO"
ERROR_BAR = "ERROR_BAR"

(i.e: extract each #define ERROR_x into a line with the macro and a string.

now run gcc -E Codes.c. That should create a file with all the macros expanded. The output should look something like

1 = "ERROR_FOO"
2 = "ERROR_BAR"

I don't have gcc handy, so haven't tested this...

like image 43
AShelly Avatar answered Nov 15 '22 02:11

AShelly


The program 'coan' looks like the tool you are after. It has the 'defs' sub-command, which is described as:

defs [OPTION...] [file...] [directory...]

Select #define and #undef directives from the input files in accordance with the options and report them on the standard output in accordance with the options.

See the cited URL for more information about the options. Obtain the code here.

like image 30
Jonathan Leffler Avatar answered Nov 15 '22 04:11

Jonathan Leffler


If you have a complete list of the macros you want to see, and all are numeric, you can compile and run a short program just for this purpose:

#include <header3.h>
#include <stdio.h>

#define SHOW(x) printf(#x " = %lld\n", (long long int) x)

int main(void) {
    SHOW(ERROR_FOO);
    /*...*/
    return 0;
}

As @nmichaels mentioned, gcc's -d flags may help get that list of macros to show.

like image 45
aschepler Avatar answered Nov 15 '22 04:11

aschepler