Initial Import from SVN

This commit is contained in:
Matt Jenkins
2014-04-09 14:27:18 +01:00
parent 8976e834c4
commit 895f96d2f7
3153 changed files with 748589 additions and 0 deletions

63
src/cmd/cpp/Makefile Normal file
View File

@@ -0,0 +1,63 @@
TOPSRC = $(shell cd ../../..; pwd)
include $(TOPSRC)/target.mk
#include $(TOPSRC)/cross.mk
#CFLAGS = -DCROSS
OBJS = cpp.o cpy.o token.o
MAN = cpp.0
MANSRC = cpp.1
LDFLAGS += -g
CFLAGS += -Werror -Wall -Os
CFLAGS += -DCPP_DEBUG -DGCC_COMPAT -DHAVE_CPP_VARARG_MACRO_GCC
all: cpp $(MAN)
cpp: $(OBJS)
${CC} ${LDFLAGS} -o cpp.elf $(OBJS) ${LIBS}
${OBJDUMP} -S cpp.elf > cpp.dis
${SIZE} cpp.elf
${ELF2AOUT} cpp.elf $@ && rm cpp.elf
$(MAN): ${MANSRC}
${MANROFF} $< > $@
clean:
rm -f *.o *.0 *.elf cpp *.elf *.dis tags *~ lex.yy.c y.tab.[ch] tests/run*
install: all
install cpp $(DESTDIR)/bin/
cp cpp.0 $(DESTDIR)/share/man/cat1/
cpp.o: cpp.c y.tab.h
.l.o:
$(LEX) $(LFLAGS) $<
$(CC) $(DEFS) $(CPPFLAGS) $(CFLAGS) -c -o $@ lex.yy.c
cpy.o y.tab.h: cpy.y
$(YACC) -d $(YFLAGS) cpy.y
$(CC) $(DEFS) $(CPPFLAGS) $(CFLAGS) -c -o cpy.o y.tab.c
test:
./cpp.elf < tests/test1 > tests/run1
cmp tests/run1 tests/res1
./cpp.elf < tests/test2 > tests/run2
cmp tests/run2 tests/res2
./cpp.elf < tests/test3 > tests/run3
cmp tests/run3 tests/res3
./cpp.elf < tests/test4 > tests/run4
cmp tests/run4 tests/res4
./cpp.elf < tests/test5 > tests/run5
cmp tests/run5 tests/res5
./cpp.elf < tests/test6 > tests/run6
cmp tests/run6 tests/res6
./cpp.elf < tests/test7 > tests/run7
cmp tests/run7 tests/res7
./cpp.elf < tests/test8 > tests/run8
cmp tests/run8 tests/res8
./cpp.elf < tests/test9 > tests/run9
cmp tests/run9 tests/res9
./cpp.elf < tests/test10 > tests/run10
cmp tests/run10 tests/res10

210
src/cmd/cpp/cpp.1 Normal file
View File

