Merge pull request #28 from alexfru/master
Update cpp to pcc 1.0.0's cpp
This commit is contained in:
@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
|
||||
#include $(TOPSRC)/cross.mk
|
||||
#CFLAGS = -DCROSS
|
||||
|
||||
OBJS = cpp.o cpy.o token.o doprnt.o
|
||||
OBJS = cpp.o cpy.o token.o compat.o doprnt.o
|
||||
MAN = cpp.0
|
||||
MANSRC = cpp.1
|
||||
|
||||
@@ -31,7 +31,7 @@ install: all
|
||||
install cpp $(DESTDIR)/bin/
|
||||
cp cpp.0 $(DESTDIR)/share/man/cat1/
|
||||
|
||||
cpp.o: cpp.c y.tab.h
|
||||
cpp.o: cpp.c cpp.h y.tab.h config.h
|
||||
|
||||
.l.o:
|
||||
$(LEX) $(LFLAGS) $<
|
||||
@@ -62,3 +62,9 @@ test:
|
||||
cmp tests/run9 tests/res9
|
||||
./cpp < tests/test10 > tests/run10
|
||||
cmp tests/run10 tests/res10
|
||||
./cpp < tests/test11 > tests/run11
|
||||
cmp tests/run11 tests/res11
|
||||
./cpp < tests/test12 > tests/run12
|
||||
cmp tests/run12 tests/res12
|
||||
./cpp < tests/test13 > tests/run13
|
||||
cmp tests/run13 tests/res13
|
||||
|
||||
91
src/cmd/cpp/compat.c
Normal file
91
src/cmd/cpp/compat.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/* $OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $ */
|
||||
/* $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1998, 2003-2005, 2010-2011, 2013
|
||||
* Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and 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 DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
/*
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
* full size of dst, not space left). At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||||
* If retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcat(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return dlen + strlen(s);
|
||||
while (*s != '\0') {
|
||||
if (n != 1) {
|
||||
*d++ = *s;
|
||||
n--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
return dlen + (s - src); /* count does not include NUL */
|
||||
}
|
||||
#endif /* HAVE_STRLCAT */
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz == 0).
|
||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcpy(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0 && --n != 0) {
|
||||
do {
|
||||
if ((*d++ = *s++) == 0)
|
||||
break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0) {
|
||||
if (siz != 0)
|
||||
*d = '\0'; /* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
|
||||
return s - src - 1; /* count does not include NUL */
|
||||
}
|
||||
#endif /* HAVE_STRLCPY */
|
||||
14
src/cmd/cpp/compat.h
Normal file
14
src/cmd/cpp/compat.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef COMPAT_H__
|
||||
#define COMPAT_H__
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
size_t strlcpy(char* dst, const char* src, size_t size);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
size_t strlcat(char* dst, const char* src, size_t size);
|
||||
#endif
|
||||
|
||||
#endif // COMPAT_H__
|
||||
11
src/cmd/cpp/config.h
Normal file
11
src/cmd/cpp/config.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef CONFIG_H__
|
||||
#define CONFIG_H__
|
||||
|
||||
#define VERSSTR "cpp for RetroBSD"
|
||||
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define HAVE_SYS_WAIT_H 1
|
||||
//#define HAVE_STRLCPY 1
|
||||
//#define HAVE_STRLCAT 1
|
||||
|
||||
#endif // CONFIG_H__
|
||||
1654
src/cmd/cpp/cpp.c
1654
src/cmd/cpp/cpp.c
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,7 @@
|
||||
/* $Id: cpp.h,v 1.47.2.1 2011/02/26 06:36:40 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
|
||||
* Copyright (c) 2004,2010 Anders Magnusson (ragge@ludd.luth.se).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -10,8 +12,6 @@
|
||||
* 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
|
||||
@@ -24,25 +24,15 @@
|
||||
* (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 <stdio.h> /* for obuf */
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Version string */
|
||||
#define VERSSTR "cpp for RetroBSD"
|
||||
#include "config.h"
|
||||
|
||||
typedef unsigned char uchar;
|
||||
#ifdef YYTEXT_POINTER
|
||||
extern char *yytext;
|
||||
#else
|
||||
extern char yytext[];
|
||||
#endif
|
||||
extern uchar *stringbuf;
|
||||
typedef unsigned char usch;
|
||||
extern usch yytext[];
|
||||
extern usch *stringbuf;
|
||||
|
||||
extern int trulvl;
|
||||
extern int flslvl;
|
||||
@@ -50,7 +40,7 @@ extern int elflvl;
|
||||
extern int elslvl;
|
||||
extern int tflag, Cflag, Pflag;
|
||||
extern int Mflag, dMflag;
|
||||
extern uchar *Mfile;
|
||||
extern usch *Mfile;
|
||||
extern int ofd;
|
||||
|
||||
/* args for lookup() */
|
||||
@@ -58,32 +48,77 @@ extern int ofd;
|
||||
#define ENTER 1
|
||||
|
||||
/* buffer used internally */
|
||||
#define CPPBUF 512
|
||||
#define CPPBUF 512
|
||||
#ifndef CPPBUF
|
||||
#if defined(__pdp11__)
|
||||
#define CPPBUF BUFSIZ
|
||||
#define BUF_STACK
|
||||
#elif defined(WIN32)
|
||||
/* winxp seems to fail > 26608 bytes */
|
||||
#define CPPBUF 16384
|
||||
#else
|
||||
#define CPPBUF (65536*2)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MAXARGS 20//128 /* Max # of args to a macro. Should be enouth */
|
||||
|
||||
#define NAMEMAX CPPBUF /* currently pushbackbuffer */
|
||||
#define BBUFSZ (NAMEMAX+CPPBUF+1)
|
||||
|
||||
#define GCCARG 0xfd /* has gcc varargs that may be replaced with 0 */
|
||||
#define VARG 0xfe /* has varargs */
|
||||
#define OBJCT 0xff
|
||||
#define WARN 1 /* SOH, not legal char */
|
||||
#define CONC 2 /* STX, not legal char */
|
||||
#define SNUFF 3 /* ETX, not legal char */
|
||||
#define EBLOCK 4 /* EOT, not legal char */
|
||||
|
||||
/* Used in macro expansion */
|
||||
#define RECMAX 400//10000 /* max # of recursive macros */
|
||||
extern struct symtab *norep[RECMAX];
|
||||
extern int norepptr;
|
||||
extern unsigned short bptr[RECMAX];
|
||||
extern int bidx;
|
||||
#define MKB(l,h) (l+((h)<<8))
|
||||
|
||||
/* quick checks for some characters */
|
||||
#define C_SPEC 001
|
||||
#define C_EP 002
|
||||
#define C_ID 004
|
||||
#define C_I (C_SPEC|C_ID)
|
||||
#define C_2 010 /* for yylex() tokenizing */
|
||||
#define C_WSNL 020 /* ' ','\t','\r','\n' */
|
||||
#define iswsnl(x) (spechr[x] & C_WSNL)
|
||||
extern char spechr[];
|
||||
|
||||
/* 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 */
|
||||
const usch *fname; /* current fn, changed if #line found */
|
||||
const usch *orgfn; /* current fn, not changed */
|
||||
int lineno;
|
||||
int infil;
|
||||
uchar *curptr;
|
||||
uchar *maxread;
|
||||
uchar *ostr;
|
||||
uchar *buffer;
|
||||
usch *curptr;
|
||||
usch *maxread;
|
||||
usch *ostr;
|
||||
usch *buffer;
|
||||
int idx;
|
||||
void *incs;
|
||||
const uchar *fn;
|
||||
uchar bbuf[NAMEMAX+CPPBUF+1];
|
||||
} *ifiles;
|
||||
const usch *fn;
|
||||
#ifdef BUF_STACK
|
||||
usch bbuf[BBUFSZ];
|
||||
#else
|
||||
usch *bbuf;
|
||||
#endif
|
||||
};
|
||||
extern struct includ *ifiles;
|
||||
|
||||
/* Symbol table entry */
|
||||
struct symtab {
|
||||
const uchar *namep;
|
||||
const uchar *value;
|
||||
const uchar *file;
|
||||
const usch *namep;
|
||||
const usch *value;
|
||||
const usch *file;
|
||||
int line;
|
||||
};
|
||||
|
||||
@@ -110,13 +145,15 @@ struct nd {
|
||||
#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 */
|
||||
struct symtab *lookup(const usch *namep, int enterf);
|
||||
usch *gotident(struct symtab *nl);
|
||||
extern int slow; /* scan slowly for new tokens */
|
||||
int submac(struct symtab *nl, int);
|
||||
int kfind(struct symtab *nl);
|
||||
int doexp(void);
|
||||
int donex(void);
|
||||
|
||||
int pushfile(const uchar *fname, const uchar *fn, int idx, void *incs);
|
||||
int pushfile(const usch *fname, const usch *fn, int idx, void *incs);
|
||||
void popfile(void);
|
||||
void prtline(void);
|
||||
int yylex(void);
|
||||
@@ -128,18 +165,22 @@ void setline(int);
|
||||
void setfile(char *);
|
||||
int yyparse(void);
|
||||
void yyerror(const char *);
|
||||
void unpstr(const uchar *);
|
||||
uchar *savstr(const uchar *str);
|
||||
void unpstr(const usch *);
|
||||
usch *savstr(const usch *str);
|
||||
void savch(int c);
|
||||
void mainscan(void);
|
||||
void putch(int);
|
||||
void putstr(const uchar *s);
|
||||
void putstr(const usch *s);
|
||||
void line(void);
|
||||
uchar *sheap(const char *fmt, ...);
|
||||
void xwarning(uchar *);
|
||||
void xerror(uchar *);
|
||||
#define warning(args...) xwarning(sheap(args))
|
||||
#define error(args...) xerror(sheap(args))
|
||||
void expmac(struct recur *);
|
||||
usch *sheap(const char *fmt, ...);
|
||||
void xwarning(usch *);
|
||||
void xerror(usch *);
|
||||
#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
|
||||
int cinput(void);
|
||||
void getcmnt(void);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* $Id: cpy.y,v 1.18 2010/02/25 15:49:00 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
|
||||
* All rights reserved.
|
||||
@@ -58,6 +60,7 @@
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
%{
|
||||
|
||||
#include "cpp.h"
|
||||
|
||||
939
src/cmd/cpp/scanner.l
Normal file
939
src/cmd/cpp/scanner.l
Normal file
@@ -0,0 +1,939 @@
|
||||
%{
|
||||
/* $Id: scanner.l,v 1.49 2009/02/14 09:23:55 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* 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 "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "compat.h"
|
||||
#include "cpp.h"
|
||||
#include "y.tab.h"
|
||||
%}
|
||||
|
||||
%{
|
||||
static void cvtdig(int rad);
|
||||
static int charcon(usch *);
|
||||
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((usch *)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((usch *)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((usch *)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((usch *)yytext);
|
||||
return (NUMBER);
|
||||
}
|
||||
if (tflag)
|
||||
yyless(1);
|
||||
if (!flslvl)
|
||||
putstr((usch *)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((usch *)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((usch *)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((usch *)yytext, FIND)) != 0) {
|
||||
usch *op = stringbuf;
|
||||
putstr(gotident(nl));
|
||||
stringbuf = op;
|
||||
} else
|
||||
putstr((usch *)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 */
|
||||
usch *obp = stringbuf;
|
||||
extern usch *prtprag(usch *);
|
||||
*stringbuf++ = yytext[0];
|
||||
do {
|
||||
*stringbuf = input();
|
||||
} while (*stringbuf++ != 14);
|
||||
prtprag(obp);
|
||||
stringbuf = obp;
|
||||
} else {
|
||||
PRTOUT(yytext[0]);
|
||||
}
|
||||
yy:;
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
usch *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(usch *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 = (usch *)"<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()
|
||||
{
|
||||
usch *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(usch *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((usch *)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((usch *)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(usch *s)
|
||||
{
|
||||
usch *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)
|
||||
{
|
||||
usch *opb = stringbuf;
|
||||
int c;
|
||||
|
||||
while ((c = input()) != '\n') {
|
||||
if (c == '/') {
|
||||
if ((c = input()) == '*') {
|
||||
/* ignore comments here whatsoever */
|
||||
usch *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 usch *
|
||||
svinp(void)
|
||||
{
|
||||
int c;
|
||||
usch *cp = stringbuf;
|
||||
|
||||
while ((c = input()) && c != '\n')
|
||||
savch(c);
|
||||
savch('\n');
|
||||
savch(0);
|
||||
BEGIN 0;
|
||||
return cp;
|
||||
}
|
||||
|
||||
static void
|
||||
cpperror(void)
|
||||
{
|
||||
usch *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((usch *)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((usch *)"#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();
|
||||
}
|
||||
22
src/cmd/cpp/tests/res11
Normal file
22
src/cmd/cpp/tests/res11
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
# 1 "<stdin>"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
a
|
||||
a b
|
||||
a b c
|
||||
a b c d
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
__attribute__((__noreturn__))
|
||||
|
||||
|
||||
1 2
|
||||
|
||||
21
src/cmd/cpp/tests/res12
Normal file
21
src/cmd/cpp/tests/res12
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
# 1 "<stdin>"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
2 2 2 2 2;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0,
|
||||
13
src/cmd/cpp/tests/res13
Normal file
13
src/cmd/cpp/tests/res13
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
# 1 "<stdin>"
|
||||
|
||||
|
||||
|
||||
|
||||
long
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
|
||||
|
||||
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);
|
||||
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", "" };
|
||||
|
||||
|
||||
20
src/cmd/cpp/tests/test11
Normal file
20
src/cmd/cpp/tests/test11
Normal file
@@ -0,0 +1,20 @@
|
||||
#define D1(s, ...) s
|
||||
#define D2(s, ...) s D1(__VA_ARGS__)
|
||||
#define D3(s, ...) s D2(__VA_ARGS__)
|
||||
#define D4(s, ...) s D3(__VA_ARGS__)
|
||||
|
||||
D1(a)
|
||||
D2(a, b)
|
||||
D3(a, b, c)
|
||||
D4(a, b, c, d)
|
||||
|
||||
|
||||
#define __sun_attr___noreturn__ __attribute__((__noreturn__))
|
||||
#define ___sun_attr_inner(__a) __sun_attr_##__a
|
||||
#define __sun_attr__(__a) ___sun_attr_inner __a
|
||||
#define __NORETURN __sun_attr__((__noreturn__))
|
||||
__NORETURN
|
||||
#define X(...)
|
||||
#define Y(...) 1 __VA_ARGS__ 2
|
||||
Y(X X() ())
|
||||
|
||||
19
src/cmd/cpp/tests/test12
Normal file
19
src/cmd/cpp/tests/test12
Normal file
@@ -0,0 +1,19 @@
|
||||
#define y 2
|
||||
#define fe(p) sfe(p) p
|
||||
#define sfe(p) p
|
||||
#define Y fe(y) y fe(y)
|
||||
|
||||
Y;
|
||||
|
||||
# define S2B_QMIN 0
|
||||
# define S2B_CMIN (S2B_QMIN + 8)
|
||||
#define S2B_1(i) i,
|
||||
#define S2B_2(i) S2B_1(i) S2B_1(i)
|
||||
#define S2B_4(i) S2B_2(i) S2B_2(i)
|
||||
#define S2B_8(i) S2B_4(i) S2B_4(i)
|
||||
#define S2B_16(i) S2B_8(i) S2B_8(i)
|
||||
#define S2B_32(i) S2B_16(i) S2B_16(i)
|
||||
#define S2B_64(i) S2B_32(i) S2B_32(i)
|
||||
#define S2B_128(i) S2B_64(i) S2B_64(i)
|
||||
#define S2B_256(i) S2B_128(i) S2B_128(i)
|
||||
S2B_256(S2B_CMIN + 0)
|
||||
11
src/cmd/cpp/tests/test13
Normal file
11
src/cmd/cpp/tests/test13
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
#define UL long, foo
|
||||
#define D(I,F) I
|
||||
#define E(I) D(I)
|
||||
E(UL)
|
||||
|
||||
#define FOO 1
|
||||
|
||||
#if (FOO == 1)
|
||||
|
||||
#endif /* FOO */
|
||||
@@ -1,3 +1,5 @@
|
||||
/* $Id: token.c,v 1.48.2.2 2011/03/12 17:08:26 ragge Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004,2009 Anders Magnusson. All rights reserved.
|
||||
*
|
||||
@@ -37,21 +39,24 @@
|
||||
* - inch() is like inpch but \\n and trigraphs are expanded.
|
||||
* - unch() pushes back a character to the input stream.
|
||||
*/
|
||||
#ifdef CROSS
|
||||
# include </usr/include/string.h>
|
||||
#else
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#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 int charcon(usch *);
|
||||
static void elsestmt(void);
|
||||
static void ifdefstmt(void);
|
||||
static void ifndefstmt(void);
|
||||
@@ -75,9 +80,8 @@ extern void yyset_lineno (int);
|
||||
|
||||
static int inch(void);
|
||||
|
||||
size_t strlcat(char *dst, const char *src, size_t siz);
|
||||
|
||||
int inif;
|
||||
extern int dflag;
|
||||
|
||||
#define PUTCH(ch) if (!flslvl) putch(ch)
|
||||
/* protection against recursion in #include */
|
||||
@@ -87,25 +91,16 @@ static int inclevel;
|
||||
/* get next character unaltered */
|
||||
#define NXTCH() (ifiles->curptr < ifiles->maxread ? *ifiles->curptr++ : inpch())
|
||||
|
||||
#ifdef YYTEXT_POINTER
|
||||
static char buf[CPPBUF];
|
||||
char *yytext = buf;
|
||||
#else
|
||||
char yytext[CPPBUF];
|
||||
#endif
|
||||
usch yytext[CPPBUF];
|
||||
|
||||
#define C_SPEC 1
|
||||
#define C_EP 2
|
||||
#define C_ID 4
|
||||
#define C_I (C_SPEC|C_ID)
|
||||
#define C_2 8 /* for yylex() tokenizing */
|
||||
static const char spechr[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, C_SPEC, 0, 0, 0, 0, 0,
|
||||
char spechr[256] = {
|
||||
0, 0, 0, 0, C_SPEC, C_SPEC, 0, 0,
|
||||
0, C_WSNL, C_SPEC|C_WSNL, 0,
|
||||
0, C_WSNL, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, C_2, C_SPEC, 0, 0, 0, C_2, C_SPEC,
|
||||
C_WSNL, C_2, C_SPEC, 0, 0, 0, C_2, C_SPEC,
|
||||
0, 0, 0, C_2, 0, C_2, 0, C_SPEC|C_2,
|
||||
C_I, C_I, C_I, C_I, C_I, C_I, C_I, C_I,
|
||||
C_I, C_I, 0, 0, C_2, C_2, C_2, C_SPEC,
|
||||
@@ -122,14 +117,55 @@ static const char spechr[256] = {
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* No-replacement array. If a macro is found and exists in this array
|
||||
* then no replacement shall occur. This is a stack.
|
||||
*/
|
||||
struct symtab *norep[RECMAX]; /* Symbol table index table */
|
||||
int norepptr = 1; /* Top of index table */
|
||||
unsigned short bptr[RECMAX]; /* currently active noexpand macro stack */
|
||||
int bidx; /* Top of bptr stack */
|
||||
|
||||
static void
|
||||
unch(int c)
|
||||
{
|
||||
|
||||
|
||||
--ifiles->curptr;
|
||||
if (ifiles->curptr < ifiles->bbuf)
|
||||
error("pushback buffer full");
|
||||
*ifiles->curptr = (uchar)c;
|
||||
*ifiles->curptr = (usch)c;
|
||||
}
|
||||
|
||||
static int
|
||||
eatcmnt(void)
|
||||
{
|
||||
int ch;
|
||||
|
||||
if (Cflag) { PUTCH('/'); PUTCH('*'); }
|
||||
for (;;) {
|
||||
ch = inch();
|
||||
if (ch == '\n') {
|
||||
ifiles->lineno++;
|
||||
PUTCH('\n');
|
||||
}
|
||||
if (ch == -1)
|
||||
return -1;
|
||||
if (ch == '*') {
|
||||
ch = inch();
|
||||
if (ch == '/') {
|
||||
if (Cflag) {
|
||||
PUTCH('*');
|
||||
PUTCH('/');
|
||||
} else
|
||||
PUTCH(' ');
|
||||
break;
|
||||
}
|
||||
unch(ch);
|
||||
ch = '*';
|
||||
}
|
||||
if (Cflag) PUTCH(ch);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -146,51 +182,38 @@ static void
|
||||
fastscan(void)
|
||||
{
|
||||
struct symtab *nl;
|
||||
int ch, i;
|
||||
int ch, i, ccnt/*, onemore*/;
|
||||
usch *cp;
|
||||
|
||||
goto run;
|
||||
for (;;) {
|
||||
ch = NXTCH();
|
||||
xloop: if (ch == -1)
|
||||
return;
|
||||
if (dflag>1)
|
||||
printf("fastscan ch %d (%c)\n", ch, ch > 31 ? ch : '@');
|
||||
if ((spechr[ch] & C_SPEC) == 0) {
|
||||
PUTCH(ch);
|
||||
continue;
|
||||
}
|
||||
switch (ch) {
|
||||
case EBLOCK:
|
||||
case WARN:
|
||||
case CONC:
|
||||
error("bad char passed");
|
||||
break;
|
||||
|
||||
case '/': /* Comments */
|
||||
if ((ch = inch()) == '/') {
|
||||
if (Cflag) { PUTCH(ch); } else { PUTCH(' '); }
|
||||
cppcmt: if (Cflag) { PUTCH(ch); } else { PUTCH(' '); }
|
||||
do {
|
||||
if (Cflag) PUTCH(ch);
|
||||
ch = inch();
|
||||
} while (ch != -1 && ch != '\n');
|
||||
goto xloop;
|
||||
} else if (ch == '*') {
|
||||
if (Cflag) { PUTCH('/'); PUTCH('*'); }
|
||||
for (;;) {
|
||||
ch = inch();
|
||||
if (ch == '\n') {
|
||||
ifiles->lineno++;
|
||||
PUTCH('\n');
|
||||
}
|
||||
if (ch == -1)
|
||||
return;
|
||||
if (ch == '*') {
|
||||
ch = inch();
|
||||
if (ch == '/') {
|
||||
if (Cflag) {
|
||||
PUTCH('*');
|
||||
PUTCH('/');
|
||||
} else
|
||||
PUTCH(' ');
|
||||
break;
|
||||
}
|
||||
unch(ch);
|
||||
ch = '*';
|
||||
}
|
||||
if (Cflag) PUTCH(ch);
|
||||
}
|
||||
if (eatcmnt())
|
||||
return;
|
||||
} else {
|
||||
PUTCH('/');
|
||||
goto xloop;
|
||||
@@ -213,11 +236,30 @@ xloop: if (ch == -1)
|
||||
goto xloop;
|
||||
|
||||
case '\n': /* newlines, for pp directives */
|
||||
ifiles->lineno++;
|
||||
run2: ifiles->lineno++;
|
||||
do {
|
||||
PUTCH(ch);
|
||||
run: ch = NXTCH();
|
||||
if (ch == '/') {
|
||||
ch = NXTCH();
|
||||
if (ch == '/')
|
||||
goto cppcmt;
|
||||
if (ch == '*') {
|
||||
if (eatcmnt())
|
||||
return;
|
||||
goto run;
|
||||
}
|
||||
unch(ch);
|
||||
ch = '/';
|
||||
}
|
||||
} while (ch == ' ' || ch == '\t');
|
||||
if (ch == '\\') {
|
||||
ch = NXTCH();
|
||||
if (ch == '\n')
|
||||
goto run2;
|
||||
unch(ch);
|
||||
ch = '\\';
|
||||
}
|
||||
if (ch == '#') {
|
||||
ppdir();
|
||||
continue;
|
||||
@@ -236,7 +278,7 @@ run: ch = NXTCH();
|
||||
case '\"': /* strings */
|
||||
str: PUTCH(ch);
|
||||
while ((ch = inch()) != '\"') {
|
||||
PUTCH(ch);
|
||||
PUTCH(ch);
|
||||
if (ch == '\\') {
|
||||
ch = inch();
|
||||
PUTCH(ch);
|
||||
@@ -257,7 +299,16 @@ str: PUTCH(ch);
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
do {
|
||||
PUTCH(ch);
|
||||
ch = NXTCH();
|
||||
nxt: ch = NXTCH();
|
||||
if (ch == '\\') {
|
||||
ch = NXTCH();
|
||||
if (ch == '\n') {
|
||||
goto nxt;
|
||||
} else {
|
||||
unch(ch);
|
||||
ch = '\\';
|
||||
}
|
||||
}
|
||||
if (spechr[ch] & C_EP) {
|
||||
PUTCH(ch);
|
||||
ch = NXTCH();
|
||||
@@ -305,9 +356,9 @@ con: PUTCH(ch);
|
||||
ch = NXTCH();
|
||||
goto xloop;
|
||||
}
|
||||
i = 0;
|
||||
/*onemore =*/ i = ccnt = 0;
|
||||
do {
|
||||
yytext[i++] = (uchar)ch;
|
||||
yytext[i++] = (usch)ch;
|
||||
ch = NXTCH();
|
||||
if (ch == '\\') {
|
||||
ch = NXTCH();
|
||||
@@ -322,14 +373,17 @@ con: PUTCH(ch);
|
||||
if (ch < 0)
|
||||
return;
|
||||
} while (spechr[ch] & C_ID);
|
||||
|
||||
yytext[i] = 0;
|
||||
unch(ch);
|
||||
if ((nl = lookup((uchar *)yytext, FIND)) != 0) {
|
||||
uchar *op = stringbuf;
|
||||
putstr(gotident(nl));
|
||||
stringbuf = op;
|
||||
|
||||
cp = stringbuf;
|
||||
if ((nl = lookup((usch *)yytext, FIND)) && kfind(nl)) {
|
||||
putstr(stringbuf);
|
||||
} else
|
||||
putstr((uchar *)yytext);
|
||||
putstr((usch *)yytext);
|
||||
stringbuf = cp;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -344,7 +398,7 @@ sloscan()
|
||||
zagain:
|
||||
yyp = 0;
|
||||
ch = inch();
|
||||
yytext[yyp++] = (uchar)ch;
|
||||
yytext[yyp++] = (usch)ch;
|
||||
switch (ch) {
|
||||
case -1:
|
||||
return 0;
|
||||
@@ -357,24 +411,24 @@ zagain:
|
||||
yyp = 0;
|
||||
break;
|
||||
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
/* readin a "pp-number" */
|
||||
ppnum: for (;;) {
|
||||
ch = inch();
|
||||
if (spechr[ch] & C_EP) {
|
||||
yytext[yyp++] = (uchar)ch;
|
||||
yytext[yyp++] = (usch)ch;
|
||||
ch = inch();
|
||||
if (ch == '-' || ch == '+') {
|
||||
yytext[yyp++] = (uchar)ch;
|
||||
yytext[yyp++] = (usch)ch;
|
||||
} else
|
||||
unch(ch);
|
||||
continue;
|
||||
}
|
||||
if ((spechr[ch] & C_ID) || ch == '.') {
|
||||
yytext[yyp++] = (uchar)ch;
|
||||
yytext[yyp++] = (usch)ch;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
unch(ch);
|
||||
@@ -383,11 +437,11 @@ ppnum: for (;;) {
|
||||
return NUMBER;
|
||||
|
||||
case '\'':
|
||||
chlit:
|
||||
chlit:
|
||||
for (;;) {
|
||||
if ((ch = inch()) == '\\') {
|
||||
yytext[yyp++] = (uchar)ch;
|
||||
yytext[yyp++] = (uchar)inch();
|
||||
yytext[yyp++] = (usch)ch;
|
||||
yytext[yyp++] = (usch)inch();
|
||||
continue;
|
||||
} else if (ch == '\n') {
|
||||
/* not a constant */
|
||||
@@ -396,7 +450,7 @@ chlit:
|
||||
ch = '\'';
|
||||
goto any;
|
||||
} else
|
||||
yytext[yyp++] = (uchar)ch;
|
||||
yytext[yyp++] = (usch)ch;
|
||||
if (ch == '\'')
|
||||
break;
|
||||
}
|
||||
@@ -407,7 +461,7 @@ chlit:
|
||||
case ' ':
|
||||
case '\t':
|
||||
while ((ch = inch()) == ' ' || ch == '\t')
|
||||
yytext[yyp++] = (uchar)ch;
|
||||
yytext[yyp++] = (usch)ch;
|
||||
unch(ch);
|
||||
yytext[yyp] = 0;
|
||||
return(WSPACE);
|
||||
@@ -415,7 +469,7 @@ chlit:
|
||||
case '/':
|
||||
if ((ch = inch()) == '/') {
|
||||
do {
|
||||
yytext[yyp++] = (uchar)ch;
|
||||
yytext[yyp++] = (usch)ch;
|
||||
ch = inch();
|
||||
} while (ch && ch != '\n');
|
||||
yytext[yyp] = 0;
|
||||
@@ -435,7 +489,10 @@ chlit:
|
||||
more: while ((c = inch()) && c != '*') {
|
||||
if (c == '\n')
|
||||
putch(c), ifiles->lineno++;
|
||||
else if (c == 1) /* WARN */
|
||||
else if (c == EBLOCK) {
|
||||
(void)inch();
|
||||
(void)inch();
|
||||
} else if (c == 1) /* WARN */
|
||||
wrn = 1;
|
||||
}
|
||||
if (c == 0)
|
||||
@@ -459,7 +516,7 @@ chlit:
|
||||
case '.':
|
||||
ch = inch();
|
||||
if (isdigit(ch)) {
|
||||
yytext[yyp++] = (uchar)ch;
|
||||
yytext[yyp++] = (usch)ch;
|
||||
goto ppnum;
|
||||
} else {
|
||||
unch(ch);
|
||||
@@ -468,14 +525,16 @@ chlit:
|
||||
goto any;
|
||||
|
||||
case '\"':
|
||||
if (tflag)
|
||||
goto any;
|
||||
strng:
|
||||
for (;;) {
|
||||
if ((ch = inch()) == '\\') {
|
||||
yytext[yyp++] = (uchar)ch;
|
||||
yytext[yyp++] = (uchar)inch();
|
||||
yytext[yyp++] = (usch)ch;
|
||||
yytext[yyp++] = (usch)inch();
|
||||
continue;
|
||||
} else
|
||||
yytext[yyp++] = (uchar)ch;
|
||||
} else
|
||||
yytext[yyp++] = (usch)ch;
|
||||
if (ch == '\"')
|
||||
break;
|
||||
}
|
||||
@@ -483,26 +542,26 @@ chlit:
|
||||
return(STRING);
|
||||
|
||||
case 'L':
|
||||
if ((ch = inch()) == '\"') {
|
||||
yytext[yyp++] = (uchar)ch;
|
||||
if ((ch = inch()) == '\"' && !tflag) {
|
||||
yytext[yyp++] = (usch)ch;
|
||||
goto strng;
|
||||
} else if (ch == '\'') {
|
||||
yytext[yyp++] = (uchar)ch;
|
||||
} else if (ch == '\'' && !tflag) {
|
||||
yytext[yyp++] = (usch)ch;
|
||||
goto chlit;
|
||||
}
|
||||
unch(ch);
|
||||
/* FALLTHROUGH */
|
||||
|
||||
/* Yetch, all identifiers */
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'y': case 'z':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'G': case 'H': case 'I': case 'J': case 'K':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
case '_': /* {L}({L}|{D})* */
|
||||
|
||||
@@ -510,7 +569,7 @@ chlit:
|
||||
for (;;) { /* get chars */
|
||||
ch = inch();
|
||||
if (isalpha(ch) || isdigit(ch) || ch == '_') {
|
||||
yytext[yyp++] = (uchar)ch;
|
||||
yytext[yyp++] = (usch)ch;
|
||||
} else {
|
||||
unch(ch);
|
||||
break;
|
||||
@@ -584,27 +643,31 @@ yylex()
|
||||
case NUMBER:
|
||||
if (yytext[0] == '\'') {
|
||||
yylval.node.op = NUMBER;
|
||||
yylval.node.nd_val = charcon((uchar *)yytext);
|
||||
yylval.node.nd_val = charcon((usch *)yytext);
|
||||
} else
|
||||
cvtdig(yytext[0] != '0' ? 10 :
|
||||
yytext[1] == 'x' || yytext[1] == 'X' ? 16 : 8);
|
||||
return NUMBER;
|
||||
|
||||
case IDENT:
|
||||
if (strcmp(yytext, "defined") == 0) {
|
||||
if (strcmp((char *)yytext, "defined") == 0) {
|
||||
ifdef = 1;
|
||||
return DEFINED;
|
||||
}
|
||||
nl = lookup((uchar *)yytext, FIND);
|
||||
nl = lookup((usch *)yytext, FIND);
|
||||
if (ifdef) {
|
||||
yylval.node.nd_val = nl != NULL;
|
||||
ifdef = 0;
|
||||
} else if (nl && noex == 0) {
|
||||
uchar *c, *och = stringbuf;
|
||||
usch *och = stringbuf;
|
||||
int i;
|
||||
|
||||
c = gotident(nl);
|
||||
unch(1);
|
||||
unpstr(c);
|
||||
i = kfind(nl);
|
||||
unch(WARN);
|
||||
if (i)
|
||||
unpstr(stringbuf);
|
||||
else
|
||||
unpstr(nl->namep);
|
||||
stringbuf = och;
|
||||
noex = 1;
|
||||
return yylex();
|
||||
@@ -613,7 +676,7 @@ yylex()
|
||||
}
|
||||
yylval.node.op = NUMBER;
|
||||
return NUMBER;
|
||||
case 1: /* WARN */
|
||||
case WARN:
|
||||
noex = 0;
|
||||
return yylex();
|
||||
default:
|
||||
@@ -623,7 +686,7 @@ yylex()
|
||||
return ch;
|
||||
}
|
||||
|
||||
uchar *yyp, yybuf[CPPBUF];
|
||||
usch *yyp, yybuf[CPPBUF];
|
||||
|
||||
int yywrap(void);
|
||||
|
||||
@@ -671,41 +734,6 @@ msdos: if ((c = inpch()) == '\n') {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
* full size of dst, not space left). At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||
* Returns strlen(initial dst) + strlen(src); if retval >= siz,
|
||||
* truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcat(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return(dlen + strlen(s));
|
||||
while (*s != '\0') {
|
||||
if (n != 1) {
|
||||
*d++ = *s;
|
||||
n--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
return(dlen + (s - src)); /* count does not include NUL */
|
||||
}
|
||||
|
||||
/*
|
||||
* Let the command-line args be faked defines at beginning of file.
|
||||
*/
|
||||
@@ -754,30 +782,29 @@ prinit(struct initar *it, struct includ *ic)
|
||||
* Return 0 on success, -1 if file to be included is not found.
|
||||
*/
|
||||
int
|
||||
pushfile(const uchar *file, const uchar *fn, int idx, void *incs)
|
||||
pushfile(const usch *file, const usch *fn, int idx, void *incs)
|
||||
{
|
||||
extern struct initar *initar;
|
||||
struct includ ibuf;
|
||||
struct includ *ic;
|
||||
int otrulvl;
|
||||
|
||||
ic = malloc(sizeof(struct includ));
|
||||
if (ic == NULL)
|
||||
error("out of memory for %s", file);
|
||||
ic = &ibuf;
|
||||
ic->next = ifiles;
|
||||
|
||||
if (file != NULL) {
|
||||
ic->infil = open((const char *)file, O_RDONLY);
|
||||
if (ic->infil < 0) {
|
||||
free(ic);
|
||||
if ((ic->infil = open((const 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 = (const uchar *)"<stdin>";
|
||||
ic->orgfn = ic->fname = (const usch *)"<stdin>";
|
||||
}
|
||||
#ifndef BUF_STACK
|
||||
ic->bbuf = malloc(BBUFSZ);
|
||||
#endif
|
||||
ic->buffer = ic->bbuf+NAMEMAX;
|
||||
ic->curptr = ic->buffer;
|
||||
ifiles = ic;
|
||||
@@ -794,8 +821,7 @@ pushfile(const uchar *file, const uchar *fn, int idx, void *incs)
|
||||
prinit(initar, ic);
|
||||
initar = NULL;
|
||||
if (dMflag)
|
||||
if (write(ofd, ic->buffer, strlen((char *)ic->buffer)) < 0)
|
||||
/* ignore */;
|
||||
write(ofd, ic->buffer, strlen((char *)ic->buffer));
|
||||
fastscan();
|
||||
prtline();
|
||||
ic->infil = oin;
|
||||
@@ -808,9 +834,11 @@ pushfile(const uchar *file, const uchar *fn, int idx, void *incs)
|
||||
if (otrulvl != trulvl || flslvl)
|
||||
error("unterminated conditional");
|
||||
|
||||
#ifndef BUF_STACK
|
||||
free(ic->bbuf);
|
||||
#endif
|
||||
ifiles = ic->next;
|
||||
close(ic->infil);
|
||||
free(ic);
|
||||
inclevel--;
|
||||
return 0;
|
||||
}
|
||||
@@ -821,15 +849,14 @@ pushfile(const uchar *file, const uchar *fn, int idx, void *incs)
|
||||
void
|
||||
prtline()
|
||||
{
|
||||
uchar *s, *os = stringbuf;
|
||||
usch *s, *os = stringbuf;
|
||||
|
||||
if (Mflag) {
|
||||
if (dMflag)
|
||||
return; /* no output */
|
||||
if (ifiles->lineno == 1) {
|
||||
s = sheap("%s: %s\n", Mfile, ifiles->fname);
|
||||
if (write(ofd, s, strlen((char *)s)) < 0)
|
||||
/* ignore */;
|
||||
write(ofd, s, strlen((char *)s));
|
||||
}
|
||||
} else if (!Pflag)
|
||||
putstr(sheap("\n# %d \"%s\"\n", ifiles->lineno, ifiles->fname));
|
||||
@@ -840,8 +867,8 @@ void
|
||||
cunput(int c)
|
||||
{
|
||||
#ifdef CPP_DEBUG
|
||||
extern int dflag;
|
||||
if (dflag)printf(": '%c'(%d)", c > 31 ? c : ' ', c);
|
||||
// extern int dflag;
|
||||
// if (dflag)printf(": '%c'(%d)\n", c > 31 ? c : ' ', c);
|
||||
#endif
|
||||
#if 0
|
||||
if (c == 10) {
|
||||
@@ -873,7 +900,7 @@ cvtdig(int rad)
|
||||
{
|
||||
unsigned long long rv = 0;
|
||||
unsigned long long rv2 = 0;
|
||||
char *y = yytext;
|
||||
usch *y = yytext;
|
||||
int c;
|
||||
|
||||
c = *y++;
|
||||
@@ -900,7 +927,7 @@ cvtdig(int rad)
|
||||
}
|
||||
|
||||
static int
|
||||
charcon(uchar *p)
|
||||
charcon(usch *p)
|
||||
{
|
||||
int val, c;
|
||||
|
||||
@@ -993,8 +1020,8 @@ skpln(void)
|
||||
}
|
||||
|
||||
static void
|
||||
ifdefstmt(void)
|
||||
{
|
||||
ifdefstmt(void)
|
||||
{
|
||||
int t;
|
||||
|
||||
if (flslvl) {
|
||||
@@ -1006,7 +1033,7 @@ ifdefstmt(void)
|
||||
while (t == WSPACE);
|
||||
if (t != IDENT)
|
||||
error("bad ifdef");
|
||||
if (lookup((uchar *)yytext, FIND) == 0) {
|
||||
if (lookup((usch *)yytext, FIND) == 0) {
|
||||
putch('\n');
|
||||
flslvl++;
|
||||
} else
|
||||
@@ -1015,8 +1042,8 @@ ifdefstmt(void)
|
||||
}
|
||||
|
||||
static void
|
||||
ifndefstmt(void)
|
||||
{
|
||||
ifndefstmt(void)
|
||||
{
|
||||
int t;
|
||||
|
||||
if (flslvl) {
|
||||
@@ -1028,7 +1055,7 @@ ifndefstmt(void)
|
||||
while (t == WSPACE);
|
||||
if (t != IDENT)
|
||||
error("bad ifndef");
|
||||
if (lookup((uchar *)yytext, FIND) != 0) {
|
||||
if (lookup((usch *)yytext, FIND) != 0) {
|
||||
putch('\n');
|
||||
flslvl++;
|
||||
} else
|
||||
@@ -1037,7 +1064,7 @@ ifndefstmt(void)
|
||||
}
|
||||
|
||||
static void
|
||||
endifstmt(void)
|
||||
endifstmt(void)
|
||||
{
|
||||
if (flslvl) {
|
||||
flslvl--;
|
||||
@@ -1094,11 +1121,11 @@ elifstmt(void)
|
||||
error("If-less elif");
|
||||
}
|
||||
|
||||
static uchar *
|
||||
static usch *
|
||||
svinp(void)
|
||||
{
|
||||
int c;
|
||||
uchar *cp = stringbuf;
|
||||
usch *cp = stringbuf;
|
||||
|
||||
while ((c = inch()) && c != '\n')
|
||||
savch(c);
|
||||
@@ -1110,7 +1137,7 @@ svinp(void)
|
||||
static void
|
||||
cpperror(void)
|
||||
{
|
||||
uchar *cp;
|
||||
usch *cp;
|
||||
int c;
|
||||
|
||||
if (flslvl)
|
||||
@@ -1128,7 +1155,7 @@ cpperror(void)
|
||||
static void
|
||||
cppwarning(void)
|
||||
{
|
||||
uchar *cp;
|
||||
usch *cp;
|
||||
int c;
|
||||
|
||||
if (flslvl)
|
||||
@@ -1158,7 +1185,7 @@ undefstmt(void)
|
||||
|
||||
if (sloscan() != WSPACE || sloscan() != IDENT)
|
||||
error("bad undef");
|
||||
if (flslvl == 0 && (np = lookup((uchar *)yytext, FIND)))
|
||||
if (flslvl == 0 && (np = lookup((usch *)yytext, FIND)))
|
||||
np->value = 0;
|
||||
chknl(0);
|
||||
}
|
||||
@@ -1171,7 +1198,7 @@ pragmastmt(void)
|
||||
if (sloscan() != WSPACE)
|
||||
error("bad pragma");
|
||||
if (!flslvl)
|
||||
putstr((const uchar *)"#pragma ");
|
||||
putstr((const usch *)"\n#pragma ");
|
||||
do {
|
||||
c = inch();
|
||||
if (!flslvl)
|
||||
@@ -1265,7 +1292,7 @@ ppdir(void)
|
||||
goto out; /* something else, ignore */
|
||||
i = 0;
|
||||
do {
|
||||
bp[i++] = (uchar)ch;
|
||||
bp[i++] = (usch)ch;
|
||||
if (i == sizeof(bp)-1)
|
||||
goto out; /* too long */
|
||||
ch = inch();
|
||||
|
||||
Reference in New Issue
Block a user