Re: comment enlever des #define ?

トップ ページ

このメッセージに返信
著者: Xavier Bestel
日付:  
To: GUILDE
題目: Re: comment enlever des #define ?
On Wed, 2005-07-20 at 11:56, Dominique Colombani wrote:
> Bonjour
>
> c'est typiquement une opération à faire avec awk ou gawk !!!


Oui, mais je suis nul en awk.

Bon, pour ceux qui auraient à faire la même chose, voilà un petit prog
en C qui peut rendre service.

A+,
    Xav

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef DEBUG
#define printd(a ...) fprintf(stderr, a)
#else
#define printd(a ...) do{}while(0)
#endif

#define MAXNAMES    20    // maximum number of options
#define MAXSTACK    100    // maximum level of nested #ifdefs


struct define
{
    const char *name;
    int positive;
};


struct ifdef
{
    int def;
    int positive;
    int prevmode;
};


struct define defs[MAXNAMES];
struct ifdef stack[MAXSTACK];

int defs_n, stack_n;

int printmode;

char * skipblanks(char* from)
{
    while(isspace(*from))
        from++;
    return from;
}


int stackit(char* word, int positive)
{
    int wlen;
    int match = -1;
    if(word)
    {
        int i;
        wlen = 0;
        while(word[wlen] && !isspace(word[wlen]))
            wlen++;
        for(i = 0; i < defs_n; i++)
            if(strlen(defs[i].name) == wlen && !strncmp(word, defs[i].name, wlen))
            {
                match = i;
                break;
            }
    }
    stack[stack_n].def = match;
    stack[stack_n].positive = positive;
    stack[stack_n].prevmode = printmode;
    printd("stacking %s\n", (match >= 0) ? defs[match].name : "unknown #define");
    stack_n++;
    if(match >= 0)
    {
        printmode &= positive ^ ~defs[match].positive;
        printd("printmode now %d\n", printmode);
    }
    if(stack_n >= MAXSTACK)
    {
        fprintf(stderr, "Too many nested #ifdefs (%d)\n", MAXSTACK);
        exit(1);
    }


    return match >= 0;
}


int process_line()
{
    int res, n = 0;
    char *line = NULL;
    res = getline(&line, &n, stdin);
    if(res < 0)
        return res;
    line[res] = 0;
    if(*line == '#')
    {
        char * nextword = skipblanks(line + 1);
        if(!strncmp(nextword, "ifdef", 5))
        {
            nextword = skipblanks(nextword + 5);
            if((!stackit(nextword, 1)) && printmode)
                printf("%s", line);
        }
        else if(!strncmp(nextword, "ifndef", 6))
        {
            nextword = skipblanks(nextword + 6);
            if((!stackit(nextword, 0)) && printmode)
                printf("%s", line);
        }
        else if(!strncmp(nextword, "if", 2))
        {
            stackit(NULL, 0);
            if(printmode)
                printf("%s", line);
        }
        else if(!strncmp(nextword, "else", 4))
        {
            printd("switching %s\n", (stack[stack_n - 1].def >= 0) ? defs[stack[stack_n - 1].def].name : "unknown #define");
            if(stack[stack_n - 1].def >= 0)
            {
                printmode = stack[stack_n - 1].prevmode & (stack[stack_n - 1].positive ^ defs[stack[stack_n - 1].def].positive);
                printd("printmode now %d\n", printmode);
            }
            if(stack[stack_n - 1].def < 0 && printmode)
                printf("%s", line);
        }
        else if(!strncmp(nextword, "endif", 5))
        {
            if(stack[stack_n - 1].def < 0 && printmode)
                printf("%s", line);
            stack_n--;
            printmode = stack[stack_n].prevmode;
            printd("unstacking %s\n", (stack[stack_n].def >= 0) ? defs[stack[stack_n].def].name : "unknown #define");
            if(stack[stack_n].def >= 0)
                printd("printmode now %d\n", printmode);
        }
        else
            if(printmode)
                printf("%s", line);
    }
    else if(printmode)
        printf("%s", line);
    free(line);
    return res;
}


int main(int argc, char *argv[])
{
    int i;
    if(argc >= MAXNAMES)
        goto badusage;
    for(i = 1; i < argc; i++)
    {
        if(argv[i][0] != '-')
            goto badusage;
        switch(argv[i][1])
        {
        case 'D':
            defs[defs_n].positive = 1;
            defs[defs_n].name = strdup(argv[i] + 2);
            defs_n++;
            break;
        case 'U':
            defs[defs_n].positive = 0;
            defs[defs_n].name = strdup(argv[i] + 2);
            defs_n++;
            break;
        default:
            goto badusage;
        }
    }


    for(i = 0; i < defs_n; i++)
        printd("#%s %s len=%d\n", defs[i].positive ? "define" : "undef", defs[i].name, strlen(defs[i].name));
    printmode = 1;
    stackit(NULL, 1);
    while(process_line() > 0);
    if(stack_n != 1)
    {
        fprintf(stderr, "Error: unbalanced #if... #endif\n");
        exit(1);
    }


    return 0;


badusage:
    fprintf(stderr, "usage: %s [-DDEFINE] [-UDEFINE] ...\n(max. %d options)\n", *argv, MAXNAMES);
    exit(1);
}