@@ -0,0 +1,210 @@
.\" $Id: cpp.1,v 1.11 2010/04/05 13:13:57 reed Exp $
.\" $NetBSD$
.\" $OpenBSD$
.\"
.\" Copyright (c) 2007 Jeremy C. Reed <reed@reedmedia.net>
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR AND CONTRIBUTORS DISCLAIM
.\" ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHOR AND
.\" CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
.\" THIS SOFTWARE.
.\"
.Dd September 17, 2007
.Dt CPP 1
.Os
.Sh NAME
.Nm cpp
.Nd C preprocessor
.Sh SYNOPSIS
.Nm
.\" TODO also document -Dvar and below without spaces?
.Op Fl CdMtVv
.Op Fl D Ar macro[=value]
.Op Fl I Ar path
.Op Fl i Ar file
.Op Fl S Ar path
.Op Fl U Ar macro
.Op Ar infile | -
.Op Ar outfile
.Sh DESCRIPTION
The
.Nm
utility is a macro preprocessor used by the
.Xr pcc 1
compiler.
It is used to include header files,
expand macro definitions,
and perform conditional compilation.
.Pp
The
.Ar infile
input file is optional.
If not provided or the file name is
.Qq -
(dash),
.Nm
reads its initial file from standard input.
The
.Ar outfile
output file is also optional.
It writes by default to standard output.
.Pp
.\" TODO: document MAXARG 250 args to a macro, limited by char value
.\" TODO: Include order:
.\" For "..." files, first search "current" dir, then as <...> files.
.\" For <...> files, first search -I directories, then system directories.
.\"
The options are as follows:
.Bl -tag -width Ds
.It Fl ?
Show command line usage for
.Nm .
.It Fl C
Do not discard comments.
.It Fl D Ar macro[=value]
Fake a definition at the beginning by using
.Do #define
.Ar macro=value Dc .
If
.Ar value
is not set on command-line, then define it as 1.
.\" TODO: show example
.It Fl dM
Print list of
.Dq #define
statements to standard output for all defined macros other than
builtin macros (see below).
The normal results of preprocessing are not output.
.\" TODO this doesn't show predefined macros
.\" other -d options are ignored
.It Fl I Ar path
Add
.Ar path
to the list of directories containing needed header files.
This may be used to override system include directories
(see
.Fl S
option).
.Fl I
may be specified multiple times.
.It Fl i Ar file
Include a file at the beginning by using
.Do #include
.Ar file Dc .
.\" Note: I did not use the .In macro above
.It Fl M
Generate dependencies for
.Xr make 1 .
.\" TODO: explain and show example?
.It Fl P
Inhibit generation of line markers. This is sometimes useful when
running the preprocessor on something other than C code.
.It Fl S Ar path
Add
.Ar path
to the list of system directories containing needed header files.
The
.Fl S
option may be specified multiple times.
Note:
.Nm
does not have a default include directory defined.
.\" TODO: explain difference between -I and -S
.\" The directories listed by -I are searched first?
.It Fl t
Traditional cpp syntax.
Do not define the
.Dv __TIME__ ,
.Dv __DATE__ ,
.Dv __STDC__ ,
and
.Dv __STDC_VERSION__
macros.
.\"
.It Fl U Ar macro
Undefine a macro at the beginning by using
.Do #undef
.Ar macro Dc .
.It Fl V
Verbose debugging output.
.Fl V
can be repeated for further details.
.\" -V only available if cpp source built with CPP_DEBUG, which is the default.
.It Fl v
Display version.
.El
.Ss Builtin Macros
A few macros are interpreted inside the
.Nm cpp
program:
.Bl -diag
.It __DATE__
Expands to the date in abbreviated month, day, and year format from
.Xr ctime 3
in quotes.
.\" TODO: is that ctime(3) format output change according to locale?
.It __FILE__
Expands to the name of the current input file in quotes.
When read from standard input, it expands to
.Qq Aq stdin .
.It __LINE__
Expands to the line number of the current line containing the macro.
.It __STDC__
Expands to the constant 1.
This means the compiler conforms to
.St -isoC
.Po also known as
.Do C90 Dc Pc .
.It __STDC_VERSION__
Expands to
.Dq 199901L
which indicates that
.Nm
supports
.St -isoC-99
.Po commonly referred to as
.Do C99 Dc Pc .
.It __TIME__
Expands to the time in hour, minutes, and seconds from
.Xr ctime 3
in quotes.
.El
.Pp
Also see the
.Fl t
option.
.Sh EXIT STATUS
The
.Nm
utility exits with one of the following values:
.Bl -tag -width Ds
.It 0
Successfully finished.
.It 1
An error occurred.
.El
.Sh SEE ALSO
.Xr as 1 ,
.Xr ccom 1 ,
.Xr pcc 1
.\"
.Sh HISTORY
The
.Nm
command comes from the original Portable C Compiler by S. C. Johnson,
written in the late 70's.
The code originates from the V6 preprocessor with some additions
from V7 cpp and ansi/c99 support.
.Pp
A lot of the PCC code was rewritten by Anders Magnusson.
.Pp
This product includes software developed or owned by Caldera
International, Inc.

1767
src/cmd/cpp/cpp.c Normal file

File diff suppressed because it is too large Load Diff

150
src/cmd/cpp/cpp.h Normal file
View File

@@ -0,0 +1,150 @@
/*
* Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef CROSS
# include </usr/include/stdio.h>
# include </usr/include/ctype.h>
#else
# include <stdio.h> /* for obuf */
# include <ctype.h>
#endif
#include <stdlib.h>
/* Version string */
#define VERSSTR "cpp for RetroBSD"
typedef unsigned char uchar;
#ifdef YYTEXT_POINTER
extern char *yytext;
#else
extern char yytext[];
#endif
extern uchar *stringbuf;
extern int trulvl;
extern int flslvl;
extern int elflvl;
extern int elslvl;
extern int tflag, Cflag, Pflag;
extern int Mflag, dMflag;
extern uchar *Mfile;
extern int ofd;
/* args for lookup() */
#define FIND 0
#define ENTER 1
/* buffer used internally */
#define CPPBUF BUFSIZ
#define NAMEMAX CPPBUF /* currently pushbackbuffer */
/* definition for include file info */
struct includ {
struct includ *next;
const uchar *fname; /* current fn, changed if #line found */
const uchar *orgfn; /* current fn, not changed */
int lineno;
int infil;
uchar *curptr;
uchar *maxread;
uchar *ostr;
uchar *buffer;
int idx;
void *incs;
const uchar *fn;
uchar bbuf[NAMEMAX+CPPBUF+1];
} *ifiles;
/* Symbol table entry */
struct symtab {
const uchar *namep;
const uchar *value;
const uchar *file;
int line;
};
struct initar {
struct initar *next;
int type;
char *str;
};
/*
* Struct used in parse tree evaluation.
* op is one of:
* - number type (NUMBER, UNUMBER)
* - zero (0) if divided by zero.
*/
struct nd {
int op;
union {
long long val;
unsigned long long uval;
} n;
};
#define nd_val n.val
#define nd_uval n.uval
struct recur; /* not used outside cpp.c */
int subst(struct symtab *, struct recur *);
struct symtab *lookup(const uchar *namep, int enterf);
uchar *gotident(struct symtab *nl);
int slow; /* scan slowly for new tokens */
int pushfile(const uchar *fname, const uchar *fn, int idx, void *incs);
void popfile(void);
void prtline(void);
int yylex(void);
int sloscan(void);
void cunput(int);
int curline(void);
char *curfile(void);
void setline(int);
void setfile(char *);
int yyparse(void);
void yyerror(const char *);
void unpstr(const uchar *);
uchar *savstr(const uchar *str);
void savch(int c);
void mainscan(void);
void putch(int);
void putstr(const uchar *s);
void line(void);
uchar *sheap(const char *fmt, ...);
void xwarning(uchar *);
void xerror(uchar *);
#ifdef HAVE_CPP_VARARG_MACRO_GCC
#define warning(...) xwarning(sheap(__VA_ARGS__))
#define error(...) xerror(sheap(__VA_ARGS__))
#else
#define warning printf
#define error printf
#endif
void expmac(struct recur *);
int cinput(void);
void getcmnt(void);

