Merge pull request #28 from alexfru/master

Update cpp to pcc 1.0.0's cpp
This commit is contained in:
Serge Vakulenko
2014-05-14 22:39:59 -07:00
16 changed files with 2384 additions and 947 deletions

View File

@@ -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
View 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
View 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
View 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__

File diff suppressed because it is too large Load Diff

View File

@@ -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);

View File

@@ -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
View 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
View 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
View 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
View File

@@ -0,0 +1,13 @@
# 1 "<stdin>"
long

View File

@@ -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
View 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
View 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
View 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 */

View File

@@ -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();