1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
|
# Programm zum Eliminieren von '#elif'-Prprozessor-Anweisungen in C-Programmen
# Bruno Haible 30.8.1991
# Methode:
# Erkenne die Prprozessor-Anweisungen #if, #else, #endif, #elif, #line.
# Bei '#if' wird ein neuer Zhler aufgemacht und auf 1 gesetzt.
# Bei '#elif' wird '#else #if' ausgegeben und der letzte Zhler um 1 erhht.
# Bei '#endif' werden so viele '#endif's ausgegeben, wie der Zhler angibt.
#define local static
#define global
#define var
#define loop while (1)
#define until(exp) while (!(exp))
typedef unsigned char uintB;
typedef unsigned short uintW;
typedef unsigned long uintL;
typedef int boolean;
#define FALSE 0
#define TRUE 1
#include <stdio.h>
#ifdef __cplusplus
extern "C" void exit(int);
#endif
typedef unsigned char Char;
global int main(argc,argv)
var int argc;
var char** argv;
{ var FILE* infile = stdin;
var FILE* outfile = stdout;
#define get() getc(infile)
#define put(x) putc(x,outfile)
#define puts(x) fputs(x,outfile)
register int c;
var long line_number = 0;
var int counterstack[1000];
var int* counterptr = &counterstack[0];
L1: # zu Beginn einer Zeile
line_number++;
c = get(); if (c==EOF) goto L3;
if (!(c=='#'))
{ put(c); if (c=='\n') goto L1;
L2a:# innerhalb einer Zeile
c = get();
L2: if (c==EOF) goto L3;
put(c);
if (c=='\n') goto L1; else goto L2a;
}
# innerhalb einer Prprozessor-Anweisung
# Whitespace innerhalb der Zeile berlesen:
#define read_whitespace() \
loop \
{ put(c); \
c = get(); \
if (c==EOF) goto L3; \
if (!((c==' ') || (c=='\t'))) break; \
}
read_whitespace();
# Token lesen:
#define MAXTOKENLEN 1000
#define alphanumericp(c) \
(((c>='0') && (c<='9')) || ((c>='A') && (c<='Z')) || ((c>='a') && (c<='z')) || (c=='_'))
{ var Char token_buffer[MAXTOKENLEN+1];
var int token_length;
#define flush_token_buffer() \
{var int i = 0; until (i==token_length) { put(token_buffer[i++]); } }
#define read_token() \
{ token_length = 0; \
while (alphanumericp(c) && (token_length<MAXTOKENLEN)) \
{ token_buffer[token_length++] = c; c = get(); } \
}
read_token();
if ((token_length >= 1) && (token_buffer[0]>='0') && (token_buffer[0]<='9'))
goto line; # Zeilennummern-Angabe
if ((token_length == 4)
&& (token_buffer[0]=='l')
&& (token_buffer[1]=='i')
&& (token_buffer[2]=='n')
&& (token_buffer[3]=='e')
)
# '#line' -Anweisung
{ flush_token_buffer();
read_whitespace();
read_token();
line:
if (token_length>0)
{ token_buffer[token_length] = '\0';
{var long token_value = atol(token_buffer);
if (token_value>0)
{ line_number = token_value - 1; } # Zeilennummer neu setzen
}}
flush_token_buffer();
goto L2;
}
if ( ((token_length == 2)
&& (token_buffer[0]=='i')
&& (token_buffer[1]=='f')
)
|| ((token_length == 5)
&& (token_buffer[0]=='i')
&& (token_buffer[1]=='f')
&& (token_buffer[2]=='d')
&& (token_buffer[3]=='e')
&& (token_buffer[4]=='f')
)
|| ((token_length == 6)
&& (token_buffer[0]=='i')
&& (token_buffer[1]=='f')
&& (token_buffer[2]=='n')
&& (token_buffer[3]=='d')
&& (token_buffer[4]=='e')
&& (token_buffer[5]=='f')
)
)
# '#if' oder '#ifdef' oder '#ifndef' -Anweisung
{ *++counterptr = 1; flush_token_buffer(); goto L2; }
if ((token_length == 4)
&& (token_buffer[0]=='e')
&& (token_buffer[1]=='l')
&& (token_buffer[2]=='s')
&& (token_buffer[3]=='e')
)
# '#else' -Anweisung
{ if (counterptr == &counterstack[0])
{ fprintf(stderr,"#else ohne #if in Zeile %ld\n",line_number); }
flush_token_buffer(); goto L2;
}
if ((token_length == 5)
&& (token_buffer[0]=='e')
&& (token_buffer[1]=='n')
&& (token_buffer[2]=='d')
&& (token_buffer[3]=='i')
&& (token_buffer[4]=='f')
)
# '#endif' -Anweisung
{ flush_token_buffer();
if (counterptr == &counterstack[0])
{ fprintf(stderr,"#endif ohne #if in Zeile %ld\n",line_number); }
else
{var int count = *counterptr-- - 1;
if (count > 0)
{ sprintf(token_buffer,"#line %ld\n",line_number);
do { put('\n'); puts(token_buffer); puts("#endif"); count--; }
until (count == 0);
} }
goto L2;
}
if ((token_length == 4)
&& (token_buffer[0]=='e')
&& (token_buffer[1]=='l')
&& (token_buffer[2]=='i')
&& (token_buffer[3]=='f')
)
# '#elif' -Anweisung
{ if (counterptr == &counterstack[0])
{ fprintf(stderr,"#elif ohne #if in Zeile %ld\n",line_number); }
else
{ (*counterptr)++; }
puts("else"); put('\n');
sprintf(token_buffer,"#line %ld\n",line_number);
puts(token_buffer);
puts("#if");
goto L2;
}
flush_token_buffer();
goto L2;
}
L3: # am File-Ende
# Files schlieen:
if (ferror(infile) || ferror(outfile))
{ fclose(infile); fclose(outfile); exit(1); }
fclose(infile);
fclose(outfile);
exit(0); # alles OK
}
|