217
src/cmd/cpp/cpy.y Normal file
View File

@@ -0,0 +1,217 @@
/*
* Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code and documentation must retain the above
* copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed or owned by Caldera
* International, Inc.
* Neither the name of Caldera International, Inc. nor the names of other
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
* INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
* FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
%{
#include "cpp.h"
void yyerror(const char *);
int yylex(void);
int setd(int l, int r);
#define EVALUNARY(tok, l, r) l.nd_val = tok r.nd_val; l.op = r.op
#define EVALBIN(tok, d, l, r) \
d.op = setd(l.op, r.op); d.nd_val = l.nd_val tok r.nd_val
#define EVALUBIN(tok, d, l, r, t) \
d.op = setd(l.op, r.op); \
if (d.op == NUMBER) d.nd_val = l.nd_val tok r.nd_val; \
else d.nd_uval = l.nd_uval tok r.nd_uval; \
if (t && d.op) d.op = NUMBER
#define XEVALUBIN(tok, d, l, r) \
if (r.nd_val) { EVALUBIN(tok, d, l, r, 0); } else d.op = 0
%}
%term stop
%term EQ NE LE GE LS RS
%term ANDAND OROR IDENT NUMBER UNUMBER DEFINED
/*
* The following terminals are not used in the yacc code.
*/
%term STRING WSPACE CMNT
%left ','
%right '?' ':'
%left OROR
%left ANDAND
%left '|' '^'
%left '&'
%binary EQ NE
%binary '<' '>' LE GE
%left LS RS
%left '+' '-'
%left '*' '/' '%'
%right '!' '~' UMINUS
%left '('
%union {
struct nd node;
}
%type <node> term e NUMBER UNUMBER
%%
S: e '\n' {
if ($1.op == 0)
error("division by zero");
return $1.nd_val;
}
e: e '*' e
{ EVALUBIN(*, $$, $1, $3, 0); }
| e '/' e
{ XEVALUBIN(/, $$, $1, $3); }
| e '%' e
{ XEVALUBIN(%, $$, $1, $3); }
| e '+' e
{ EVALBIN(+, $$, $1, $3); }
| e '-' e
{ EVALBIN(-, $$, $1, $3); }
| e LS e
{ EVALBIN(<<, $$, $1, $3); }
| e RS e
{ EVALUBIN(>>, $$, $1, $3, 0); }
| e '<' e
{ EVALUBIN(<, $$, $1, $3, 1); }
| e '>' e
{ EVALUBIN(>, $$, $1, $3, 1); }
| e LE e
{ EVALUBIN(<=, $$, $1, $3, 1); }
| e GE e
{ EVALUBIN(>=, $$, $1, $3, 1); }
| e EQ e
{ EVALUBIN(==, $$, $1, $3, 1); }
| e NE e
{ EVALUBIN(!=, $$, $1, $3, 1); }
| e '&' e
{ EVALBIN(&, $$, $1, $3); }
| e '^' e
{ EVALBIN(^, $$, $1, $3); }
| e '|' e
{ EVALBIN(|, $$, $1, $3); }
| e ANDAND e {
$$ = $1;
if ($1.nd_val) {
$$.op = setd($1.op, $3.op);
$$.nd_val = ($3.nd_val != 0);
}
if ($$.op == UNUMBER) $$.op = NUMBER;
}
| e OROR e {
if ($1.nd_val != 0) {
$$.nd_val = ($1.nd_val != 0);
$$.op = $1.op;
} else {
$$.nd_val = ($3.nd_val != 0);
$$.op = setd($1.op, $3.op);
}
if ($$.op == UNUMBER) $$.op = NUMBER;
}
| e '?' e ':' e {
if ($1.op == 0)
$$ = $1;
else if ($1.nd_val)
$$ = $3;
else
$$ = $5;
}
| e ',' e {
$$.op = setd($1.op, $3.op);
$$.nd_val = $3.nd_val;
if ($$.op) $$.op = $3.op;
}
| term
{$$ = $1;}
term:
'-' term %prec UMINUS
{ EVALUNARY(-, $$, $2); }
| '+' term %prec UMINUS
{$$ = $2;}
| '!' term
{ $$.nd_val = ! $2.nd_val; $$.op = $2.op ? NUMBER : 0; }
| '~' term
{ EVALUNARY(~, $$, $2); }
| '(' e ')'
{$$ = $2;}
| DEFINED '(' NUMBER ')'
{$$= $3;}
| DEFINED NUMBER
{$$ = $2;}
| NUMBER
{$$ = $1;}
%%
void
yyerror(const char *err)
{
error(err);
}
/*
* Set return type of an expression.
*/
int
setd(int l, int r)
{
if (!l || !r)
return 0; /* div by zero involved */
if (l == UNUMBER || r == UNUMBER)
return UNUMBER;
return NUMBER;
}

