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);
}