Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/pax/nocomment.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1987-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
22
/*
23
* Glenn Fowler
24
* AT&T Research
25
*
26
* nocomment -- strip C comments
27
*/
28
29
#include <ast.h>
30
#include <ctype.h>
31
32
#if 0
33
static int line_sfputc(int line, Sfio_t* sp, int c)
34
{
35
sfprintf(sp, "<<<C:%d>>>", line);
36
return sfputc(sp, c);
37
}
38
static int line_sfputr(int line, Sfio_t* sp, const char* buf, int op)
39
{
40
sfprintf(sp, "<<<R:%d>>>", line);
41
return sfputr(sp, buf, op);
42
}
43
#undef sfputc
44
#define sfputc(a,b) line_sfputc(__LINE__,a,b)
45
#undef sfputr
46
#define sfputr(a,b,c) line_sfputr(__LINE__,a,b,c)
47
#endif
48
49
#define SYNC() do \
50
{ \
51
if (line > prev && line > directive) \
52
{ \
53
if (sfsprintf(buf, sizeof(buf), "\n#%s %d\n", sync <= 0 ? "line" : "", line + 1) <= line - prev) \
54
{ \
55
sfputr(op, buf, -1); \
56
prev = line; \
57
} \
58
else while (prev < line) \
59
{ \
60
prev++; \
61
sfputc(op, '\n'); \
62
} \
63
data = 0; \
64
} \
65
} while (0)
66
67
#define DATA(c) do \
68
{ \
69
SYNC(); \
70
data = 1; \
71
sfputc(op, c); \
72
} while (0)
73
74
/*
75
* get next token on ip
76
*/
77
78
static char*
79
token(register Sfio_t* ip)
80
{
81
register int c;
82
register char* s;
83
84
static char buf[1024];
85
86
s = buf;
87
for (;;)
88
{
89
switch (c = sfgetc(ip))
90
{
91
case EOF:
92
if (s > buf)
93
break;
94
return 0;
95
case '\\':
96
case '/':
97
case '\n':
98
sfungetc(ip, c);
99
break;
100
default:
101
if (isspace(c))
102
{
103
if (s > buf)
104
{
105
sfungetc(ip, c);
106
break;
107
}
108
}
109
else if (s < &buf[sizeof(buf)-1])
110
*s++ = c;
111
continue;
112
}
113
break;
114
}
115
*s = 0;
116
return buf;
117
}
118
119
/*
120
* uncomment ip into op
121
*/
122
123
off_t
124
nocomment(register Sfio_t* ip, Sfio_t* op)
125
{
126
register int c = 0;
127
register int p;
128
register int data = 0;
129
int sync = 0;
130
int formals = 0;
131
unsigned long line = 0;
132
unsigned long prev = 0;
133
unsigned long directive = 0;
134
Sfio_t* pp = 0;
135
off_t count;
136
int quote;
137
int n;
138
char* s;
139
char buf[PATH_MAX];
140
141
count = sftell(op);
142
for (;;)
143
{
144
next:
145
p = c;
146
c = sfgetc(ip);
147
check:
148
switch (c)
149
{
150
case EOF:
151
if (line != prev)
152
sfputc(op, '\n');
153
goto done;
154
case 0:
155
sfputc(op, c);
156
sfmove(ip, op, SF_UNBOUND, -1);
157
goto done;
158
case '\\':
159
DATA(c);
160
switch (c = sfgetc(ip))
161
{
162
case EOF:
163
goto done;
164
case '\n':
165
directive++;
166
prev = ++line;
167
sfputc(op, c);
168
c = 0;
169
break;
170
default:
171
sfputc(op, c);
172
break;
173
}
174
break;
175
case '\f':
176
case '\t':
177
case '\v':
178
c = ' ';
179
/*FALLTHROUGH*/
180
case ' ':
181
if (data) switch (p)
182
{
183
case ' ':
184
case '\n':
185
case '(':
186
case '[':
187
case ']':
188
case '{':
189
case '}':
190
case ';':
191
case ':':
192
case '!':
193
case '<':
194
case '>':
195
case '|':
196
case ',':
197
case '?':
198
case '*':
199
break;
200
case ')':
201
if (directive == line && formals)
202
{
203
formals = 0;
204
sfputc(op, ' ');
205
}
206
break;
207
default:
208
switch (c = sfgetc(ip))
209
{
210
case '\n':
211
case ')':
212
case '[':
213
case ']':
214
case '{':
215
case '}':
216
case ';':
217
case ':':
218
case '=':
219
case '!':
220
case '<':
221
case '>':
222
case '|':
223
case ',':
224
case '?':
225
break;
226
case '(':
227
if (directive == line && formals)
228
{
229
formals = 0;
230
sfputc(op, ' ');
231
}
232
break;
233
case '*':
234
if (p == '/' || p == '=')
235
sfputc(op, ' ');
236
break;
237
case '+':
238
case '-':
239
case '&':
240
if (p == c || p == '=')
241
sfputc(op, ' ');
242
break;
243
default:
244
sfputc(op, ' ');
245
break;
246
}
247
p = ' ';
248
goto check;
249
}
250
break;
251
case '\n':
252
data = 0;
253
line++;
254
break;
255
case '#':
256
SYNC();
257
directive = line;
258
formals = 1;
259
if (sync >= 0 && !data)
260
{
261
if (s = token(ip))
262
{
263
if (isdigit(*s))
264
{
265
sync = 1;
266
directive = 0;
267
line = strtol(s, NiL, 10);
268
if (s = sfgetr(ip, '\n', 1))
269
{
270
while (isspace(*s))
271
s++;
272
if (*s == '"')
273
{
274
sfprintf(op, "# %d %s\n", line, s);
275
prev = line;
276
}
277
}
278
break;
279
}
280
if (!sync)
281
{
282
if (!pp && line <= 24 && streq(s, "pragma"))
283
{
284
if ((s = token(ip)) && streq(s, "prototyped"))
285
{
286
sync = -1;
287
if (c = sffileno(ip))
288
{
289
n = dup(0);
290
close(0);
291
dup(c);
292
}
293
sfseek(ip, (Sfoff_t)(-1), SEEK_CUR);
294
sfsync(ip);
295
if (pp = sfpopen(NiL, "proto -fns", "r"))
296
ip = pp;
297
if (c)
298
{
299
close(0);
300
dup(n);
301
}
302
c = 0;
303
break;
304
}
305
DATA('#');
306
sfputr(op, "pragma", ' ');
307
sfputr(op, s, -1);
308
c = 0;
309
break;
310
}
311
if (!streq(s, "ident") && !streq(s, "line") && !streq(s, "pragma"))
312
sync = -1;
313
}
314
DATA('#');
315
sfputr(op, s, -1);
316
c = 0;
317
}
318
else sync = -1;
319
}
320
if (c) DATA(c);
321
else data = 1;
322
break;
323
case '/':
324
switch (c = sfgetc(ip))
325
{
326
case EOF:
327
goto done;
328
case '/':
329
for (;;) switch (p = c, c = sfgetc(ip))
330
{
331
case EOF:
332
goto done;
333
case '\n':
334
if (p == '\\')
335
{
336
sfputc(op, p);
337
sfputc(op, c);
338
prev = ++line;
339
break;
340
}
341
p = ' ';
342
c = '\n';
343
goto check;
344
}
345
break;
346
case '*':
347
for (;;) switch (p = c, c = sfgetc(ip))
348
{
349
case EOF:
350
goto done;
351
case '\n':
352
directive++;
353
line++;
354
break;
355
case '*':
356
for (;;)
357
{
358
switch (c = sfgetc(ip))
359
{
360
case EOF:
361
goto done;
362
case '\n':
363
directive++;
364
line++;
365
break;
366
case '/':
367
p = c = ' ';
368
goto check;
369
case '*':
370
continue;
371
}
372
break;
373
}
374
break;
375
}
376
break;
377
default:
378
p = '/';
379
DATA(p);
380
goto check;
381
}
382
break;
383
case '"':
384
case '\'':
385
DATA(c);
386
quote = c;
387
for (;;)
388
{
389
switch (c = sfgetc(ip))
390
{
391
case EOF:
392
goto done;
393
case '\\':
394
sfputc(op, c);
395
switch (c = sfgetc(ip))
396
{
397
case EOF:
398
goto done;
399
case '\n':
400
directive++;
401
prev = ++line;
402
break;
403
}
404
break;
405
case '"':
406
case '\'':
407
if (c == quote)
408
{
409
sfputc(op, c);
410
goto next;
411
}
412
break;
413
case '\n':
414
p = ' ';
415
goto check;
416
}
417
sfputc(op, c);
418
}
419
break;
420
default:
421
DATA(c);
422
break;
423
}
424
}
425
done:
426
count = count < 0 ? 0 : (sferror(ip) || sferror(op)) ? -1 : (sftell(op) - count);
427
if (pp) sfclose(pp);
428
return count;
429
}
430
431