932
src/cmd/cpp/scanner.l Normal file
View File

@@ -0,0 +1,932 @@
%{
/*
* Copyright (c) 2004 Anders Magnusson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include "compat.h"
#include "cpp.h"
#include "y.tab.h"
%}
%{
static void cvtdig(int rad);
static int charcon(uchar *);
static void elsestmt(void);
static void ifdefstmt(void);
static void ifndefstmt(void);
static void endifstmt(void);
static void ifstmt(void);
static void cpperror(void);
static void pragmastmt(void);
static void undefstmt(void);
static void cpperror(void);
static void elifstmt(void);
static void storepb(void);
static void badop(const char *);
void include(void);
void define(void);
extern int yyget_lineno (void);
extern void yyset_lineno (int);
static int inch(void);
static int scale, gotdef, contr;
int inif;
#ifdef FLEX_SCANNER /* should be set by autoconf instead */
static int
yyinput(char *b, int m)
{
int c, i;
for (i = 0; i < m; i++) {
if ((c = inch()) < 0)
break;
*b++ = c;
if (c == '\n') {
i++;
break;
}
}
return i;
}
#undef YY_INPUT
#undef YY_BUF_SIZE
#define YY_BUF_SIZE (8*65536)
#define YY_INPUT(b,r,m) (r = yyinput(b, m))
#ifdef HAVE_CPP_VARARG_MACRO_GCC
#define fprintf(x, ...) error(__VA_ARGS__)
#endif
#define ECHO putstr((uchar *)yytext)
#undef fileno
#define fileno(x) 0
#if YY_FLEX_SUBMINOR_VERSION >= 31
/* Hack to avoid unnecessary warnings */
FILE *yyget_in (void);
FILE *yyget_out (void);
int yyget_leng (void);
char *yyget_text (void);
void yyset_in (FILE * in_str );
void yyset_out (FILE * out_str );
int yyget_debug (void);
void yyset_debug (int bdebug );
int yylex_destroy (void);
#endif
#else /* Assume lex here */
#undef input
#undef unput
#define input() inch()
#define unput(ch) unch(ch)
#endif
#define PRTOUT(x) if (YYSTATE || slow) return x; if (!flslvl) putstr((uchar *)yytext);
/* protection against recursion in #include */
#define MAX_INCLEVEL 100
static int inclevel;
%}
D [0-9]
L [a-zA-Z_]
H [a-fA-F0-9]
E [Ee][+-]?{D}+
FS (f|F|l|L)
IS (u|U|l|L)*
WS [\t ]
%s IFR CONTR DEF COMMENT
%%
"\n" { int os = YYSTATE;
if (os != IFR)
BEGIN 0;
ifiles->lineno++;
if (flslvl == 0) {
if (ifiles->lineno == 1)
prtline();
else
putch('\n');
}
if ((os != 0 || slow) && !contr)
return '\n';
contr = 0;
}
"\r" { ; /* Ignore CR's */ }
<IFR>"++" { badop("++"); }
<IFR>"--" { badop("--"); }
<IFR>"==" { return EQ; }
<IFR>"!=" { return NE; }
<IFR>"<=" { return LE; }
<IFR>"<<" { return LS; }
<IFR>">>" { return RS; }
<IFR>">=" { return GE; }
<IFR>"||" { return OROR; }
<IFR>"&&" { return ANDAND; }
<IFR>"defined" { int p, c;
gotdef = 1;
if ((p = c = yylex()) == '(')
c = yylex();
if (c != IDENT || (p != IDENT && p != '('))
error("syntax error");
if (p == '(' && yylex() != ')')
error("syntax error");
return NUMBER;
}
<IFR>{WS}+ { ; }
<IFR>{L}({L}|{D})* {
yylval.node.op = NUMBER;
if (gotdef) {
yylval.node.nd_val
= lookup((uchar *)yytext, FIND) != 0;
gotdef = 0;
return IDENT;
}
yylval.node.nd_val = 0;
return NUMBER;
}
[0-9][0-9]* {
if (slow && !YYSTATE)
return IDENT;
scale = yytext[0] == '0' ? 8 : 10;
goto num;
}
0[xX]{H}+{IS}? { scale = 16;
num: if (YYSTATE == IFR)
cvtdig(scale);
PRTOUT(NUMBER);
}
0{D}+{IS}? { scale = 8; goto num; }
{D}+{IS}? { scale = 10; goto num; }
'(\\.|[^\\'])+' {
if (YYSTATE || slow) {
yylval.node.op = NUMBER;
yylval.node.nd_val = charcon((uchar *)yytext);
return (NUMBER);
}
if (tflag)
yyless(1);
if (!flslvl)
putstr((uchar *)yytext);
}
<IFR>. { return yytext[0]; }
{D}+{E}{FS}? { PRTOUT(FPOINT); }
{D}*"."{D}+({E})?{FS}? { PRTOUT(FPOINT); }
{D}+"."{D}*({E})?{FS}? { PRTOUT(FPOINT); }
^{WS}*#{WS}* { extern int inmac;
if (inmac)
error("preprocessor directive found "
"while expanding macro");
contr = 1;
BEGIN CONTR;
}
{WS}+ { PRTOUT(WSPACE); }
<CONTR>"ifndef" { contr = 0; ifndefstmt(); }
<CONTR>"ifdef" { contr = 0; ifdefstmt(); }
<CONTR>"if" { contr = 0; storepb(); BEGIN IFR; ifstmt(); BEGIN 0; }
<CONTR>"include" { contr = 0; BEGIN 0; include(); prtline(); }
<CONTR>"else" { contr = 0; elsestmt(); }
<CONTR>"endif" { contr = 0; endifstmt(); }
<CONTR>"error" { contr = 0; if (slow) return IDENT; cpperror(); BEGIN 0; }
<CONTR>"define" { contr = 0; BEGIN DEF; define(); BEGIN 0; }
<CONTR>"undef" { contr = 0; if (slow) return IDENT; undefstmt(); }
<CONTR>"line" { contr = 0; storepb(); BEGIN 0; line(); }
<CONTR>"pragma" { contr = 0; pragmastmt(); BEGIN 0; }
<CONTR>"elif" { contr = 0; storepb(); BEGIN IFR; elifstmt(); BEGIN 0; }
"//".*$ { /* if (tflag) yyless(..) */
if (Cflag && !flslvl && !slow)
putstr((uchar *)yytext);
else if (!flslvl)
putch(' ');
}
"/*" { int c, wrn;
int prtcm = Cflag && !flslvl && !slow;
extern int readmac;
if (Cflag && !flslvl && readmac)
return CMNT;
if (prtcm)
putstr((uchar *)yytext);
wrn = 0;
more: while ((c = input()) && c != '*') {
if (c == '\n')
putch(c), ifiles->lineno++;
else if (c == 1) /* WARN */
wrn = 1;
else if (prtcm)
putch(c);
}
if (c == 0)
return 0;
if (prtcm)
putch(c);
if ((c = input()) && c != '/') {
unput(c);
goto more;
}
if (prtcm)
putch(c);
if (c == 0)
return 0;
if (!tflag && !Cflag && !flslvl)
unput(' ');
if (wrn)
unput(1);
}
<DEF>"##" { return CONCAT; }
<DEF>"#" { return MKSTR; }
<DEF>"..." { return ELLIPS; }
<DEF>"__VA_ARGS__" { return VA_ARGS; }
L?\"(\\.|[^\\"])*\" { PRTOUT(STRING); }
[a-zA-Z_0-9]+ { /* {L}({L}|{D})* */
struct symtab *nl;
if (slow)
return IDENT;
if (YYSTATE == CONTR) {
if (flslvl == 0) {
/*error("undefined control");*/
while (input() != '\n')
;
unput('\n');
BEGIN 0;
goto xx;
} else {
BEGIN 0; /* do nothing */
}
}
if (flslvl) {
; /* do nothing */
} else if (isdigit((int)yytext[0]) == 0 &&
(nl = lookup((uchar *)yytext, FIND)) != 0) {
uchar *op = stringbuf;
putstr(gotident(nl));
stringbuf = op;
} else
putstr((uchar *)yytext);
xx: ;
}
. {
if (contr) {
while (input() != '\n')
;
unput('\n');
BEGIN 0;
contr = 0;
goto yy;
}
if (YYSTATE || slow)
return yytext[0];
if (yytext[0] == 6) { /* PRAGS */
uchar *obp = stringbuf;
extern uchar *prtprag(uchar *);
*stringbuf++ = yytext[0];
do {
*stringbuf = input();
} while (*stringbuf++ != 14);
prtprag(obp);
stringbuf = obp;
} else {
PRTOUT(yytext[0]);
}
yy:;
}
%%
uchar *yyp, yybuf[CPPBUF];
int yylex(void);
int yywrap(void);
static int
inpch(void)
{
int len;
if (ifiles->curptr < ifiles->maxread)
return *ifiles->curptr++;
if ((len = read(ifiles->infil, ifiles->buffer, CPPBUF)) < 0)
error("read error on file %s", ifiles->orgfn);
if (len == 0)
return -1;
ifiles->curptr = ifiles->buffer;
ifiles->maxread = ifiles->buffer + len;
return inpch();
}
#define unch(c) *--ifiles->curptr = c
static int
inch(void)
{
int c;
again: switch (c = inpch()) {
case '\\': /* continued lines */
msdos: if ((c = inpch()) == '\n') {
ifiles->lineno++;
putch('\n');
goto again;
} else if (c == '\r')
goto msdos;
unch(c);
return '\\';
case '?': /* trigraphs */
if ((c = inpch()) != '?') {
unch(c);
return '?';
}
switch (c = inpch()) {
case '=': c = '#'; break;
case '(': c = '['; break;
case ')': c = ']'; break;
case '<': c = '{'; break;
case '>': c = '}'; break;
case '/': c = '\\'; break;
case '\'': c = '^'; break;
case '!': c = '|'; break;
case '-': c = '~'; break;
default:
unch(c);
unch('?');
return '?';
}
unch(c);
goto again;
default:
return c;
}
}
/*
* Let the command-line args be faked defines at beginning of file.
*/
static void
prinit(struct initar *it, struct includ *ic)
{
char *a, *pre, *post;
if (it->next)
prinit(it->next, ic);
pre = post = NULL; /* XXX gcc */
switch (it->type) {
case 'D':
pre = "#define ";
if ((a = strchr(it->str, '=')) != NULL) {
*a = ' ';
post = "\n";
} else
post = " 1\n";
break;
case 'U':
pre = "#undef ";
post = "\n";
break;
case 'i':
pre = "#include \"";
post = "\"\n";
break;
default:
error("prinit");
}
strlcat((char *)ic->buffer, pre, CPPBUF+1);
strlcat((char *)ic->buffer, it->str, CPPBUF+1);
if (strlcat((char *)ic->buffer, post, CPPBUF+1) >= CPPBUF+1)
error("line exceeds buffer size");
ic->lineno--;
while (*ic->maxread)
ic->maxread++;
}
/*
* A new file included.
* If ifiles == NULL, this is the first file and already opened (stdin).
* Return 0 on success, -1 if file to be included is not found.
*/
int
pushfile(uchar *file)
{
extern struct initar *initar;
struct includ ibuf;
struct includ *ic;
int c, otrulvl;
ic = &ibuf;
ic->next = ifiles;
slow = 0;
if (file != NULL) {
if ((ic->infil = open((char *)file, O_RDONLY)) < 0)
return -1;
ic->orgfn = ic->fname = file;
if (++inclevel > MAX_INCLEVEL)
error("Limit for nested includes exceeded");
} else {
ic->infil = 0;
ic->orgfn = ic->fname = (uchar *)"<stdin>";
}
ic->buffer = ic->bbuf+NAMEMAX;
ic->curptr = ic->buffer;
ifiles = ic;
ic->lineno = 1;
ic->maxread = ic->curptr;
prtline();
if (initar) {
*ic->maxread = 0;
prinit(initar, ic);
if (dMflag)
write(ofd, ic->buffer, strlen((char *)ic->buffer));
initar = NULL;
}
otrulvl = trulvl;
if ((c = yylex()) != 0)
error("yylex returned %d", c);
if (otrulvl != trulvl || flslvl)
error("unterminated conditional");
ifiles = ic->next;
close(ic->infil);
inclevel--;
return 0;
}
/*
* Print current position to output file.
*/
void
prtline()
{
uchar *s, *os = stringbuf;
if (Mflag) {
if (dMflag)
return; /* no output */
if (ifiles->lineno == 1) {
s = sheap("%s: %s\n", Mfile, ifiles->fname);
write(ofd, s, strlen((char *)s));
}
} else if (!Pflag)
putstr(sheap("# %d \"%s\"\n", ifiles->lineno, ifiles->fname));
stringbuf = os;
}
void
cunput(int c)
{
#ifdef CPP_DEBUG
extern int dflag;
if (dflag)printf(": '%c'(%d)", c > 31 ? c : ' ', c);
#endif
unput(c);
}
int yywrap(void) { return 1; }
static int
dig2num(int c)
{
if (c >= 'a')
c = c - 'a' + 10;
else if (c >= 'A')
c = c - 'A' + 10;
else
c = c - '0';
return c;
}
/*
* Convert string numbers to unsigned long long and check overflow.
*/
static void
cvtdig(int rad)
{
unsigned long long rv = 0;
unsigned long long rv2 = 0;
char *y = yytext;
int c;
c = *y++;
if (rad == 16)
y++;
while (isxdigit(c)) {
rv = rv * rad + dig2num(c);
/* check overflow */
if (rv / rad < rv2)
error("Constant \"%s\" is out of range", yytext);
rv2 = rv;
c = *y++;
}
y--;
while (*y == 'l' || *y == 'L')
y++;
yylval.node.op = *y == 'u' || *y == 'U' ? UNUMBER : NUMBER;
yylval.node.nd_uval = rv;
if ((rad == 8 || rad == 16) && yylval.node.nd_val < 0)
yylval.node.op = UNUMBER;
if (yylval.node.op == NUMBER && yylval.node.nd_val < 0)
/* too large for signed */
error("Constant \"%s\" is out of range", yytext);
}
static int
charcon(uchar *p)
{
int val, c;
p++; /* skip first ' */
val = 0;
if (*p++ == '\\') {
switch (*p++) {
case 'a': val = '\a'; break;
case 'b': val = '\b'; break;
case 'f': val = '\f'; break;
case 'n': val = '\n'; break;
case 'r': val = '\r'; break;
case 't': val = '\t'; break;
case 'v': val = '\v'; break;
case '\"': val = '\"'; break;
case '\'': val = '\''; break;
case '\\': val = '\\'; break;
case 'x':
while (isxdigit(c = *p)) {
val = val * 16 + dig2num(c);
p++;
}
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7':
p--;
while (isdigit(c = *p)) {
val = val * 8 + (c - '0');
p++;
}
break;
default: val = p[-1];
}
} else
val = p[-1];
return val;
}
static void
chknl(int ignore)
{
int t;
slow = 1;
while ((t = yylex()) == WSPACE)
;
if (t != '\n') {
if (ignore) {
warning("newline expected, got \"%s\"", yytext);
/* ignore rest of line */
while ((t = yylex()) && t != '\n')
;
}
else
error("newline expected, got \"%s\"", yytext);
}
slow = 0;
}
static void
elsestmt(void)
{
if (flslvl) {
if (elflvl > trulvl)
;
else if (--flslvl!=0) {
flslvl++;
} else {
trulvl++;
prtline();
}
} else if (trulvl) {
flslvl++;
trulvl--;
} else
error("If-less else");
if (elslvl==trulvl+flslvl)
error("Too many else");
elslvl=trulvl+flslvl;
chknl(1);
}
static void
ifdefstmt(void)
{
int t;
if (flslvl) {
/* just ignore the rest of the line */
while (input() != '\n')
;
unput('\n');
yylex();
flslvl++;
return;
}
slow = 1;
do
t = yylex();
while (t == WSPACE);
if (t != IDENT)
error("bad ifdef");
slow = 0;
if (flslvl == 0 && lookup((uchar *)yytext, FIND) != 0)
trulvl++;
else
flslvl++;
chknl(0);
}
static void
ifndefstmt(void)
{
int t;
slow = 1;
do
t = yylex();
while (t == WSPACE);
if (t != IDENT)
error("bad ifndef");
slow = 0;
if (flslvl == 0 && lookup((uchar *)yytext, FIND) == 0)
trulvl++;
else
flslvl++;
chknl(0);
}
static void
endifstmt(void)
{
if (flslvl) {
flslvl--;
if (flslvl == 0)
prtline();
} else if (trulvl)
trulvl--;
else
error("If-less endif");
if (flslvl == 0)
elflvl = 0;
elslvl = 0;
chknl(1);
}
/*
* Note! Ugly!
* Walk over the string s and search for defined, and replace it with
* spaces and a 1 or 0.
*/
static void
fixdefined(uchar *s)
{
uchar *bc, oc;
for (; *s; s++) {
if (*s != 'd')
continue;
if (memcmp(s, "defined", 7))
continue;
/* Ok, got defined, can scratch it now */
memset(s, ' ', 7);
s += 7;
#define WSARG(x) (x == ' ' || x == '\t')
if (*s != '(' && !WSARG(*s))
continue;
while (WSARG(*s))
s++;
if (*s == '(')
s++;
while (WSARG(*s))
s++;
#define IDARG(x) ((x>= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x == '_'))
#define NUMARG(x) (x >= '0' && x <= '9')
if (!IDARG(*s))
error("bad defined arg");
bc = s;
while (IDARG(*s) || NUMARG(*s))
s++;
oc = *s;
*s = 0;
*bc = (lookup(bc, FIND) != 0) + '0';
memset(bc+1, ' ', s-bc-1);
*s = oc;
}
}
/*
* get the full line of identifiers after an #if, pushback a WARN and
* the line and prepare for expmac() to expand.
* This is done before switching state. When expmac is finished,
* pushback the expanded line, change state and call yyparse.
*/
static void
storepb(void)
{
uchar *opb = stringbuf;
int c;
while ((c = input()) != '\n') {
if (c == '/') {
if ((c = input()) == '*') {
/* ignore comments here whatsoever */
uchar *g = stringbuf;
getcmnt();
stringbuf = g;
continue;
} else if (c == '/') {
while ((c = input()) && c != '\n')
;
break;
}
unput(c);
c = '/';
}
savch(c);
}
cunput('\n');
savch(0);
fixdefined(opb); /* XXX can fail if #line? */
cunput(1); /* WARN XXX */
unpstr(opb);
stringbuf = opb;
slow = 1;
expmac(NULL);
slow = 0;
/* line now expanded */
while (stringbuf > opb)
cunput(*--stringbuf);
}
static void
ifstmt(void)
{
if (flslvl == 0) {
slow = 1;
if (yyparse())
++trulvl;
else
++flslvl;
slow = 0;
} else
++flslvl;
}
static void
elifstmt(void)
{
if (flslvl == 0)
elflvl = trulvl;
if (flslvl) {
if (elflvl > trulvl)
;
else if (--flslvl!=0)
++flslvl;
else {
slow = 1;
if (yyparse()) {
++trulvl;
prtline();
} else
++flslvl;
slow = 0;
}
} else if (trulvl) {
++flslvl;
--trulvl;
} else
error("If-less elif");
}
static uchar *
svinp(void)
{
int c;
uchar *cp = stringbuf;
while ((c = input()) && c != '\n')
savch(c);
savch('\n');
savch(0);
BEGIN 0;
return cp;
}
static void
cpperror(void)
{
uchar *cp;
int c;
if (flslvl)
return;
c = yylex();
if (c != WSPACE && c != '\n')
error("bad error");
cp = svinp();
if (flslvl)
stringbuf = cp;
else
error("%s", cp);
}
static void
undefstmt(void)
{
struct symtab *np;
slow = 1;
if (yylex() != WSPACE || yylex() != IDENT)
error("bad undef");
if (flslvl == 0 && (np = lookup((uchar *)yytext, FIND)))
np->value = 0;
slow = 0;
chknl(0);
}
static void
pragmastmt(void)
{
int c;
slow = 1;
if (yylex() != WSPACE)
error("bad pragma");
if (!flslvl)
putstr((uchar *)"#pragma ");
do {
c = input();
if (!flslvl)
putch(c); /* Do arg expansion instead? */
} while (c && c != '\n');
ifiles->lineno++;
prtline();
slow = 0;
}
static void
badop(const char *op)
{
error("invalid operator in preprocessor expression: %s", op);
}
int
cinput()
{
return input();
}

