Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libpp/ppproto.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1986-2012 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
* Glenn Fowler
23
* AT&T Research
24
*
25
* convert C prototypes to ANSI, K&R and C++ styles or K&R to ANSI
26
* slips into the pp block read
27
*
28
* define PROTOMAIN for standalone proto
29
* PROTOMAIN is coded for minimal library support
30
*/
31
32
static const char id[] = "\n@(#)$Id: proto (AT&T Research) 2012-04-14 $\0\n";
33
34
#if PROTOMAIN
35
36
#include "ppfsm.c"
37
38
#include <hashkey.h>
39
40
#if PROTO_STANDALONE
41
#undef O_RDONLY
42
#endif
43
44
#else
45
46
#include "pplib.h"
47
#include "ppfsm.h"
48
49
#endif
50
51
#define GENERATED "/* : : generated by proto : : */\n"
52
53
#define PRAGMADIR "pragma" /* pragma directive */
54
#define MAGICTOP 80 /* must be in these top lines */
55
56
#ifndef elementsof
57
#define elementsof(x) (sizeof(x)/sizeof(x[0]))
58
#endif
59
60
typedef struct Key_s
61
{
62
const char* name;
63
size_t size;
64
int hit;
65
int val;
66
} Key_t;
67
68
typedef struct Proto_s /* proto buffer state */
69
{
70
int brace; /* {..} level */
71
int call; /* call level */
72
int fd; /* input file descriptor */
73
char* file; /* input file name */
74
long flags; /* coupled flags */
75
long options; /* uncoupled flags */
76
char* package; /* header package */
77
int line; /* input line count */
78
int test; /* testing */
79
80
char* tp; /* input token base */
81
82
int iz; /* input buffer size */
83
char* ib; /* input buffer base */
84
char* ip; /* input buffer pointer */
85
86
int oz; /* output buffer size */
87
char* ob; /* output buffer base */
88
char* op; /* output buffer pointer */
89
char* ox; /* output buffer externalize */
90
91
char cc[3]; /* beg mid end comment char */
92
char pushback[4]; /* pushback area for caller */
93
94
char variadic[256]; /* variadic args buffer */
95
96
/* output buffer */
97
/* slide buffer */
98
/* input buffer */
99
} Proto_t;
100
101
/*
102
* proto is separate from pp so these undef's are ok
103
*/
104
105
#undef CLASSIC
106
#define CLASSIC (1L<<0)
107
#undef DECLARE
108
#define DECLARE (1L<<1)
109
#undef DEFINE
110
#define DEFINE (1L<<2)
111
#undef DIRECTIVE
112
#define DIRECTIVE (1L<<3)
113
#undef ERROR
114
#define ERROR (1L<<4)
115
#undef EXTERN
116
#define EXTERN (1L<<5)
117
#undef EXTERNALIZE
118
#define EXTERNALIZE (1L<<6)
119
#undef IDID
120
#define IDID (1L<<7)
121
#undef INDIRECT
122
#define INDIRECT (1L<<8)
123
#undef INIT
124
#define INIT (1L<<9)
125
#undef INIT_DEFINE
126
#define INIT_DEFINE (1L<<10)
127
#undef INIT_INCLUDE
128
#define INIT_INCLUDE (1L<<11)
129
#undef JUNK
130
#define JUNK (1L<<12)
131
#undef LINESYNC
132
#define LINESYNC (1L<<13)
133
#undef MANGLE
134
#define MANGLE (1L<<14)
135
#undef MATCH
136
#define MATCH (1L<<15)
137
#undef MORE
138
#define MORE (1L<<16)
139
#undef OTHER
140
#define OTHER (1L<<17)
141
#undef PASS
142
#define PASS (1L<<18)
143
#undef PLUSONLY
144
#define PLUSONLY (1L<<19)
145
#undef PLUSPLUS
146
#define PLUSPLUS (1L<<20)
147
#undef RECURSIVE
148
#define RECURSIVE (1L<<21)
149
#undef SHARP
150
#define SHARP (1L<<22)
151
#undef SKIP
152
#define SKIP (1L<<23)
153
#undef SLIDE
154
#define SLIDE (1L<<24)
155
#undef TOKENS
156
#define TOKENS (1L<<25)
157
#undef TYPEDEF
158
#define TYPEDEF (1L<<26)
159
#undef VARIADIC
160
#define VARIADIC (1L<<27)
161
#undef VARIADIC2
162
#define VARIADIC2 (1L<<28)
163
#undef YACC
164
#define YACC (1L<<29)
165
#undef YACCSPLIT
166
#define YACCSPLIT (1L<<30)
167
#undef YACC2
168
#define YACC2 (1L<<31)
169
170
#undef GLOBAL
171
#define GLOBAL (MORE)
172
173
#undef REGULAR
174
#define REGULAR (1L<<0)
175
176
#ifndef CHUNK
177
#define CHUNK 1024
178
#endif
179
#define BLOCK (16*CHUNK)
180
181
#define T_VA_START (N_TOKEN+1)
182
183
#define RESERVED(b,e,n) ((((long)(b))<<16)|(((long)(e))<<8)|((long)(n)))
184
185
#define KEYENT(s,m,v) {s,sizeof(s)-1,m,v}
186
187
#define HIT_prototyped 0x01
188
#define HIT_noticed 0x02
189
190
static const Key_t pragmas[] =
191
{
192
KEYENT("prototyped", HIT_prototyped, 1), /* NOTE: first entry */
193
KEYENT("noprototyped", HIT_prototyped, 0),
194
KEYENT("noticed", HIT_noticed, 1),
195
KEYENT("nonoticed", HIT_noticed, 0),
196
};
197
198
static const Key_t notices[] =
199
{
200
KEYENT("Copyright", HIT_noticed, 1),
201
KEYENT("COPYRIGHT", HIT_noticed, 1),
202
KEYENT("copyright", HIT_noticed, 1),
203
KEYENT("Public Domain", HIT_noticed, 0),
204
KEYENT("PUBLIC DOMAIN", HIT_noticed, 0),
205
};
206
207
/*
208
* generate integer
209
* pointer to end returned
210
*/
211
212
static char*
213
number(register char* p, register long n)
214
{
215
register long d;
216
217
for (d = 1000000; d > 1; d /= 10)
218
if (n >= d) *p++ = '0' + (n / d) % 10;
219
*p++ = '0' + n % 10;
220
return p;
221
}
222
223
#if PROTOMAIN
224
225
static int errors;
226
227
#if PROTO_STANDALONE
228
229
/*
230
* namespace pollution forces us to claim parts of libc
231
*/
232
233
#undef memcpy
234
#define memcpy(t,f,n) memcopy(t,f,n)
235
#undef strcpy
236
#define strcpy(t,f) strcopy(t,f)
237
#undef strlen
238
#define strlen(s) sstrlen(s)
239
#undef strncmp
240
#define strncmp(s,t,n) sstrncmp(s,t,n)
241
242
/*
243
* environmentally safe strlen()
244
*/
245
246
static int
247
sstrlen(register const char* s)
248
{
249
register const char* b;
250
251
for (b = s; *s; s++);
252
return s - b;
253
}
254
255
/*
256
* environmentally safe strncmp()
257
*/
258
259
static int
260
sstrncmp(register const char* s, register const char* t, register int n)
261
{
262
register const char* e = s + n;
263
264
while (s < e)
265
{
266
if (*s != *t || !*s)
267
return *s - *t;
268
s++;
269
t++;
270
}
271
return 0;
272
}
273
274
/*
275
* strcpy() except pointer to end returned
276
*/
277
278
static char*
279
strcopy(register char* s, register const char* t)
280
{
281
while (*s++ = *t++);
282
return s - 1;
283
}
284
285
#endif
286
287
static void
288
proto_error(char* iob, int level, char* msg, char* arg)
289
{
290
register char* p;
291
char buf[1024];
292
293
p = strcopy(buf, "proto: ");
294
if (iob)
295
{
296
register Proto_t* proto = (Proto_t*)(iob - sizeof(Proto_t));
297
298
if (proto->line)
299
{
300
if (proto->file)
301
{
302
*p++ = '"';
303
p = strcopy(p, proto->file);
304
*p++ = '"';
305
*p++ = ',';
306
*p++ = ' ';
307
}
308
p = strcopy(p, "line ");
309
p = number(p, proto->line);
310
}
311
else if (proto->file)
312
p = strcopy(p, proto->file);
313
}
314
else
315
{
316
p = strcopy(p, msg);
317
msg = arg;
318
arg = 0;
319
}
320
if (*(p - 1) != ' ')
321
{
322
*p++ = ':';
323
*p++ = ' ';
324
}
325
if (level == 1)
326
p = strcopy(p, "warning: ");
327
p = strcopy(p, msg);
328
if (arg)
329
{
330
*p++ = ' ';
331
p = strcopy(p, arg);
332
}
333
*p++ = '\n';
334
write(2, buf, p - buf);
335
if (level >= 3)
336
exit(level - 2);
337
if (level >= 2)
338
errors++;
339
}
340
341
/*
342
* memcpy() but pointer to end returned
343
*/
344
345
static char*
346
memcopy(register char* s, register char* t, int n)
347
{
348
register char* e = t + n;
349
350
while (t < e) *s++ = *t++;
351
return s;
352
}
353
354
#include "../libast/port/astlicense.c"
355
356
#else
357
358
#define memcopy(s,t,n) (((char*)memcpy(s,t,n))+(n))
359
360
#endif
361
362
/*
363
* generate line sync
364
* pointer to end returned
365
*/
366
367
static char*
368
linesync(register Proto_t* proto, register char* p, register long n)
369
{
370
#if PROTOMAIN
371
if (proto->flags & LINESYNC)
372
#endif
373
{
374
#if PROTOMAIN
375
p = strcopy(p, "\n#line ");
376
#else
377
p = strcopy(p, "\n# ");
378
#endif
379
p = number(p, n);
380
*p++ = '\n';
381
}
382
return p;
383
}
384
385
/*
386
* output init header
387
* pointer to end returned
388
*/
389
390
static char*
391
init(Proto_t* proto, char* op, int flags)
392
{
393
register char* s;
394
395
if (flags & INIT_DEFINE)
396
{
397
op = strcopy(op, "\
398
\n\
399
#if !defined(__PROTO__)\n\
400
# if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)\n\
401
# if defined(__cplusplus)\n\
402
# define __LINKAGE__ \"C\"\n\
403
# else\n\
404
# define __LINKAGE__\n\
405
# endif\n\
406
# define __STDARG__\n\
407
# define __PROTO__(x) x\n\
408
# define __OTORP__(x)\n\
409
# define __PARAM__(n,o) n\n\
410
# if !defined(__STDC__) && !defined(__cplusplus)\n\
411
# if !defined(c_plusplus)\n\
412
# define const\n\
413
# endif\n\
414
# define signed\n\
415
# define void int\n\
416
# define volatile\n\
417
# define __V_ char\n\
418
# else\n\
419
# define __V_ void\n\
420
# endif\n\
421
# else\n\
422
# define __PROTO__(x) ()\n\
423
# define __OTORP__(x) x\n\
424
# define __PARAM__(n,o) o\n\
425
# define __LINKAGE__\n\
426
# define __V_ char\n\
427
# define const\n\
428
# define signed\n\
429
# define void int\n\
430
# define volatile\n\
431
# endif\n\
432
# define __MANGLE__ __LINKAGE__\n\
433
# if defined(__cplusplus) || defined(c_plusplus)\n\
434
# define __VARARG__ ...\n\
435
# else\n\
436
# define __VARARG__\n\
437
# endif\n\
438
# if defined(__STDARG__)\n\
439
# define __VA_START__(p,a) va_start(p,a)\n\
440
# else\n\
441
# define __VA_START__(p,a) va_start(p)\n\
442
# endif\n\
443
# if !defined(__INLINE__)\n\
444
# if defined(__cplusplus)\n\
445
# define __INLINE__ extern __MANGLE__ inline\n\
446
# else\n\
447
# if defined(_WIN32) && !defined(__GNUC__)\n\
448
# define __INLINE__ __inline\n\
449
# endif\n\
450
# endif\n\
451
# endif\n\
452
#endif\n\
453
#if !defined(__LINKAGE__)\n\
454
#define __LINKAGE__ /* 2004-08-11 transition */\n\
455
#endif\n\
456
");
457
}
458
else
459
op = strcopy(op, "\
460
\n\
461
#if !defined(__PROTO__)\n\
462
#include <prototyped.h>\n\
463
#endif\n\
464
#if !defined(__LINKAGE__)\n\
465
#define __LINKAGE__ /* 2004-08-11 transition */\n\
466
#endif\n\
467
");
468
if (proto->package)
469
{
470
s = "\
471
#ifndef __MANGLE_%_DATA__\n\
472
# ifdef _BLD_%\n\
473
# ifdef __EXPORT__\n\
474
# define __MANGLE_%_DATA__ __MANGLE__ __EXPORT__\n\
475
# else\n\
476
# define __MANGLE_%_DATA__ __MANGLE__\n\
477
# endif\n\
478
# define __MANGLE_%_FUNC__ __MANGLE__\n\
479
# else\n\
480
# ifdef __IMPORT__\n\
481
# define __MANGLE_%_DATA__ __MANGLE__ __IMPORT__\n\
482
# else\n\
483
# define __MANGLE_%_DATA__ __MANGLE__\n\
484
# endif\n\
485
# define __MANGLE_%_FUNC__ __MANGLE__\n\
486
# endif\n\
487
#endif\n\
488
";
489
for (;;)
490
{
491
switch (*op++ = *s++)
492
{
493
case 0:
494
op--;
495
break;
496
case '%':
497
op = strcopy(op - 1, proto->package);
498
continue;
499
default:
500
continue;
501
}
502
break;
503
}
504
}
505
return op;
506
}
507
508
#define BACKOUT() (op=ko)
509
#define CACHE() do{CACHEIN();CACHEOUT();call=proto->call;}while(0)
510
#define CACHEIN() (ip=proto->ip)
511
#define CACHEOUT() (op=proto->op)
512
#define GETCHR() (*(unsigned char*)ip++)
513
#define KEEPOUT() (ko=op)
514
#define LASTOUT() (*(op-1))
515
#define PUTCHR(c) (*op++=(c))
516
#define SYNC() do{SYNCIN();SYNCOUT();proto->flags&=~(EXTERN|INIT|OTHER|VARIADIC|VARIADIC2);proto->flags|=flags&(EXTERN|INIT|OTHER|VARIADIC|VARIADIC2);proto->call=call;}while(0)
517
#define SYNCIN() (proto->ip=ip)
518
#define SYNCOUT() (proto->op=op)
519
#define UNGETCHR() (ip--)
520
#define UNPUTCHR() (op--)
521
522
/*
523
* advance to the next non-space character
524
*/
525
526
static char*
527
nns(register char* s)
528
{
529
while (*s == ' ' || *s == '\t' || *s == '\n')
530
s++;
531
return s;
532
}
533
534
#define DIR_if 01
535
#define DIR_el 02
536
#define DIR_en 03
537
#define DIR 03
538
539
/*
540
* update directive mask
541
*/
542
543
static int
544
directive(register char* s, int dir)
545
{
546
switch (*(s = nns(s)))
547
{
548
case 'e':
549
case 'i':
550
dir <<= 2;
551
switch (*++s)
552
{
553
case 'f':
554
dir |= DIR_if;
555
break;
556
case 'l':
557
dir |= DIR_el;
558
break;
559
case 'n':
560
dir |= DIR_en;
561
break;
562
}
563
break;
564
}
565
return dir;
566
}
567
568
/*
569
* the tokenizer
570
* top level calls loop until EOB
571
* recursive calls just return the next token
572
*/
573
574
static int
575
lex(register Proto_t* proto, register long flags)
576
{
577
register char* ip;
578
register char* op;
579
register int c;
580
register int state;
581
register short* rp;
582
char* m;
583
char* e;
584
char* t;
585
char* bp;
586
char* v;
587
char* im;
588
char* ko;
589
char* aom;
590
int n;
591
int line;
592
int quot;
593
int brack;
594
int sub;
595
int x;
596
int vc;
597
598
char* ie = 0;
599
char* om = 0;
600
char* aim = 0;
601
char* aie = 0;
602
char* func = 0;
603
int call = 0;
604
int dir = 0;
605
int group = 0;
606
int last = 0;
607
int paren = 0;
608
#if PROTOMAIN
609
char* qe = 0;
610
int qn = 0;
611
int args = 0;
612
#endif
613
614
CACHE();
615
#if PROTOMAIN
616
if (flags & EXTERN) KEEPOUT();
617
#endif
618
fsm_start:
619
proto->tp = ip;
620
state = PROTO;
621
bp = ip;
622
do
623
{
624
rp = fsm[state];
625
fsm_get:
626
while (!(state = rp[c = GETCHR()]));
627
fsm_next:
628
;
629
} while (state > 0);
630
if ((n = ip - bp - 1) > 0)
631
{
632
ip = bp;
633
MEMCPY(op, ip, n);
634
ip++;
635
}
636
state = ~state;
637
fsm_terminal:
638
switch (TERM(state))
639
{
640
case S_CHR:
641
if (op > proto->ob && *(op - 1) == '=' && (op == proto->ob + 1 || *(op - 2) != '=')) switch (c)
642
{
643
case '+':
644
case '-':
645
case '*':
646
case '&':
647
PUTCHR(' ');
648
break;
649
}
650
PUTCHR(c);
651
break;
652
653
case S_CHRB:
654
UNGETCHR();
655
c = LASTOUT();
656
break;
657
658
case S_COMMENT:
659
switch (c)
660
{
661
case '\n':
662
if (INCOMMENTXX(rp)) goto fsm_newline;
663
PUTCHR(c);
664
proto->line++;
665
rp = fsm[COM2];
666
break;
667
case '/':
668
#if PROTOMAIN
669
if ((flags & (EXTERN|MATCH)) == EXTERN) BACKOUT();
670
else
671
#endif
672
PUTCHR(c);
673
if (INCOMMENTXX(rp))
674
{
675
rp = fsm[COM5];
676
break;
677
}
678
goto fsm_start;
679
case EOF:
680
break;
681
default:
682
#if PROTOMAIN
683
if ((flags & (EXTERN|MATCH)) == EXTERN) BACKOUT();
684
else
685
#endif
686
PUTCHR(c);
687
rp = fsm[INCOMMENTXX(rp) ? COM5 : COM3];
688
break;
689
}
690
bp = ip;
691
goto fsm_get;
692
693
case S_EOB:
694
if (c)
695
{
696
if (state = fsm[TERMINAL][INDEX(rp)+1])
697
goto fsm_terminal;
698
SYNC();
699
return 0;
700
}
701
UNGETCHR();
702
fsm_eob:
703
if ((flags & (DECLARE|GLOBAL|RECURSIVE)) == GLOBAL && (proto->flags & MORE))
704
{
705
#if PROTOMAIN
706
if (!(flags & EXTERN)) /* XXX */
707
#endif
708
flags |= SLIDE;
709
c = ip - proto->ib;
710
if (!(flags & MATCH))
711
im = proto->tp;
712
if (ip > proto->ib)
713
{
714
n = ip - im;
715
if (ip - n < proto->ib)
716
proto->flags |= ERROR;
717
memcopy(proto->ib - n, ip - n, n);
718
ip = proto->ib;
719
}
720
proto->tp -= c;
721
if (flags & MATCH)
722
{
723
im -= c;
724
ie -= c;
725
}
726
if (aim)
727
aim -= c;
728
if (aie)
729
aie -= c;
730
if ((n = read(proto->fd, ip, proto->iz)) > 0)
731
{
732
if ((proto->options & REGULAR) && n < proto->iz)
733
{
734
proto->flags &= ~MORE;
735
close(proto->fd);
736
}
737
*(ip + n) = 0;
738
if (state & SPLICE)
739
goto fsm_splice;
740
bp = ip;
741
goto fsm_get;
742
}
743
*ip = 0;
744
proto->flags &= ~MORE;
745
close(proto->fd);
746
}
747
if (state & SPLICE)
748
goto fsm_splice;
749
/* NOTE: RECURSIVE lex() should really SLIDE too */
750
if (!(flags & RECURSIVE) && (state = rp[c = EOF]))
751
{
752
bp = ip;
753
goto fsm_next;
754
}
755
SYNC();
756
return 0;
757
758
case S_LITBEG:
759
quot = c;
760
#if PROTOMAIN
761
if (c == '"' && qe)
762
{
763
for (n = 0, t = qe + 1; t < op && (*t == ' ' || *t == '\t' || *t == '\n' && ++n || *t >= 'A' && *t <= 'Z' || *t == '_'); t++);
764
if (t == op)
765
{
766
op = qe;
767
qe = 0;
768
qn = n;
769
}
770
else PUTCHR(c);
771
}
772
else
773
#endif
774
PUTCHR(c);
775
rp = fsm[LIT1];
776
bp = ip;
777
goto fsm_get;
778
779
case S_LITEND:
780
if (c == quot)
781
{
782
#if PROTOMAIN
783
if (!(flags & DIRECTIVE))
784
qe = (c == '"') ? op : (char*)0;
785
#endif
786
PUTCHR(c);
787
#if PROTOMAIN
788
while (qn > 0)
789
{
790
qn--;
791
PUTCHR('\n');
792
}
793
#endif
794
}
795
else if (c != '\n' && c != EOF)
796
{
797
PUTCHR(c);
798
bp = ip;
799
goto fsm_get;
800
}
801
else
802
{
803
#if PROTOMAIN
804
while (qn > 0)
805
{
806
qn--;
807
PUTCHR('\n');
808
}
809
#endif
810
UNGETCHR();
811
}
812
c = T_INVALID;
813
break;
814
815
case S_LITESC:
816
#if PROTOMAIN
817
if (flags & CLASSIC) PUTCHR(c);
818
else
819
#endif
820
switch (c)
821
{
822
case 'a':
823
n = CC_bel;
824
goto fsm_oct;
825
case 'E':
826
n = CC_esc;
827
goto fsm_oct;
828
case 'v':
829
n = CC_vt;
830
goto fsm_oct;
831
case 'x':
832
SYNC();
833
lex(proto, (flags & GLOBAL) | RECURSIVE);
834
for (n = x = 0; (c = GETCHR()), x < 3; x++) switch (c)
835
{
836
case '0': case '1': case '2': case '3':
837
case '4': case '5': case '6': case '7':
838
case '8': case '9':
839
n = (n << 4) + c - '0';
840
break;
841
case 'a': case 'b': case 'c': case 'd':
842
case 'e': case 'f':
843
n = (n << 4) + c - 'a' + 10;
844
break;
845
case 'A': case 'B': case 'C': case 'D':
846
case 'E': case 'F':
847
n = (n << 4) + c - 'A' + 10;
848
break;
849
default:
850
goto fsm_hex;
851
}
852
fsm_hex:
853
UNGETCHR();
854
fsm_oct:
855
PUTCHR(((n >> 6) & 07) + '0');
856
PUTCHR(((n >> 3) & 07) + '0');
857
PUTCHR((n & 07) + '0');
858
break;
859
default:
860
PUTCHR(c);
861
break;
862
}
863
rp = fsm[LIT1];
864
bp = ip;
865
goto fsm_get;
866
867
case S_MACRO:
868
UNGETCHR();
869
#if PROTOMAIN
870
if ((flags & EXTERN) && *proto->tp == 's' && !strncmp(proto->tp, "static", 6))
871
{
872
c = T_EXTERN;
873
break;
874
}
875
#endif
876
if (*proto->tp == '_' && !strncmp(proto->tp, "__STDPP__directive", 6)) c = '#';
877
else c = T_ID;
878
879
break;
880
881
case S_NL:
882
fsm_newline:
883
proto->line++;
884
#if PROTOMAIN
885
if (flags & EXTERN)
886
{
887
if (op != proto->ob && LASTOUT() != ' ' && LASTOUT() != '\n')
888
PUTCHR(' ');
889
}
890
else
891
#endif
892
PUTCHR(c);
893
if (flags & DIRECTIVE)
894
{
895
#if PROTOMAIN
896
if (flags & CLASSIC)
897
{
898
if (flags & EXTERN) BACKOUT();
899
if (flags & JUNK)
900
{
901
*(ip - 1) = 0;
902
op = strcopy(om, "/* ");
903
op = strcopy(op, im);
904
op = strcopy(op, " */\n");
905
}
906
flags &= ~(DEFINE|DIRECTIVE|IDID|INDIRECT|JUNK|MATCH|SHARP|TYPEDEF);
907
}
908
else
909
#endif
910
{
911
if ((flags & (DEFINE|SHARP)) == (DEFINE|SHARP))
912
{
913
*(ip - 1) = 0;
914
op = strcopy(om, "#if defined(__STDC__) || defined(__STDPP__)\n");
915
op = strcopy(op, im);
916
op = strcopy(op, "\n#else\n");
917
bp = ip;
918
ip = im;
919
*op++ = *ip++;
920
while (*op = *ip++)
921
if (*op++ == '#' && *ip != '(')
922
{
923
op--;
924
while (*--op == ' ' || *op == '\t');
925
if (*ip == '#')
926
{
927
op = strcopy(op + 1, "/**/");
928
while (*++ip == ' ' || *ip == '\t');
929
}
930
else
931
{
932
if (*op != '"') *++op = '"';
933
op++;
934
while (*ip == ' ' || *ip == '\t') ip++;
935
while ((c = *ip) >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c == '_') *op++ = *ip++;
936
while (*ip == ' ' || *ip == '\t') ip++;
937
if (*ip == '"') ip++;
938
else *op++ = '"';
939
}
940
}
941
ip = bp;
942
op = strcopy(op, "\n#endif\n");
943
op = linesync(proto, op, proto->line);
944
}
945
flags &= ~(DEFINE|DIRECTIVE|IDID|INDIRECT|MATCH|OTHER|SHARP|SKIP|TOKENS|TYPEDEF);
946
}
947
call = 0;
948
group = 0;
949
paren = 0;
950
last = '\n';
951
}
952
if (paren == 0 && (flags & (MATCH|RECURSIVE|SKIP|SLIDE)) == SLIDE)
953
{
954
#if PROTOMAIN
955
if (flags & EXTERN) BACKOUT();
956
#endif
957
SYNC();
958
return 0;
959
}
960
goto fsm_start;
961
962
case S_QUAL:
963
PUTCHR(c);
964
rp = fsm[NEXT(state)];
965
bp = ip;
966
goto fsm_get;
967
968
case S_TOK:
969
PUTCHR(c);
970
c = TYPE(state);
971
break;
972
973
case S_TOKB:
974
UNGETCHR();
975
c = TYPE(state);
976
break;
977
978
case S_RESERVED:
979
UNGETCHR();
980
c = T_ID;
981
if (!(flags & DECLARE)) switch (RESERVED(*proto->tp, *(ip - 1), ip - proto->tp))
982
{
983
case RESERVED('N', 'N', 3):
984
if (proto->tp[1] == 'o')
985
c = T_DO;
986
break;
987
case RESERVED('d', 'o', 2):
988
c = T_DO;
989
break;
990
case RESERVED('e', 'e', 4):
991
if (!(flags & RECURSIVE) && (flags & (DIRECTIVE|TOKENS)) != DIRECTIVE && !strncmp(proto->tp, "else", 4))
992
{
993
c = T_ELSE;
994
goto fsm_id;
995
}
996
break;
997
case RESERVED('e', 'n', 6):
998
if (!strncmp(proto->tp, "extern", 6))
999
c = T_EXTERN;
1000
break;
1001
case RESERVED('f', 'r', 3):
1002
if (!(flags & RECURSIVE) && !strncmp(proto->tp, "for", 3))
1003
{
1004
c = T_FOR;
1005
goto fsm_id;
1006
}
1007
break;
1008
case RESERVED('i', 'f', 2):
1009
c = T_IF;
1010
break;
1011
case RESERVED('i', 'e', 6):
1012
if (!strncmp(proto->tp, "inline", 6) && !(flags & (MATCH|SKIP|TOKENS|TYPEDEF)) && proto->brace == 0 && paren == 0 && group == 0 && (last == ';' || last == '}' || last == '\n' || last == 0))
1013
{
1014
flags |= SKIP;
1015
SYNC();
1016
line = proto->line;
1017
op = strcopy(op - 6, "__INLINE__");
1018
SYNC();
1019
}
1020
break;
1021
case RESERVED('r', 'n', 6):
1022
if (!(flags & RECURSIVE) && !strncmp(proto->tp, "return", 6))
1023
{
1024
c = T_RETURN;
1025
goto fsm_id;
1026
}
1027
break;
1028
case RESERVED('s', 'c', 6):
1029
if ((proto->options & EXTERNALIZE) && !strncmp(proto->tp, "static", 6))
1030
{
1031
proto->ox = op - 6;
1032
flags |= EXTERNALIZE;
1033
}
1034
break;
1035
case RESERVED('t', 'f', 7):
1036
if (!(flags & RECURSIVE) && !strncmp(proto->tp, "typedef", 7))
1037
{
1038
flags |= TYPEDEF;
1039
c = T_EXTERN;
1040
}
1041
break;
1042
case RESERVED('v', 't', 8):
1043
if (*ip == '(' && !strncmp(proto->tp, "va_start", 8)) c = T_VA_START;
1044
break;
1045
case RESERVED('v', 'd', 4):
1046
if (!strncmp(proto->tp, "void", 4))
1047
{
1048
if (flags & (CLASSIC|PLUSONLY|INIT_DEFINE|INIT_INCLUDE)) c = T_VOID;
1049
else
1050
{
1051
SYNC();
1052
line = proto->line;
1053
if (lex(proto, (flags & GLOBAL) | RECURSIVE) == '*')
1054
{
1055
memcopy(op - 4, "__V_", 4);
1056
memcopy(ip - 4, "__V_", 4);
1057
}
1058
else c = T_VOID;
1059
proto->line = line;
1060
SYNC();
1061
bp = ip;
1062
}
1063
}
1064
break;
1065
case RESERVED('w', 'e', 5):
1066
if (!(flags & RECURSIVE) && !strncmp(proto->tp, "while", 5))
1067
{
1068
c = T_WHILE;
1069
goto fsm_id;
1070
}
1071
break;
1072
}
1073
#if PROTOMAIN
1074
if ((flags & CLASSIC) && c != T_EXTERN)
1075
c = T_ID;
1076
#endif
1077
break;
1078
1079
case S_VS:
1080
goto fsm_start;
1081
1082
case S_WS:
1083
UNGETCHR();
1084
#if PROTOMAIN
1085
if ((flags & (EXTERN|MATCH)) == EXTERN)
1086
{
1087
while (op > proto->ob && (*(op - 1) == ' ' || *(op - 1) == '\t'))
1088
op--;
1089
if (op > proto->ob && *(op - 1) != '\n') *op++ = ' ';
1090
}
1091
#endif
1092
goto fsm_start;
1093
1094
default:
1095
if (state & SPLICE)
1096
{
1097
if (c == '\\')
1098
{
1099
if (!(n = GETCHR()))
1100
{
1101
goto fsm_eob;
1102
fsm_splice:
1103
c = '\\';
1104
n = GETCHR();
1105
}
1106
if (n == '\n')
1107
{
1108
proto->line++;
1109
PUTCHR('\\');
1110
PUTCHR('\n');
1111
bp = ip;
1112
goto fsm_get;
1113
}
1114
UNGETCHR();
1115
}
1116
state &= ~SPLICE;
1117
if (state >= TERMINAL)
1118
goto fsm_terminal;
1119
rp = fsm[state];
1120
}
1121
PUTCHR(c);
1122
bp = ip;
1123
goto fsm_get;
1124
}
1125
if (!(flags & (INIT_DEFINE|INIT_INCLUDE|RECURSIVE)))
1126
{
1127
if (!(flags & DIRECTIVE)) switch (c)
1128
{
1129
case '(':
1130
#if PROTOMAIN
1131
if (!(flags & CLASSIC) || proto->brace == 0)
1132
#endif
1133
{
1134
if (paren++ == 0)
1135
{
1136
#if PROTOMAIN
1137
if (!(flags & CLASSIC) || group <= 1)
1138
#endif
1139
{
1140
#if PROTOMAIN
1141
args = 0;
1142
#endif
1143
if (group++ == 0) group++;
1144
else if (flags & INDIRECT) call++;
1145
flags |= MATCH;
1146
im = ip - 1;
1147
om = op - 1;
1148
}
1149
sub = 0;
1150
}
1151
else if (paren == 2 && !aim)
1152
{
1153
sub++;
1154
if (last == '(')
1155
{
1156
flags &= ~MATCH;
1157
om = 0;
1158
}
1159
else if (flags & INDIRECT)
1160
{
1161
aim = ip - 1;
1162
aom = op - 1;
1163
}
1164
else if ((flags & (MATCH|TOKENS)) == MATCH)
1165
{
1166
for (m = ip - 2; m > im && (*m == ' ' || *m == '\t'); m--);
1167
if (m != im && sub == 1)
1168
{
1169
m = im + (*nns(ip) == '*');
1170
}
1171
if (m == im)
1172
{
1173
flags &= ~MATCH;
1174
om = 0;
1175
}
1176
}
1177
else if ((flags & MATCH) && sub == 1 && *nns(ip) != '*')
1178
{
1179
flags &= ~MATCH;
1180
om = 0;
1181
}
1182
}
1183
flags &= ~TOKENS;
1184
}
1185
break;
1186
case ')':
1187
#if PROTOMAIN
1188
if (!(flags & CLASSIC) || proto->brace == 0)
1189
#endif
1190
if (--paren == 0)
1191
{
1192
#if PROTOMAIN
1193
if (flags & CLASSIC)
1194
{
1195
if (group != 2)
1196
{
1197
c = T_ID;
1198
break;
1199
}
1200
group++;
1201
}
1202
#endif
1203
ie = ip;
1204
}
1205
else if (paren == 1 && (flags & INDIRECT) && !aie)
1206
aie = ip;
1207
break;
1208
case '*':
1209
if (last == '(' && group == 2)
1210
{
1211
group--;
1212
if (paren == 1)
1213
{
1214
flags |= INDIRECT;
1215
aim = aie = 0;
1216
}
1217
}
1218
break;
1219
case '#':
1220
dir = directive(ip, dir);
1221
if (proto->brace == 0 && paren == 0 && last != '=' && (flags & (CLASSIC|DECLARE|DIRECTIVE|MATCH|PLUSONLY|SKIP|TOKENS)) == (MATCH|TOKENS) && ((dir & DIR) != DIR_en || ((dir>>2) & DIR) != DIR_if))
1222
flags |= DIRECTIVE;
1223
else if (!(flags & (DECLARE|DIRECTIVE)))
1224
{
1225
flags |= DIRECTIVE;
1226
if (!(flags & PLUSONLY))
1227
{
1228
bp = ip;
1229
while (*ip == ' ' || *ip == '\t') ip++;
1230
if (*ip == 'l' && *++ip == 'i' && *++ip == 'n' && *++ip == 'e')
1231
{
1232
if (*++ip == ' ' || *ip == '\t')
1233
{
1234
proto->line = 0;
1235
while (*++ip >= '0' && *ip <= '9')
1236
proto->line = proto->line * 10 + *ip - '0';
1237
proto->line--;
1238
}
1239
}
1240
#if PROTOMAIN
1241
else if ((flags & (CLASSIC|EXTERN)) == CLASSIC)
1242
{
1243
n = 0;
1244
t = ip + 6;
1245
while (ip < t && *ip >= 'a' && *ip <= 'z')
1246
n = HASHKEYPART(n, *ip++);
1247
switch (n)
1248
{
1249
case HASHKEY4('e','l','s','e'):
1250
case HASHKEY5('e','n','d','i','f'):
1251
while (*ip == ' ' || *ip == '\t') ip++;
1252
if (*ip != '\n' && *ip != '/' && *(ip + 1) != '*')
1253
{
1254
flags |= JUNK|MATCH;
1255
im = ip;
1256
om = op + (ip - bp);
1257
}
1258
break;
1259
case HASHKEY4('e','l','i','f'):
1260
case HASHKEY5('e','r','r','o','r'):
1261
case HASHKEY2('i','f'):
1262
case HASHKEY5('i','f','d','e','f'):
1263
case HASHKEY6('i','f','n','d','e','f'):
1264
case HASHKEY5('u','n','d','e','f'):
1265
break;
1266
case HASHKEY6('i','n','c','l','u','d'):
1267
if (*ip == 'e') ip++;
1268
/*FALLTHROUGH*/
1269
case HASHKEY6('d','e','f','i','n','e'):
1270
case HASHKEY6('p','r','a','g','m','a'):
1271
if (*ip < 'a' || *ip > 'z') break;
1272
/*FALLTHROUGH*/
1273
default:
1274
flags |= JUNK|MATCH;
1275
im = bp - 1;
1276
om = op - 1;
1277
break;
1278
}
1279
}
1280
else
1281
#endif
1282
{
1283
if (*ip == 'i' && *++ip == 'n' && *++ip == 'c' && *++ip == 'l' && *++ip == 'u' && *++ip == 'd' && *++ip == 'e')
1284
{
1285
while (*++ip == ' ' || *ip == '\t');
1286
if (*ip++ == '<' && *ip++ == 's' && *ip++ == 't' && *ip++ == 'd' && *ip++ == 'a' && *ip++ == 'r' && *ip++ == 'g' && *ip++ == '.' && *ip++ == 'h' && *ip++ == '>')
1287
{
1288
op = strcopy(op, "\
1289
if !defined(va_start)\n\
1290
#if defined(__STDARG__)\n\
1291
#include <stdarg.h>\n\
1292
#else\n\
1293
#include <varargs.h>\n\
1294
#endif\n\
1295
#endif\n\
1296
");
1297
op = linesync(proto, op, proto->line);
1298
break;
1299
}
1300
}
1301
else if (*ip == 'd' && *++ip == 'e' && *++ ip == 'f' && *++ip == 'i' && *++ip == 'n' && *++ip == 'e' && (*++ip == ' ' || *ip == '\t'))
1302
{
1303
while (*++ip == ' ' || *ip == '\t');
1304
if (*ip == 'e' && *++ip == 'x' && *++ ip == 't' && *++ip == 'e' && *++ip == 'r' && *++ip == 'n' && (*++ip == ' ' || *ip == '\t'))
1305
{
1306
t = ip;
1307
while (*++t == ' ' || *t == '\t');
1308
if (*t == 'e' && *++t == 'x' && *++ t == 't' && *++t == 'e' && *++t == 'r' && *++t == 'n' && (*++t == ' ' || *t == '\t' || *t == '\n' || *t == '\r'))
1309
ip = t;
1310
t = ip;
1311
while (*++t == ' ' || *t == '\t');
1312
if (*t == '_' && *(t + 1) == '_')
1313
{
1314
op = strcopy(op, "undef __MANGLE__\n");
1315
op = linesync(proto, op, proto->line);
1316
op = strcopy(op, "#define __MANGLE__ __LINKAGE__");
1317
break;
1318
}
1319
}
1320
flags |= DEFINE|MATCH;
1321
im = bp - 1;
1322
om = op - 1;
1323
}
1324
else if (*ip == 'u' && *++ip == 'n' && *++ ip == 'd' && *++ip == 'e' && *++ip == 'f' && (*++ip == ' ' || *ip == '\t'))
1325
{
1326
while (*++ip == ' ' || *ip == '\t');
1327
if (*ip == 'e' && *++ip == 'x' && *++ ip == 't' && *++ip == 'e' && *++ip == 'r' && *++ip == 'n' && (*++ip == ' ' || *ip == '\t' || *ip == '\n' || *ip == '\r'))
1328
{
1329
op = strcopy(op, "undef __MANGLE__\n");
1330
op = linesync(proto, op, proto->line);
1331
op = strcopy(op, "#define __MANGLE__ __LINKAGE__");
1332
break;
1333
}
1334
flags |= DEFINE|MATCH;
1335
im = bp - 1;
1336
om = op - 1;
1337
}
1338
}
1339
ip = bp;
1340
}
1341
break;
1342
}
1343
else
1344
break;
1345
/*FALLTHROUGH*/
1346
case '{':
1347
if (proto->brace++ == 0 && paren == 0)
1348
{
1349
if (last == '=') flags |= INIT;
1350
#if PROTOMAIN
1351
else if (flags & CLASSIC)
1352
{
1353
if ((flags & (MATCH|OTHER|SKIP)) == MATCH)
1354
{
1355
if (args)
1356
{
1357
v = number(op, args < 0 ? -args : args);
1358
v = strcopy(v, " argument actual/formal mismatch");
1359
*v++ = ' ';
1360
v = memcopy(v, im, ie - im);
1361
*v = 0;
1362
proto_error((char*)proto + sizeof(Proto_t), 2, op, NiL);
1363
}
1364
ip--;
1365
/*UNDENT...*/
1366
v = ie;
1367
while (ie < ip)
1368
if (*ie++ == '/' && *ie == '*')
1369
{
1370
e = ie - 1;
1371
while (++ie < ip)
1372
{
1373
if (*ie == '*')
1374
{
1375
while (ie < ip && *ie == '*') ie++;
1376
if (ie < ip && *ie == '/')
1377
{
1378
while (++ie < ip && (*ie == ' ' || *ie == '\t'));
1379
while (e > v && (*(e - 1) == ' ' || *(e - 1) == '\t')) e--;
1380
if (e > v && *e != '\n') *e++ = ' ';
1381
t = ie;
1382
while (--e >= v)
1383
*--t = *e;
1384
v = t;
1385
break;
1386
}
1387
}
1388
}
1389
}
1390
ie = v;
1391
/*...INDENT*/
1392
op = om++;
1393
if (flags & EXTERN)
1394
{
1395
v = op;
1396
while (v > ko && *--v != ' ');
1397
if (*v != ' ')
1398
{
1399
om = (v = (op += 4)) + 1;
1400
while (v >= ko + 4)
1401
{
1402
*v = *(v - 4);
1403
v--;
1404
}
1405
memcopy(ko, "int ", 4);
1406
}
1407
if (*v == ' ')
1408
{
1409
while (*(v + 1) == '*')
1410
*v++ = '*';
1411
*v = '\t';
1412
if ((v - ko) <= 8)
1413
{
1414
om = (e = ++op) + 1;
1415
while (e > v)
1416
{
1417
*e = *(e - 1);
1418
e--;
1419
}
1420
}
1421
}
1422
om = (v = (op += 7)) + 1;
1423
while (v >= ko + 7)
1424
{
1425
*v = *(v - 7);
1426
v--;
1427
}
1428
memcopy(ko, "extern ", 7);
1429
}
1430
PUTCHR('(');
1431
t = op;
1432
e = 0;
1433
/*UNDENT...*/
1434
while (ie < ip)
1435
{
1436
if ((c = *ie) == ' ' || c == '\t' || c == '\n')
1437
{
1438
while ((c = *++ie) == ' ' || c == '\t' || c == '\n');
1439
if (ie >= ip) break;
1440
if (c != '*' && op > om) PUTCHR(' ');
1441
}
1442
if ((n = ((c = *ie) == ',')) || c == ';')
1443
{
1444
if (flags & EXTERN)
1445
{
1446
m = op;
1447
while (op > om && ((c = *(op - 1)) == '(' || c == ')' || c == '[' || c == ']'))
1448
op--;
1449
v = op;
1450
while (op > om && (c = *(op - 1)) != ' ' && c != '*')
1451
op--;
1452
while (*(op - 1) == ' ')
1453
op--;
1454
if (!e)
1455
{
1456
e = op;
1457
while (e > om && *(e - 1) == '*')
1458
e--;
1459
}
1460
#if _s5r4_386_compiler_bug_fixed_
1461
if (op <= om || *(op - 1) == ',' && (*op++ = ' '))
1462
op = strcopy(op, "int");
1463
#else
1464
if (op <= om)
1465
op = strcopy(op, "int");
1466
else if (*(op - 1) == ',')
1467
op = strcopy(op, " int");
1468
#endif
1469
while (v < m)
1470
PUTCHR(*v++);
1471
}
1472
PUTCHR(',');
1473
if (n)
1474
{
1475
if (x = !e) e = op - 1;
1476
PUTCHR(' ');
1477
m = t;
1478
while (m < e)
1479
PUTCHR(*m++);
1480
if (x)
1481
{
1482
m = e;
1483
while (*--e != ' ');
1484
while (*(e - 1) == '*') e--;
1485
op -= m - e;
1486
}
1487
}
1488
while ((c = *++ie) == ' ' || c == '\t' || c == '\n');
1489
if (ie >= ip) UNPUTCHR();
1490
else PUTCHR(' ');
1491
if (!n)
1492
{
1493
t = op;
1494
e = 0;
1495
}
1496
}
1497
else if (*ie == '*')
1498
{
1499
if (op > om && (c = *(op - 1)) == ' ') op--;
1500
while (*ie == '*') PUTCHR(*ie++);
1501
while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++;
1502
if (c != '(') PUTCHR(' ');
1503
}
1504
else if (*ie == '(')
1505
{
1506
if (op > om && *(op - 1) == ' ') op--;
1507
PUTCHR(*ie++);
1508
while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++;
1509
}
1510
else if (*ie == ')')
1511
{
1512
if (op > om && *(op - 1) == '(')
1513
proto_error((char*)proto + sizeof(Proto_t), 1, "function pointer argument prototype omitted", NiL);
1514
PUTCHR(*ie++);
1515
while (*ie == ' ' || *ie == '\t' || *ie == '\n') ie++;
1516
}
1517
else if ((flags & EXTERN) && (op == om || *(op - 1) == ' ') && *ie == 'r' && !strncmp(ie, "register", 8) && (*(ie + 8) == ' ' || *(ie + 8) == '\t' || *(ie + 8) == '\n'))
1518
{
1519
ie += 8;
1520
if (op > om) UNPUTCHR();
1521
}
1522
else PUTCHR(*ie++);
1523
}
1524
/*...INDENT*/
1525
if (op <= om) op = strcopy(op, "void");
1526
PUTCHR(')');
1527
if (flags & EXTERN)
1528
{
1529
PUTCHR(';');
1530
PUTCHR('\n');
1531
SYNCOUT();
1532
KEEPOUT();
1533
}
1534
else
1535
{
1536
PUTCHR('\n');
1537
PUTCHR(*ip);
1538
}
1539
ip++;
1540
flags &= ~(MATCH|SKIP);
1541
}
1542
}
1543
#endif
1544
else if ((flags & (MATCH|PLUSONLY|SKIP|TOKENS)) == (MATCH|TOKENS))
1545
{
1546
line = proto->line;
1547
op = strcopy(om, " __PARAM__(");
1548
op = memcopy(op, im, ie - im);
1549
PUTCHR(',');
1550
PUTCHR(' ');
1551
PUTCHR('(');
1552
flags &= ~(MATCH|SKIP);
1553
if (flags & VARIADIC)
1554
{
1555
if ((vc = ie - im + 1) > sizeof(proto->variadic)) vc = sizeof(proto->variadic);
1556
memcopy(proto->variadic, im, vc);
1557
op = strcopy(op, "va_alist)) __OTORP__(va_dcl)\n{");
1558
}
1559
else
1560
{
1561
flags |= SKIP;
1562
proto->ip = im;
1563
proto->op = op;
1564
group = 0;
1565
brack = 0;
1566
for (;;)
1567
{
1568
switch (lex(proto, (flags & GLOBAL) | RECURSIVE))
1569
{
1570
case '[':
1571
brack++;
1572
continue;
1573
case ']':
1574
brack--;
1575
continue;
1576
case '(':
1577
if (paren++) group++;
1578
continue;
1579
case ')':
1580
if (--paren == 0)
1581
{
1582
group = 0;
1583
if (flags & MATCH)
1584
{
1585
flags &= ~(MATCH|SKIP);
1586
op = memcopy(op, m, e - m);
1587
}
1588
break;
1589
}
1590
continue;
1591
case ',':
1592
if (paren == 1)
1593
{
1594
group = 0;
1595
if (flags & MATCH)
1596
{
1597
flags &= ~(MATCH|SKIP);
1598
op = memcopy(op, m, e - m);
1599
}
1600
PUTCHR(',');
1601
PUTCHR(' ');
1602
proto->op = op;
1603
}
1604
continue;
1605
case T_ID:
1606
if (group <= 1 && !brack)
1607
{
1608
flags |= MATCH;
1609
m = proto->tp;
1610
e = proto->ip;
1611
}
1612
continue;
1613
default:
1614
continue;
1615
}
1616
break;
1617
}
1618
PUTCHR(')');
1619
PUTCHR(')');
1620
}
1621
if (!(flags & SKIP))
1622
{
1623
flags |= SKIP;
1624
proto->op = strcopy(op, " __OTORP__(");
1625
proto->ip = im + 1;
1626
n = *(ie - 1);
1627
*(ie - 1) = ';';
1628
c = *ie;
1629
*ie = 0;
1630
lex(proto, (flags & GLOBAL) | DECLARE);
1631
*(ie - 1) = n;
1632
*ie = c;
1633
proto->ip = ie;
1634
op = proto->op;
1635
PUTCHR(')');
1636
}
1637
if (flags & EXTERNALIZE) memcpy(proto->ox, "extern", 6);
1638
op = linesync(proto, op, proto->line = line);
1639
if (flags & DIRECTIVE)
1640
{
1641
proto->brace = 0;
1642
PUTCHR('\n');
1643
PUTCHR('#');
1644
}
1645
else if (!(flags & VARIADIC)) PUTCHR('{');
1646
}
1647
}
1648
flags &= ~(IDID|INDIRECT|MATCH|OTHER|SKIP);
1649
call = 0;
1650
group = 0;
1651
break;
1652
case '}':
1653
flags &= ~(IDID|INDIRECT|MATCH|OTHER|SKIP|TOKENS);
1654
if (--proto->brace == 0)
1655
{
1656
flags &= ~(INIT|VARIADIC|VARIADIC2);
1657
#if PROTOMAIN
1658
if (flags & EXTERN) BACKOUT();
1659
#endif
1660
}
1661
call = 0;
1662
group = 0;
1663
paren = 0;
1664
break;
1665
case '=':
1666
if (last == '?') flags |= DIRECTIVE;
1667
else if (paren == 0 && (flags & (INIT|MATCH|SKIP)) == MATCH)
1668
{
1669
if (last == ')' && proto->brace && (group != 2 || call != 2)) flags |= SKIP;
1670
else goto fsm_statement;
1671
}
1672
goto fsm_other;
1673
case ',':
1674
#if PROTOMAIN
1675
if (flags & CLASSIC)
1676
{
1677
if (paren == 1) args++;
1678
else
1679
{
1680
args--;
1681
flags &= ~MATCH;
1682
}
1683
break;
1684
}
1685
#endif
1686
if (paren == 0 && (flags & DECLARE)) *(op - 1) = c = ';';
1687
/*FALLTHROUGH*/
1688
case ';':
1689
fsm_statement:
1690
if (flags & INIT) /* ignore */;
1691
#if PROTOMAIN
1692
else if (flags & CLASSIC)
1693
{
1694
if (paren == 0)
1695
{
1696
if ((flags & MATCH) && last == ')')
1697
flags &= ~MATCH;
1698
if (!(flags & MATCH))
1699
{
1700
call = 0;
1701
group = 0;
1702
flags &= ~SKIP;
1703
if (flags & EXTERN) BACKOUT();
1704
if (flags & SLIDE)
1705
{
1706
SYNC();
1707
return 0;
1708
}
1709
}
1710
else
1711
{
1712
args--;
1713
if ((flags & (EXTERN|SKIP)) == (EXTERN|SKIP))
1714
BACKOUT();
1715
}
1716
}
1717
}
1718
#endif
1719
else if (paren == 0)
1720
{
1721
if ((flags & (MATCH|OTHER|SKIP)) == MATCH && call > 1)
1722
{
1723
if ((flags & MANGLE) && func)
1724
{
1725
func[0] = 'F';
1726
func[1] = 'U';
1727
func[2] = 'N';
1728
func[3] = 'C';
1729
func = 0;
1730
}
1731
if ((flags & (DECLARE|INDIRECT)) == INDIRECT && aim && aie < im)
1732
{
1733
while (aie < ip && (*aie == ' ' || *aie == '\t' || *aie == '\n')) aie++;
1734
v = aim;
1735
while (v < aie)
1736
if (*v++ == ')') break;
1737
while (v < aie && (*v == ' ' || *v == '\t' || *v == '\n')) v++;
1738
if (v == aie || !(flags & PLUSPLUS))
1739
{
1740
if (flags & PLUSPLUS) n = 3;
1741
else if (v == aie && *v == '(') n = 10;
1742
else n = 11;
1743
ko = op;
1744
om += n;
1745
v = op += n;
1746
while (v >= ko + n)
1747
{
1748
*v = *(v - n);
1749
v--;
1750
}
1751
if (flags & PLUSPLUS) memcopy(aom, "(...))", 6);
1752
else if (n == 10) memcopy(aom, "(__VARARG__))", 13);
1753
else
1754
{
1755
ko = strcopy(aom, " __PROTO__(");
1756
ko = memcopy(ko, aim, aie - aim);
1757
*ko = ')';
1758
if (++ko >= om)
1759
{
1760
*ko++ = ')';
1761
om = ko;
1762
}
1763
}
1764
}
1765
}
1766
else if (flags & TYPEDEF)
1767
{
1768
op = om;
1769
while (*--op == ' ' || *op == '\t' || *op == '\n');
1770
if (*op != ')')
1771
{
1772
op = om += 14;
1773
*--op = ')';
1774
while ((x = *(op - 14)) >= 'A' && x <= 'Z' || x >= 'a' && x <= 'z' || x >= '0' && x <= '9' || x == '_')
1775
*--op = x;
1776
memcopy(op - 13, "(__OTORP__(*)", 13);
1777
}
1778
}
1779
if (flags & OTHER)
1780
;
1781
else if (flags & PLUSPLUS)
1782
{
1783
op = om;
1784
if (!(flags & TOKENS)) op = strcopy(op, "(...)");
1785
else op = memcopy(op, im, ie - im);
1786
PUTCHR(c);
1787
}
1788
else
1789
{
1790
if (flags & DECLARE) op = strcopy(om, "()");
1791
else if (!(flags & TOKENS)) op = strcopy(om, "(__VARARG__)");
1792
else
1793
{
1794
op = strcopy(om, " __PROTO__(");
1795
op = memcopy(op, im, ie - im);
1796
PUTCHR(')');
1797
}
1798
if (flags & EXTERNALIZE) memcpy(proto->ox, "extern", 6);
1799
PUTCHR(c);
1800
}
1801
flags &= ~(MATCH|VARIADIC|VARIADIC2);
1802
if (c == ',' && !(flags & INDIRECT))
1803
{
1804
call = 1;
1805
group = 0;
1806
break;
1807
}
1808
}
1809
else if (flags & (OTHER|SKIP)) call = 0;
1810
if (c == ';')
1811
{
1812
flags &= ~(EXTERNALIZE|MANGLE|TOKENS|TYPEDEF);
1813
call = 0;
1814
if (flags & SLIDE)
1815
{
1816
SYNC();
1817
return 0;
1818
}
1819
}
1820
else call = call > 1 && c == ',';
1821
group = 0;
1822
flags &= ~(IDID|INDIRECT|MATCH|OTHER|SKIP);
1823
}
1824
else if (paren == 1 && group == 1 && !(flags & (IDID|MANGLE))) flags |= TOKENS|OTHER;
1825
break;
1826
case T_DO:
1827
case T_IF:
1828
flags |= TOKENS|SKIP;
1829
break;
1830
case T_EXTERN:
1831
#if PROTOMAIN
1832
if (flags & CLASSIC)
1833
{
1834
if (proto->brace == 0)
1835
flags |= SKIP;
1836
}
1837
else
1838
#endif
1839
if (paren == 0 && !(flags & TYPEDEF))
1840
{
1841
flags |= MANGLE;
1842
if (!(flags & PLUSONLY) || proto->package)
1843
{
1844
op = strcopy(op, " __MANGLE__");
1845
if (proto->package)
1846
{
1847
op = strcopy(op - 1, proto->package);
1848
func = op + 1;
1849
op = strcopy(op, "_DATA__");
1850
}
1851
}
1852
else
1853
func = 0;
1854
}
1855
break;
1856
case T_VARIADIC:
1857
if (paren == 0 && (flags & (DECLARE|VARIADIC)) == DECLARE)
1858
{
1859
op -= 3;
1860
SYNC();
1861
return c;
1862
}
1863
if (paren == 1 && !(flags & SKIP))
1864
flags |= VARIADIC;
1865
flags |= TOKENS;
1866
break;
1867
case T_VOID:
1868
goto fsm_id;
1869
case T_VA_START:
1870
if ((flags & (PLUSONLY|VARIADIC)) == VARIADIC)
1871
{
1872
flags &= ~MATCH;
1873
line = proto->line;
1874
op = strcopy(op - 8, "__VA_START__");
1875
SYNC();
1876
for (;;)
1877
{
1878
switch (lex(proto, (flags & GLOBAL) | RECURSIVE))
1879
{
1880
case 0:
1881
case ';':
1882
break;
1883
case T_ID:
1884
if (!(flags & MATCH))
1885
{
1886
flags |= MATCH;
1887
m = proto->tp;
1888
e = proto->ip;
1889
}
1890
continue;
1891
default:
1892
continue;
1893
}
1894
break;
1895
}
1896
CACHE();
1897
if (flags & MATCH)
1898
{
1899
v = m;
1900
n = e - m;
1901
}
1902
else
1903
{
1904
v = "ap";
1905
n = 2;
1906
}
1907
op = strcopy(op, " __OTORP__(");
1908
proto->ip = proto->variadic;
1909
proto->op = op;
1910
flags &= ~MATCH;
1911
group = 0;
1912
bp = proto->ip + 1;
1913
if (*bp == 'r' && !strncmp(bp, "register", 8) && (*(bp + 8) == ' ' || *(bp + 8) == '\t')) bp += 9;
1914
for (;;)
1915
{
1916
switch (lex(proto, (flags & GLOBAL) | RECURSIVE))
1917
{
1918
case '(':
1919
if (paren++) group++;
1920
continue;
1921
case ')':
1922
if (--paren == 0)
1923
{
1924
if (flags & MATCH)
1925
{
1926
flags &= ~MATCH;
1927
if (!(flags & VARIADIC2))
1928
{
1929
op = memcopy(op, m, e - m);
1930
op = strcopy(op, " = ");
1931
}
1932
op = strcopy(op, "va_arg(");
1933
op = memcopy(op, v, n);
1934
PUTCHR(',');
1935
PUTCHR(' ');
1936
if (m > bp) op = memcopy(op, bp, m - bp);
1937
else op = strcopy(op, "int ");
1938
if (group > 1) op = strcopy(op, ")()");
1939
else op = memcopy(op, e, proto->ip - e - 1);
1940
PUTCHR(')');
1941
PUTCHR(';');
1942
}
1943
group = 0;
1944
break;
1945
}
1946
continue;
1947
case ',':
1948
if (paren == 1)
1949
{
1950
if (flags & MATCH)
1951
{
1952
flags &= ~MATCH;
1953
if (!(flags & VARIADIC2))
1954
{
1955
op = memcopy(op, m, e - m);
1956
op = strcopy(op, " = ");
1957
}
1958
op = strcopy(op, "va_arg(");
1959
op = memcopy(op, v, n);
1960
PUTCHR(',');
1961
PUTCHR(' ');
1962
if (m > bp) op = memcopy(op, bp, m - bp);
1963
else op = strcopy(op, "int ");
1964
if (group > 1) op = strcopy(op, ")()");
1965
else op = memcopy(op, e, proto->ip - e - 1);
1966
PUTCHR(')');
1967
PUTCHR(';');
1968
bp = proto->ip + 1;
1969
if (*bp == 'r' && !strncmp(bp, "register", 8) && (*(bp + 8) == ' ' || *(bp + 8) == '\t')) bp += 9;
1970
}
1971
group = 0;
1972
proto->op = op;
1973
}
1974
continue;
1975
case T_ID:
1976
if (group <= 1)
1977
{
1978
flags |= MATCH;
1979
m = proto->tp;
1980
e = proto->ip;
1981
}
1982
continue;
1983
default:
1984
continue;
1985
}
1986
break;
1987
}
1988
op = strcopy(op, ")");
1989
flags |= VARIADIC2;
1990
proto->line = line;
1991
call = 0;
1992
break;
1993
}
1994
/*FALLTHROUGH*/
1995
case T_ID:
1996
fsm_id:
1997
#if PROTOMAIN
1998
if (flags & CLASSIC)
1999
{
2000
if (!args && paren == 1) args++;
2001
break;
2002
}
2003
#endif
2004
if (paren == 0)
2005
{
2006
if (last == ')')
2007
{
2008
if (proto->brace == 0 && !(flags & DECLARE)) flags |= SKIP;
2009
call = !call;
2010
}
2011
else if ((flags & SKIP) || c == T_ID || c == T_VOID) call++;
2012
else flags |= SKIP;
2013
if (last == T_ID) flags |= IDID;
2014
}
2015
c = T_ID;
2016
flags |= TOKENS;
2017
break;
2018
case T_INVALID:
2019
if (*proto->tp >= '0' && *proto->tp <= '9')
2020
{
2021
n = 0;
2022
for (;; op--)
2023
{
2024
switch (*(op - 1))
2025
{
2026
case 'f':
2027
case 'F':
2028
t = op;
2029
while ((c = *--t) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
2030
if (*t == '.')
2031
op--;
2032
n = 0;
2033
break;
2034
case 'l':
2035
case 'L':
2036
if (!(n & 01))
2037
{
2038
n |= 01;
2039
t = op;
2040
while ((c = *--t) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
2041
if (*t == '.')
2042
{
2043
n = 0;
2044
op--;
2045
break;
2046
}
2047
}
2048
continue;
2049
case 'u':
2050
case 'U':
2051
n |= 02;
2052
continue;
2053
}
2054
break;
2055
}
2056
if (n & 01)
2057
*op++ = 'L';
2058
if (n & 02)
2059
{
2060
m = op;
2061
t = op = m + 10;
2062
while ((c = *--m) >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
2063
*--t = c;
2064
c = *t;
2065
strcopy(m + 1, "(unsigned)");
2066
*t = c;
2067
break;
2068
}
2069
}
2070
goto fsm_other;
2071
#if PROTOMAIN
2072
case '[':
2073
if ((flags & CLASSIC) && paren == 0 && group <= 2) flags |= SKIP;
2074
/*FALLTHROUGH*/
2075
#endif
2076
default:
2077
fsm_other:
2078
#if PROTOMAIN
2079
if (flags & CLASSIC) break;
2080
#endif
2081
flags |= TOKENS;
2082
if (paren == 0) flags |= OTHER;
2083
break;
2084
}
2085
else if (c == '#' && *ip != '(') flags |= SHARP;
2086
last = c;
2087
#if PROTOMAIN
2088
if ((flags & (EXTERN|MATCH)) == (EXTERN|MATCH) && ((flags & (DIRECTIVE|SKIP)) || proto->brace || c != '(' && c != ')' && c != '*' && c != T_ID))
2089
CACHEOUT();
2090
else
2091
#endif
2092
SYNCOUT();
2093
goto fsm_start;
2094
}
2095
else if (flags & (INIT_DEFINE|INIT_INCLUDE))
2096
{
2097
#if PROTOMAIN
2098
if ((flags & YACC) && c == '%' && *ip == '{')
2099
t = 0;
2100
else
2101
#endif
2102
{
2103
if (c == '#')
2104
{
2105
for (t = ip; *t == ' ' || *t == '\t'; t++);
2106
if (*t++ == 'i' && *t++ == 'f' && *t++ == 'n' && *t++ == 'd' && *t++ == 'e' && *t++ == 'f')
2107
{
2108
#if !PROTOMAIN
2109
while (*t == ' ' || *t == '\t') t++;
2110
if (*t != '_')
2111
#endif
2112
t = 0;
2113
}
2114
}
2115
else
2116
t = "";
2117
}
2118
if (t)
2119
{
2120
#if PROTOMAIN
2121
n = ip - proto->tp;
2122
ip -= n;
2123
op -= n;
2124
#else
2125
ip = bp;
2126
op = proto->op;
2127
#endif
2128
}
2129
else
2130
while (*ip != '\n')
2131
*op++ = *ip++;
2132
op = init(proto, op, flags);
2133
op = linesync(proto, op, proto->line);
2134
flags &= ~(INIT_DEFINE|INIT_INCLUDE);
2135
proto->flags &= ~(INIT_DEFINE|INIT_INCLUDE);
2136
goto fsm_start;
2137
}
2138
SYNC();
2139
return c;
2140
}
2141
2142
/*
2143
* close a proto buffer stream
2144
*/
2145
2146
void
2147
pppclose(char* iob)
2148
{
2149
register Proto_t* proto = (Proto_t*)(iob - sizeof(Proto_t));
2150
2151
if (proto->flags & MORE) close(proto->fd);
2152
free((char*)proto); /* some ANSI cc's botch the free() prototype */
2153
}
2154
2155
/*
2156
* open a new proto buffer stream
2157
* read buffer pointer returned
2158
* 0 returned on error or if no magic
2159
*
2160
* file !=0 file path to open, otherwise use fd
2161
* fd open file fd if file==0
2162
* notice !=0 copyright notice info commented at the top
2163
* options !=0 additional notice name=value pairs, space or ; separated
2164
* package !=0 generate header for this package
2165
*/
2166
2167
char*
2168
pppopen(char* file, int fd, char* notice, char* options, char* package, char* comment, int flags)
2169
{
2170
register Proto_t* proto;
2171
register char* iob;
2172
register long n;
2173
register char* s;
2174
char* t;
2175
int pragma;
2176
int clr;
2177
int hit;
2178
int i;
2179
int z;
2180
char* b;
2181
#if PROTOMAIN
2182
int comlen;
2183
char com[80];
2184
#endif
2185
int m = 0;
2186
2187
static int retain;
2188
2189
/*
2190
* initialize proto
2191
*/
2192
2193
#if PROTOMAIN
2194
if (flags & PROTO_CLASSIC) flags &= ~PROTO_INCLUDE;
2195
#endif
2196
if (flags & PROTO_RETAIN) flags &= ~retain;
2197
else retain &= PROTO_INITIALIZED;
2198
if (file && (fd = open(file, O_RDONLY)) < 0) return 0;
2199
#if !PROTOMAIN
2200
if ((n = lseek(fd, 0L, 2)) > 0)
2201
{
2202
if (lseek(fd, 0L, 0)) return 0;
2203
if (n < CHUNK) n = CHUNK;
2204
else if (n > 2 * BLOCK) n = 0;
2205
m = 1;
2206
}
2207
if (n > 0)
2208
{
2209
/*
2210
* file read in one chunk
2211
*/
2212
2213
if (!(proto = newof(0, Proto_t, 1, 4 * n + 2)))
2214
return 0;
2215
proto->iz = n;
2216
proto->oz = 3 * n;
2217
n = 0;
2218
}
2219
else
2220
#endif
2221
{
2222
/*
2223
* file read in BLOCK chunks
2224
*/
2225
2226
n = BLOCK;
2227
if (!(proto = newof(0, Proto_t, 1, 5 * n + 2)))
2228
return 0;
2229
proto->iz = n;
2230
proto->oz = 3 * n;
2231
proto->flags |= MORE;
2232
}
2233
proto->fd = fd;
2234
proto->package = package;
2235
iob = (char*)proto + sizeof(Proto_t);
2236
proto->op = proto->ob = iob;
2237
proto->ip = proto->ib = iob + proto->oz + n;
2238
if (m) proto->options |= REGULAR;
2239
if (!comment)
2240
comment = "/*";
2241
if (!(proto->cc[0] = comment[0]))
2242
notice = options = 0;
2243
else if (comment[1])
2244
{
2245
proto->cc[1] = comment[1];
2246
proto->cc[2] = comment[2] ? comment[2] : comment[0];
2247
}
2248
else
2249
proto->cc[1] = proto->cc[2] = comment[0];
2250
2251
/*
2252
* read the first chunk
2253
*/
2254
2255
n = read(fd, proto->ip, proto->iz);
2256
if (!(proto->flags & MORE))
2257
close(fd);
2258
if (n < 0)
2259
{
2260
pppclose(iob);
2261
return 0;
2262
}
2263
*(proto->ip + n) = 0;
2264
2265
/*
2266
* check for proto pragma in first block of lines
2267
* pragma blanked out if found
2268
*
2269
* -1 no pragma
2270
* 0 #pragma noprototyped
2271
* 1 #pragma prototyped
2272
*
2273
* NOTE: matches may occur inside comments and quotes
2274
*/
2275
2276
#if PROTOMAIN
2277
if (!notice && !options || (comlen = astlicense(com, sizeof(com), NiL, "type=check", proto->cc[0], proto->cc[1], proto->cc[2])) <= 0)
2278
*com = 0;
2279
#endif
2280
hit = (notice || options) ? 0 : HIT_noticed;
2281
pragma = -1;
2282
s = proto->ip;
2283
m = MAGICTOP;
2284
while (m-- > 0 && *s && hit != (HIT_prototyped|HIT_noticed))
2285
{
2286
while (*s == ' ' || *s == '\t')
2287
s++;
2288
if (*s == '#')
2289
{
2290
b = s++;
2291
while (*s == ' ' || *s == '\t')
2292
s++;
2293
if (*s == *PRAGMADIR && !strncmp(s, PRAGMADIR, sizeof(PRAGMADIR) - 1) && (*(s += sizeof(PRAGMADIR) - 1) == ' ' || *s == '\t'))
2294
{
2295
clr = 0;
2296
while (*s && *s != '\r' && *s != '\n')
2297
{
2298
for (; *s == ' ' || *s == '\t'; s++);
2299
for (t = s; *s && *s != ' ' && *s != '\t' && *s != '\r' && *s != '\n'; s++);
2300
z = s - t;
2301
for (i = 0; i < elementsof(pragmas); i++)
2302
if (pragmas[i].size == z && !strncmp(t, pragmas[i].name, z))
2303
{
2304
clr = 1;
2305
hit |= pragmas[i].hit;
2306
switch (pragmas[i].hit)
2307
{
2308
case HIT_noticed:
2309
notice = options = 0;
2310
break;
2311
case HIT_prototyped:
2312
pragma = pragmas[i].val;
2313
break;
2314
}
2315
}
2316
}
2317
if (clr)
2318
{
2319
#if PROTOMAIN
2320
if (!(flags & PROTO_DISABLE) || (flags & PROTO_NOPRAGMA))
2321
#endif
2322
for (; b < s; *b++ = ' ');
2323
}
2324
}
2325
}
2326
else if (*s == *GENERATED && !strncmp(s, GENERATED, sizeof(GENERATED) - 1))
2327
{
2328
pragma = 0;
2329
break;
2330
}
2331
#if PROTOMAIN
2332
else if (*s == '%' && *(s + 1) == '{')
2333
proto->flags |= YACC;
2334
else if (!(hit & HIT_noticed))
2335
{
2336
if (*s == *com && !strncmp(s, com, comlen))
2337
{
2338
hit |= HIT_noticed;
2339
notice = options = 0;
2340
}
2341
else
2342
for (; *s && *s != '\n' && !(hit & HIT_noticed); s++)
2343
for (i = 0; i < elementsof(notices); i++)
2344
if (*s == notices[i].name[0] && !strncmp(s, notices[i].name, notices[i].size))
2345
{
2346
s += notices[i].size;
2347
if (notices[i].val)
2348
{
2349
while (*s == ' ' || *s == '\t')
2350
s++;
2351
if (*s == '(' && (*(s + 1) == 'c' || *(s + 1) == 'C') && *(s + 2) == ')' || *s >= '0' && *s <= '9' && *(s + 1) >= '0' && *(s + 1) <= '9')
2352
{
2353
hit |= notices[i].hit;
2354
notice = options = 0;
2355
}
2356
}
2357
else
2358
{
2359
hit |= notices[i].hit;
2360
notice = options = 0;
2361
}
2362
break;
2363
}
2364
}
2365
#endif
2366
while (*s && *s++ != '\n');
2367
}
2368
if (flags & PROTO_PLUSPLUS) proto->flags |= PLUSPLUS;
2369
if (flags & PROTO_TEST) proto->test = 1;
2370
if (flags & PROTO_EXTERNALIZE) proto->options |= EXTERNALIZE;
2371
#if PROTOMAIN
2372
if (flags & PROTO_CLASSIC) pragma = -pragma;
2373
if (flags & PROTO_DISABLE) pragma = 0;
2374
if (flags & PROTO_LINESYNC) proto->flags |= LINESYNC;
2375
if (!(proto->flags & YACC) && file && (m = strlen(file)) > 2 && file[--m] == 'y' && file[--m] == '.')
2376
proto->flags |= YACC;
2377
#endif
2378
if (pragma <= 0)
2379
{
2380
if (flags & PROTO_PLUSPLUS)
2381
{
2382
flags &= ~(PROTO_HEADER|PROTO_INCLUDE);
2383
proto->flags |= PLUSONLY;
2384
}
2385
else if (!(flags & (PROTO_FORCE|PROTO_PASS)))
2386
{
2387
pppclose(iob);
2388
return 0;
2389
}
2390
else if ((flags & (PROTO_FORCE|PROTO_PASS)) == PROTO_PASS || !pragma)
2391
{
2392
proto->flags |= PASS;
2393
if (proto->flags & MORE)
2394
proto->oz += proto->iz;
2395
proto->iz = n;
2396
if (notice || options)
2397
{
2398
if (proto->cc[0] == '#' && proto->ip[0] == '#' && proto->ip[1] == '!')
2399
{
2400
s = proto->ip;
2401
while (*s && *s++ != '\n');
2402
m = s - proto->ip;
2403
proto->op = memcopy(proto->op, proto->ip, m);
2404
proto->ip = s;
2405
proto->iz = n -= m;
2406
}
2407
#if PROTOMAIN
2408
if (proto->cc[0])
2409
{
2410
if ((comlen = astlicense(proto->op, proto->oz, notice, options, proto->cc[0], proto->cc[1], proto->cc[2])) < 0)
2411
proto_error((char*)proto + sizeof(Proto_t), 1, proto->op, NiL);
2412
else
2413
proto->op += comlen;
2414
}
2415
if (!(flags & PROTO_CLASSIC) && !(proto->flags & YACC))
2416
#endif
2417
proto->op = linesync(proto, proto->op, 1);
2418
proto->iz += proto->op - proto->ob;
2419
}
2420
memcopy(proto->op, proto->ip, n);
2421
return iob;
2422
}
2423
}
2424
#if PROTOMAIN
2425
if (!(retain & PROTO_INITIALIZED))
2426
{
2427
retain |= PROTO_INITIALIZED;
2428
ppfsm(FSM_INIT, NiL);
2429
}
2430
#endif
2431
proto->line = 1;
2432
#if CHUNK >= 512
2433
if (notice || options || (flags & (PROTO_HEADER|PROTO_INCLUDE)))
2434
{
2435
#if PROTOMAIN
2436
if (notice || options)
2437
{
2438
if ((comlen = astlicense(proto->op, proto->oz, notice, options, proto->cc[0], proto->cc[1], proto->cc[2])) < 0)
2439
proto_error((char*)proto + sizeof(Proto_t), 1, proto->op, NiL);
2440
else
2441
proto->op += comlen;
2442
}
2443
#endif
2444
if (flags & PROTO_INCLUDE)
2445
{
2446
proto->flags |= INIT_INCLUDE;
2447
if (flags & PROTO_RETAIN)
2448
retain |= PROTO_INCLUDE;
2449
}
2450
else if (flags & PROTO_HEADER)
2451
{
2452
if (flags & PROTO_RETAIN) retain |= PROTO_HEADER;
2453
#if PROTOMAIN
2454
if (flags & PROTO_CLASSIC)
2455
{
2456
*proto->op++ = '#';
2457
proto->op = strcopy(proto->op, PRAGMADIR);
2458
*proto->op++ = ' ';
2459
proto->op = strcopy(proto->op, pragmas[0].name);
2460
*proto->op++ = '\n';
2461
}
2462
else
2463
#endif
2464
proto->flags |= INIT_DEFINE;
2465
}
2466
#if PROTOMAIN
2467
if (!(flags & PROTO_CLASSIC))
2468
{
2469
if (proto->flags & YACC)
2470
{
2471
proto->op = strcopy(proto->op, "\n%{\n" + !notice);
2472
proto->op = strcopy(proto->op, GENERATED);
2473
proto->op = strcopy(proto->op, "%}\n");
2474
}
2475
else
2476
{
2477
if (n || notice || options)
2478
*proto->op++ = '\n';
2479
proto->op = strcopy(proto->op, GENERATED);
2480
if (n)
2481
proto->op = linesync(proto, proto->op, proto->line);
2482
else if (proto->flags & (INIT_DEFINE|INIT_INCLUDE))
2483
proto->op = init(proto, proto->op, proto->flags);
2484
}
2485
}
2486
#endif
2487
}
2488
#endif
2489
#if PROTOMAIN
2490
proto->file = file;
2491
if (flags & PROTO_CLASSIC)
2492
{
2493
proto->flags |= CLASSIC;
2494
if (!(flags & PROTO_HEADER)) proto->flags |= EXTERN;
2495
}
2496
#endif
2497
return iob;
2498
}
2499
2500
/*
2501
* read next proto'd chunk into iob
2502
* the chunk is 0 terminated and its size is returned
2503
*/
2504
2505
int
2506
pppread(char* iob)
2507
{
2508
register Proto_t* proto = (Proto_t*)(iob - sizeof(Proto_t));
2509
register int n;
2510
2511
if (proto->flags & PASS)
2512
{
2513
if (proto->iz)
2514
{
2515
n = proto->iz;
2516
proto->iz = 0;
2517
}
2518
else if (!(proto->flags & MORE)) n = 0;
2519
else if ((n = read(proto->fd, proto->ob, proto->oz)) <= 0 || (proto->options & REGULAR) && n < proto->oz)
2520
{
2521
proto->flags &= ~MORE;
2522
close(proto->fd);
2523
}
2524
}
2525
else
2526
{
2527
if (proto->op == proto->ob)
2528
{
2529
if (proto->flags & ERROR) return -1;
2530
#if PROTOMAIN
2531
if (proto->flags & YACC)
2532
{
2533
register char* ip = proto->ip;
2534
register char* op = proto->ob;
2535
register char* ep = proto->ob + proto->oz - 2;
2536
2537
if (!*ip)
2538
{
2539
ip = proto->ip = proto->ib;
2540
if (!(proto->flags & MORE)) n = 0;
2541
else if ((n = read(proto->fd, ip, proto->iz)) <= 0 || (proto->options & REGULAR) && n < proto->iz)
2542
{
2543
if (n < 0) n = 0;
2544
proto->flags &= ~MORE;
2545
close(proto->fd);
2546
}
2547
ip[n] = 0;
2548
}
2549
if (proto->flags & YACCSPLIT)
2550
{
2551
proto->flags &= ~YACCSPLIT;
2552
if (*ip == '%')
2553
{
2554
*op++ = *ip++;
2555
if (proto->flags & YACC2) proto->flags &= ~YACC;
2556
else proto->flags |= YACC2;
2557
}
2558
}
2559
if (proto->flags & YACC)
2560
while (op < ep && (n = *op++ = *ip))
2561
{
2562
ip++;
2563
if (n == '%')
2564
{
2565
if (*ip == '%' && (ip == proto->ip + 1 || *(ip - 2) == '\n'))
2566
{
2567
*op++ = *ip++;
2568
if (proto->flags & YACC2) proto->flags &= ~YACC;
2569
else proto->flags |= YACC2;
2570
break;
2571
}
2572
if (!*ip)
2573
{
2574
*op++ = '%';
2575
proto->flags |= YACCSPLIT;
2576
break;
2577
}
2578
}
2579
else if (n == '\n') proto->line++;
2580
}
2581
proto->op = memcopy(proto->ob, proto->ip, ip - proto->ip);
2582
proto->ip = ip;
2583
}
2584
else
2585
#endif
2586
lex(proto, proto->flags);
2587
if ((proto->flags & (ERROR|MORE)) == ERROR)
2588
proto->op = strcopy(proto->op, "/* NOTE: some constructs may not have been converted */\n");
2589
}
2590
n = proto->op - proto->ob;
2591
proto->op = proto->ob;
2592
}
2593
return n;
2594
}
2595
2596
#if !PROTOMAIN
2597
2598
/*
2599
* drop control of iob after first pppread()
2600
* return value is input fd
2601
* if fd<0 then all data in iob
2602
*/
2603
2604
int
2605
pppdrop(char* iob)
2606
{
2607
register Proto_t* proto = (Proto_t*)(iob - sizeof(Proto_t));
2608
2609
if (proto->flags & MORE)
2610
{
2611
proto->flags &= ~MORE;
2612
return proto->fd;
2613
}
2614
return -1;
2615
}
2616
2617
#endif
2618
2619