-2

I have a file which has some difinitions like:

TRACE( tra_1, "AA")
TRACE( tra_1, "BB")
TRACE( tra_1, "CC")
TRACE( tra_1, "DD")
TRACE( tra_1, "EE")
..

and so on. where AA, BB, CC, DD and EE are strings.

I want to take those TRACE definitions from file and convert them to enum. The output of pre-processor should look like:

typedef enum{
AA,
BB,
CC,
DD,
EE
} TRACE;
AstroCB
  • 12,337
  • 20
  • 57
  • 73
user1430471
  • 9
  • 1
  • 2
  • This is not a question about C programming, this is a question about manipulating source code text according to a pattern. – unwind Jun 01 '12 at 10:55
  • You could use Perl or Python to parse the input file and generate the required `enum` declarations. – gavinb Jun 01 '12 at 10:57
  • possible duplicate of [Easy way to use variables of enum types as string in C?](http://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c) – Suma Jun 01 '12 at 11:27
  • `"The output should look like"`... Huh? The output should print source code? I don't understand this question. – Lundin Jun 01 '12 at 13:01
  • Have you tried to do something like to generate a file, say MyEnum.h, with your enum written in it, then to include the file where you need and use the enum? – giocarmine Jun 01 '12 at 10:58

6 Answers6

5

Perhaps you can make it the other way round: Have enums and make strings from them?

 #define ENUM2STR( _e ) #_e
 TRACE( tra_1, ENUM2STR(AA) )
 ...
ur.
  • 2,890
  • 1
  • 18
  • 21
3

There is no need for code generation. The c pre-processor can do it for you.

Put all the enum values in an include file. trace_val.h:

ENUM_START(TRACE)
ENUM_VAL(tra_1, "AA")
ENUM_VAL(tra_1, "BB")
ENUM_VAL(tra_1, "CC")
ENUM_VAL(tra_1, "DD")
ENUM_VAL(tra_1, "EE")
ENUM_END(TRACE)

In another file trace.h:

#define ENUM_START(NAME) typedef enum {
#define ENUM_VAL(ID, VAL) ID,
#define ENUM_END(NAME) } NAME;
#include trace_val.h

In a similar way, you can redefine ENUM_START, ENUM_VAL and ENUM_END to create a translation table:

#define ENUM_START(NAME) enum_val_t NAME##_E[] = {
#define ENUM_VAL(ID, VAL) {ID, VAL},
#define ENUM_END(NAME) {NULL, NULL}};
#include "trace_val.h"
eyalm
  • 3,366
  • 19
  • 21
  • I tried your solution but it is giving compilation problems when compiling with gcc. I have one file (lets say my_file.ti) which has definitions like TRACE( tra_1, "AA") TRACE( tra_2, "BB") TRACE( tra_3, "CC") TRACE( tra_4, "DD") TRACE( tra_5, "EE"). I want to include my_file.ti and convert those strings (second parameter in TRACE) to enum values. – user1430471 Jun 01 '12 at 16:02
0

sorry I post the wrong earlier.

check out this posts... It could help http://www.dreamincode.net/forums/topic/157186-conversion-of-string-to-enum/

0
typedef enum {
        LOL, WUT, foobar, helloworld
} TRACE;

#define NNAMES 4

// MUST MATCH ENUM DEFINITION
char *TRACE_NAMES[] = {
        "LOL",
        "WUT",
        "foobar",
        "helloworld"
};

TRACE convert_str_to_TRACE( char *n ){
        int i;
        for( i=0; i<NNAMES; i++){
                if( !strcmp( TRACE_NAMES[i], n )){
                        return i;
                }
        }
        return -1; //not found
}
mateusza
  • 5,341
  • 2
  • 24
  • 20
0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//Linked List
typedef struct _node {
    char *name;
    struct _node *next;
} Node;
typedef struct _list {
    Node *data;
    struct _list *next;
} List;

Node *new_Node(char *name){
    Node *p;
    p=(Node*)malloc(sizeof(Node));
    p->name = strdup(name);
    p->next = NULL;
    return p;
}

void free_Node(Node *p){
    if(p == NULL) return;
    free(p->name);
    free_Node(p->next);
    free(p);
}

List *new_List(){
    List *p;
    p=(List*)malloc(sizeof(List));
    p->data = NULL;
    p->next = NULL;
    return p;
}

void free_List(List *p){
    if(p == NULL) return;
    free_Node(p->data);
    free_List(p->next);
    free(p);
}

Node *findNode(List *root, char *name){
    if(root->data == NULL){
        root->data = new_Node(name);
        return root->data;
    }
    if(0==strcmp(root->data->name, name)){
        return root->data;
    }
    if(root->next == NULL){
        root->next = new_List();
        root->next->data = new_Node(name);
        return root->next->data;
    }
    return findNode(root->next, name);
}

void addChildNode(Node *node, char *name){
    if(node->next == NULL){
        node->next = new_Node(name);
    } else {
        addChildNode(node->next, name);
    }
}

void addNode(List *root, char *typeName, char *idName){
    Node *np;
    np = findNode(root, typeName);
    addChildNode(np, idName);
}

void toEnumSrcOut(FILE *fo, const char *srcFile){
    FILE *fp;
    int count;
    char enumName[64]={0};
    char enumId[64]={0};
    List *root,*lp;
    Node *np;

    root = new_List();
    fp=fopen(srcFile, "r");
    while(EOF!=(count=fscanf(fp, "%[^(]%*c %*[^,]%*c %*c%[^\"]%*[^\n]%*c", enumName, enumId))){
        if(count == 2){
            addNode(root, enumName, enumId);
        }
    }
    fclose(fp);
    for(lp = root; lp != NULL ; lp=lp->next){
        fprintf(fo, "typedef enum {\n");
        for(np = lp->data->next; np != NULL ; np=np->next){
            fprintf(fo, "\t%s",np->name);
            fprintf(fo, (np->next == NULL)? "\n" : ",\n");
        }
        fprintf(fo, "} %s;\n",lp->data->name);
    }
    free_List(root);
}

int main(){
    toEnumSrcOut(stdout, "enumsrc.txt");
    return 0;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
0

You could define a preprocessor function like this:

#define STRINGIFY(x) #x

Then if you have the following enum:

enum test {FIRST, SECOND, THIRD };

You can convert the enum to string using the preprocessor function, for example:

printf("enum string is %s\n", STRINGIFY(FIRST));
theprole
  • 2,274
  • 23
  • 25