8
src/cmd/cpp/tests/res1 Normal file
View File

@@ -0,0 +1,8 @@
# 1 "<stdin>"
char p[] = "x ## y";

16
src/cmd/cpp/tests/res10 Normal file
View File

@@ -0,0 +1,16 @@
# 1 "<stdin>"
int midiopen(int);
foo_optarg

26
src/cmd/cpp/tests/res2 Normal file
View File

@@ -0,0 +1,26 @@
# 1 "<stdin>"
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
int i[] = { 1, 23, 4, 5, };
char c[2][6] = { "hello", "" };

16
src/cmd/cpp/tests/res3 Normal file
View File

@@ -0,0 +1,16 @@
# 1 "<stdin>"
printf("x" "1" "= %d, x" "2" "= %s", x1, x2);
fputs(
"strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n", s);
\#include "vers2.h"
"hello";
"hello" ", world"

6
src/cmd/cpp/tests/res4 Normal file
View File

@@ -0,0 +1,6 @@
# 1 "<stdin>"
(1)

5
src/cmd/cpp/tests/res5 Normal file
View File

@@ -0,0 +1,5 @@
# 1 "<stdin>"
int j[] = { 123, 45, 67, 89,
10, 11, 12, };

5
src/cmd/cpp/tests/res6 Normal file
View File

@@ -0,0 +1,5 @@
# 1 "<stdin>"
foo

6
src/cmd/cpp/tests/res7 Normal file
View File

@@ -0,0 +1,6 @@
# 1 "<stdin>"
a
YES

9
src/cmd/cpp/tests/res8 Normal file
View File

@@ -0,0 +1,9 @@
# 1 "<stdin>"
(hej.s_s.s_pos)

6
src/cmd/cpp/tests/res9 Normal file
View File

@@ -0,0 +1,6 @@
# 1 "<stdin>"
ao

6
src/cmd/cpp/tests/test1 Normal file
View File

@@ -0,0 +1,6 @@
#define hash_hash # ## #
#define mkstr(a) # a
#define in_between(a) mkstr(a)
#define join(c, d) in_between(c hash_hash d)
char p[] = join(x, y); // equivalent to
// char p[] = "x ## y";

14
src/cmd/cpp/tests/test10 Normal file
View File

@@ -0,0 +1,14 @@
#define __CONCAT(x,y) x ## y
#define dev_type_open(n) int n(int)
#define dev_decl(n,t) __CONCAT(dev_type_,t)(__CONCAT(n,t))
#define cdev_decl(n) dev_decl(n,open)
cdev_decl(midi);
# define __GETOPT_PREFIX foo_
# define __GETOPT_CONCAT(x, y) x ## y
# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y)
# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y)
# define optarg __GETOPT_ID (optarg)
optarg

25
src/cmd/cpp/tests/test2 Normal file
View File

@@ -0,0 +1,25 @@
#define x 3
#define f(a) f(x * (a))
#undef x
#define x 2
#define g f
#define z z[0]
#define h g(~
#define m(a) a(w)
#define w 0,1
#define t(a) a
#define p() int
#define q(x) x
#define r(x,y) x ## y
#define str(x) # x
f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
g(x+(3,4)-w) | h 5) & m
(f)^m(m);
p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };
char c[2][6] = { str(hello), str() };
/*
* f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
* f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
* int i[] = { 1, 23, 4, 5, };
* char c[2][6] = { "hello", "" };
*/

15
src/cmd/cpp/tests/test3 Normal file
View File

@@ -0,0 +1,15 @@
#define str(s) # s
#define xstr(s) str(s)
#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \
x ## s, x ## t)
#define INCFILE(n) vers ## n
#define glue(a, b) a ## b
#define xglue(a, b) glue(a, b)
#define HIGHLOW "hello"
#define LOW LOW ", world"
debug(1, 2);
fputs(str(strncmp("abc\0d", "abc", '\4') // this goes away
== 0) str(: @\n), s);
\#include xstr(INCFILE(2).h)
glue(HIGH, LOW);
xglue(HIGH, LOW)

4
src/cmd/cpp/tests/test4 Normal file
View File

@@ -0,0 +1,4 @@
#define foobar 1
#define C(x,y) x##y
#define D(x) (C(x,bar))
D(foo)

3
src/cmd/cpp/tests/test5 Normal file
View File

@@ -0,0 +1,3 @@
#define t(x,y,z) x ## y ## z
int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
t(10,,), t(,11,), t(,,12), t(,,) };

5
src/cmd/cpp/tests/test6 Normal file
View File

@@ -0,0 +1,5 @@
#define X(a,b, \
c,d) \
foo
X(1,2,3,4)

4
src/cmd/cpp/tests/test7 Normal file
View File

@@ -0,0 +1,4 @@
#define a() YES
#define b() a
b()
b()()

7
src/cmd/cpp/tests/test8 Normal file
View File

@@ -0,0 +1,7 @@
// test macro expansion in arguments
#define s_pos s_s.s_pos
#define foo(x) (x)
//hej.s_pos
foo(hej.s_pos)

4
src/cmd/cpp/tests/test9 Normal file
View File

@@ -0,0 +1,4 @@
#define C(a,b,c) a##b##c
#define N(x,y) C(x,_,y)
#define A_O ao
N(A,O)

1289
src/cmd/cpp/token.c Normal file

File diff suppressed because it is too large Load Diff