Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
mkver -e "Preprocessor -"
c68 -L -r -DMC68000 -c cexpr.c
c68 -L -r -DMC68000 -c lex.c
c68 -L -r -DMC68000 -c macro.c
c68 -L -r -DMC68000 -c main.c
c68 -L -r -DMC68000 -n version.c cexpr.o lex.o macro.o main.o -o cpp68.4k -l6
setstack cpp68.4k 8000 8000

View File

@@ -0,0 +1,7 @@
mkver -e "Preprocessor -"
cc -w -DPDP11 -c cexpr.c
cc -w -DPDP11 -c lex.c
cc -w -DPDP11 -c macro.c
cc -w -DPDP11 -c main.c
cc -w -DPDP11 -c version.c
cc -n version.o cexpr.o lex.o macro.o main.o seek.o lseek.o -l6 -lC -o cpp68.pdp

View File

@@ -0,0 +1,7 @@
mkver -e "Preprocessor -"
cc -O -w -DVAX11 -c cexpr.c
cc -O -w -DVAX11 -c lex.c
cc -O -w -DVAX11 -c macro.c
cc -O -w -DVAX11 -c main.c
cc -O -w -DVAX11 -c version.c
cc -n version.o cexpr.o lex.o macro.o main.o ../binary/libV.a -o cpp68.vax

View File

@@ -0,0 +1,7 @@
mkver "preproc - ";
c68 -S -L -DMC68000 -DVERSADOS cexpr.c
c68 -S -L -DMC68000 -DVERSADOS lex.c
c68 -S -L -DMC68000 -DVERSADOS macro.c
c68 -S -L -DMC68000 -DVERSADOS main.c
c68 -S -L -DMC68000 -DVERSADOS version.c
mv *.s vst

View File

@@ -0,0 +1,340 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "preproc.h"
#define OPPRI 077
#define OPBIN 0100
#define STKLEN 64
int oprstk[STKLEN]; /*operator stack*/
int opnstk[STKLEN]; /*operand stack*/
int pristk[STKLEN]; /*operator priority stack*/
int *oprptr; /*pointer to operator stack*/
int *opnptr; /*pointer to operand stack*/
int *priptr; /*pointer to priority stack*/
int cvalue;
int opinfo[] = {
0, /*EOF=0*/
16|OPBIN, /*SUB=1*/
16|OPBIN, /*ADD=2*/
20, /*NOT=3*/
20, /*NEG=4*/
22, /*LPAREN=5*/
2, /*RPAREN=6*/
6|OPBIN, /*QMARK=7*/
6|OPBIN, /*COLON=8*/
8|OPBIN, /*OR=9*/
10|OPBIN, /*AND=10*/
8|OPBIN, /*XOR=11*/
12|OPBIN, /*EQUAL=12*/
12|OPBIN, /*NEQUAL=13*/
14|OPBIN, /*LESS=14*/
14|OPBIN, /*LSEQUAL=15*/
14|OPBIN, /*GREAT=16*/
14|OPBIN, /*GREQUAL=17*/
4|OPBIN, /*LSHIFT=18*/
4|OPBIN, /*RSHIFT=19*/
18|OPBIN, /*MULT=20*/
18|OPBIN, /*DIV=21*/
18|OPBIN, /*MOD=22*/
20, /*COMPL=23*/
};
/* cexpr - constant expression evaluation*/
/* Does priority-driven operator/operand stack evaluation of*/
/* constant expressions.*/
cexpr() /* returns constant evaluated*/
{
register int lop, type;
oprptr = &oprstk[0];
opnptr = &opnstk[0];
priptr = &pristk[0];
*priptr = 0;
lop = -1;
while(1) {
switch( type = getctok() ) {
case CONST:
if( !lop ) /*last was not operator*/
goto syntax;
if( opnptr >= &opnstk[STKLEN] ) {
error("expression stack overflow");
cexit();
}
lop = FALSE;
*++opnptr = cvalue;
continue;
case SUB:
if( lop )
type = NEG; /*unary minus*/
break;
case ADD:
if( lop )
continue; /*ignore unary +*/
break;
case COMPL:
case LPAREN:
case NOT:
if( !lop )
goto syntax;
break;
case RPAREN:
if( lop )
goto syntax;
lop = FALSE;
if( !stkop(type) )
goto syntax;
continue;
case NEWL:
case EOF:
if( lop || !stkop(EOF) || opnptr != &opnstk[1] )
goto syntax;
type = opnstk[1];
putback('\n');
return(type);
default:
if( lop || type > LASTOP )
goto syntax;
break;
}
lop = TRUE;
if( !stkop(type) )
goto syntax;
}
syntax:
error("expression syntax");
if( type == NEWL )
putback('\n');
return(0);
}
/* getctok - get a constant expression token*/
/* Handles conversion of quoted character strings and numbers.*/
getctok()
{
register int type, c, count;
register char *p;
char token[TOKSIZE];
while( 1 ) {
switch( type = getntok(token) ) {
case DIGIT:
cvalue = const(token);
return(CONST);
case SQUOTE:
for( cvalue = 0, p = &token[1], count = 2; --count >= 0; ) {
if( (c= *p++) == '\'' )
break;
if( c == '\\' ) {
if( *p >= '0' && *p <= '7' ) {
for( c = 0; *p >= '0' && *p <= '7'; )
c = (c<<3) + (*p++ - '0');
}
else switch( c = *p++ ) {
case 'n':
c = '\n';
break;
case 't':
c = '\t';
break;
case 'b':
c = '\b';
break;
case 'r':
c = '\r';
break;
case 'f':
c = '\f';
break;
}
}
cvalue = (cvalue<<8) | c;
}
return(CONST);
case ALPHA:
if( p = lookup(token) )
expand((struct symbol *)p);
else
return(ALPHA);
break;
default:
return(type);
}
}
}
/* stkop - stack an operator on the operand stack*/
/* Unstack all operators of lower priority, evaluating them as*/
/* they are unstacked.*/
stkop(opr) /* returns 1 if ok, 0 otherwise*/
int opr; /* operator to stack*/
{
register int op1, op2, pri;
for( pri = opinfo[opr]&OPPRI; pri < *priptr; ) {
if( *oprptr == LPAREN ) {
if( opr == RPAREN ) {
oprptr--;
priptr--;
return(1);
}
break;
}
op1 = *opnptr;
if( opinfo[*oprptr] & OPBIN ) {
op2 = op1;
op1 = *--opnptr;
}
switch(*oprptr) { /*operator*/
case ADD:
op1 += op2;
break;
case SUB:
op1 -= op2;
break;
case COLON:
priptr--;
if( *--oprptr != QMARK )
return(0);
op1 = (*--opnptr ? op1 : op2);
break;
case QMARK:
return(0);
case XOR:
op1 ^= op2;
break;
case OR:
op1 |= op2;
break;
case AND:
op1 &= op2;
break;
case EQUAL:
op1 = (op1 == op2);
break;
case NEQUAL:
op1 = (op1 != op2);
break;
case LESS:
op1 = (op1 < op2);
break;
case LSEQUAL:
op1 = (op1 <= op2);
break;
case GREAT:
op1 = (op1 > op2);
break;
case GREQUAL:
op1 = (op1 >= op2);
break;
case LSHIFT:
op1 = (op1 << op2);
break;
case RSHIFT:
op1 = (op1 >> op2);
break;
case NEG:
op1 = -op1;
break;
case NOT:
op1 = !op1;
break;
case COMPL:
op1 = ~ op1;
break;
case MULT:
op1 *= op2;
break;
case DIV:
op1 /= op2;
break;
case MOD:
op1 %= op2;
break;
}
*opnptr = op1;
priptr--;
oprptr--;
}
if( priptr >= &pristk[STKLEN-1] ) {
error("expression operator stack overflow");
cexit();
}
*++oprptr = opr; /*operator value*/
*++priptr = pri; /*operator priority*/
return(1);
}
#define toupper(c) ((c) & ~32)
/* const - alpha to int conversion, handles octal and hexidecimal*/
/* Uses Horner's method to evaluate number.*/
const(str) /* returns number evaluated*/
char *str; /* pointer to string to convert*/
{
register int c, ch, i, radix;
i = 0;
radix = 10;
if( *str == '0' ) {
radix = 8;
if( *++str == 'x' || *str == 'X' ) {
radix = 16;
str++;
}
}
while( c = *str++ ) {
if( (ch=toupper(c)) >= 'A' && ch <= 'F' )
c = ch - ('A'-10);
else if( c >= '0' && c <= '9' )
c -= '0';
else
break;
if( c >= radix )
break;
i = i*radix + c;
}
return(i);
}

View File

@@ -0,0 +1,35 @@
argument buffer overflow
bad -o option
bad argument: (name)
bad character
bad define name: (name)
bad include file (filename)
bad include file name (filename)
can't creat file (filename)
can't open include file: (filename)
can't open source file (filename)
condition stack overflow
define recursion
define table overflow
expression operator stack overflow
expression stack overflow
expression syntax
includes nested too deeply
incompatible flags : '-f' and '-e'
invalid #else
invalid #endif
invalid #line args
invalid preprocessor command
line overflow
macro argument too long
no */ before EOF
string cannot cross line
string too long
symbol table overflow
too many args
too many arguments
too many characters pushed back
too many files
too many loader args
unexpected EOF
unmatched conditional

View File

@@ -0,0 +1,411 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "preproc.h"
int Eflag;
int status;
extern char null[];
char ctype[] = {
EOF, ANYC, ANYC, ANYC, ANYC, ANYC, ANYC, ANYC,
ANYC, WHITE, NEWL, ANYC, ANYC, ANYC, ANYC, ANYC,
ANYC, ANYC, ANYC, ANYC, NEWL, ANYC, ANYC, ANYC,
ANYC, ANYC, ANYC, ANYC, ANYC, ANYC, ANYC, ANYC,
WHITE, NOT, DQUOTE, POUND, ANYC, MOD, AND, SQUOTE,
LPAREN, RPAREN, MULT, ADD, COMMA, SUB, ANYC, DIV,
DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
DIGIT, DIGIT, COLON, ANYC, LESS, EQUAL, GREAT, QMARK,
ANYC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ANYC, BSLASH, ANYC, XOR, ALPHA,
ANYC, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA,
ALPHA, ALPHA, ALPHA, ANYC, OR, ANYC, COMPL, ANYC
}; /* BUG2 - ANYC */
/* symhash - compute hash value for symbol*/
/* Sums the symbols characters and takes that modulus the hash table*/
/* size.*/
symhash(sym) /* returns hash value for symbol*/
char *sym; /* pointer to symbol*/
{
register char *p;
register int hashval, i;
for( p = sym, i = SSIZE, hashval = 0; *p != '\0' && i > 0; i-- )
hashval += *p++;
return( hashval % (HSIZE - 2 )); /* [vlh] 4.1 added -2 */
}
/* symequal - check for symbol equality*/
/* Does comparison between two symbols.*/
symequal(sym1,sym2) /* returns 1 if equal, 0 otherwise*/
char *sym1; /* pointer to first symbol*/
char *sym2; /* pointer to second symbol*/
{
register char *p, *q;
register int i;
q = sym2;
i = SSIZE;
for( p = sym1; *p == *q++; )
if( *p++ == '\0' || --i == 0 ) {
return(1);
}
return(0);
}
/* symcopy - symbol copy*/
/* Copies one symbol to another.*/
symcopy(sym1,sym2) /* returns - none*/
char *sym1; /* pointer to symbol to copy*/
char *sym2; /* pointer to area to copy to*/
{
register char *p, *q;
register int i;
for( p = sym1, q = sym2, i = SSIZE; --i >= 0; )
if( *p )
*q++ = *p++;
else
*q++ = '\0';
*q = '\0'; /* [vlh] 4.1, force null terminator */
}
/* error - output error message*/
/* Outputs line number and error message and keeps track of errors.*/
error(s,x1,x2,x3,x4,x5,x6) /* returns - none*/
char *s; /* printf string*/
int x1, x2, x3, x4, x5, x6; /* printf args*/
{
if (literal)
printf((char *)STDERR,"%s, # line %d: ",lit_file, lit_num);
else if (filep == &filestack[0]) /* [vlh] 3.4 not in include */
printf((char *)STDERR,"%s, # line %d: ",source, lineno);
else
printf((char *)STDERR,"%s, # line %d: ",(filep-1)->ifile,(filep-1)->lineno);
printf((char *)STDERR,s,x1,x2,x3,x4,x5,x6);
cputc('\n',STDERR);
status++;
}
/* putback - puts back a single character*/
/* Checks for push back buffer overflow.*/
putback(c)
int c;
{
if( pbp >= &pbbuf[PBSIZE] ) {
error("too many characters pushed back");
cexit();
}
*pbp++ = c;
}
/* pbtok - push back a token*/
/* Reverses token as its pushing it back.*/
pbtok(s)
char *s;
{
register char *p;
for( p = s + strlen(s); p > s ; )
putback(*--p);
}
/* ngetch - get a (possibly) pushed back character*/
/* This handles the include file stack and incrementing the line*/
/* number for the lowest level file.*/
ngetch() /* returns character or EOF*/
{
register int c, i;
register char *p, *q;
if( pbp > &pbbuf[0] )
return(*--pbp);
pbflag = 0;
while( (c=getc(&inbuf)) < 0 ) {
if( filep == &filestack[0] )
return(EOF);
close(inbuf.fd);
filep--;
#ifdef NONEST
inbuf.cc = filep->tcc;
inbuf.cp = filep->tcp;
p = &inbuf.cbuf[0];
q = &filep->tbuf[0];
for(i = 0; i<BSIZE; i++)
*p++ = *q++;
#else
inbuf.cc = 0;
inbuf.cp = &inbuf.cbuf[0];
#endif
inbuf.fd = filep->ifd;
if( filep == &filestack[0] ) { /*need line for #include...*/
lineno++;
putid(source,lineno); /* [vlh] 4.2 id line .... */
}
else {
(filep-1)->lineno++;
putid((filep-1)->ifile,(filep-1)->lineno);
}
}
return( c );
}
/*
* getsp - get symbol pointer
* Calculates the symbol table pointer for a given symbol, if symbol
* is not defined, will point to appropriate place to insert symbol.
*/
struct symbol *getsp(name)
char *name;
{
register int wrap;
register struct symbol *sp, *asp;
wrap = 0;
asp = 0;
for( sp = &symtab[symhash(name)]; sp->s_def != null; ) {
if( symequal(sp->s_name,name) )
return(sp);
if( !asp && sp->s_def == null )
asp = sp;
if( ++sp >= &symtab[HSIZE] ) {
if( wrap++ ) {
error("symbol table overflow");
cexit();
}
sp = &symtab[0];
}
}
return( asp ? asp : sp );
}
/* lookup - looks up a symbol to see if it is defined*/
/* Returns pointer to definition if found.*/
char *lookup(name) /* returns 0 or ptr to symbol*/
char *name; /* symbol name*/
{
register struct symbol *sp;
sp = getsp(name);
if( sp->s_def == 0 || sp->s_def == null )
return(0);
return((char *)sp);
}
/**
* gettok - gets next token from input
* Collects character string in token and handles special tokens for
* the expression evaluator.
**/
gettok(token) /* returns token type*/
char *token;
{
register char *p, c, *s;
register int type, t, l;
p = token;
c = ngetch();
*p++ = c;
switch( type = ctype[c] ) {
case SQUOTE:
case DQUOTE:
getstr(token,TOKSIZE,c);
return(type);
case DIGIT:
case ALPHA:
for( ; p < &token[TOKSIZE]; p++ ) {
*p = ngetch();
if( (t=ctype[*p]) != ALPHA && t != DIGIT )
break;
}
putback(*p);
break;
case NOT:
if( peekis('=') ) {
type = NEQUAL;
*p++ = '=';
}
break;
case GREAT:
if( peekis('>') ) {
type = RSHIFT;
*p++ = '>';
}
else if( peekis('=') ) {
type = GREQUAL;
*p++ = '=';
}
break;
case LESS:
if( peekis('<') ) {
type = LSHIFT;
*p++ = '<';
}
else if( peekis('=') ) {
type = LSEQUAL;
*p++ = '=';
}
break;
case EQUAL:
if( peekis('=') )
*p++ = '=';
else
type = ANYC;
break;
case DIV:
if( peekis('*') ) {
if (Cflag) {
putl((int)'/');
putl((int)'*');
}
l = lineno;
while( (c=ngetch()) != EOF )
if( c == '\n' ) {
if( filep == &filestack[0] && pbp == &pbbuf[0] )
lineno++;
if (Cflag) { /* [vlh] 4.2 */
putl((int)'\0');
s = line;
while (*s)
doputc(*s++,&outbuf);
initl();
}
doputc(' ',&outbuf);
doputc('\n',&outbuf);
}
else if( c == '*' && peekis('/') ) {
if (Cflag) { /* [vlh] 4.2 */
putl((int)'*');
putl((int)'/');
}
break;
}
else if (Cflag) /* [vlh] 4.2.c */
putl((int)c);
if( c == EOF ) {
lineno = l;
error("no */ before EOF");
}
type = WHITE;
token[0] = ' ';
}
else if( peekis('/') ) {
if (Cflag) {
putl((int)'/');
putl((int)'/');
}
while( (c=ngetch()) != EOF && c != '\n' )
if (Cflag)
putl(c);
type = NEWL;
token[0] = '\n';
}
break;
case BADC:
error("bad character 0%o",c);
break;
}
*p = '\0';
return(type);
}
/* getstr - get a quoted (single or double) character string*/
/* Gets specified number of characters, handling escapes.*/
getstr(str,nchars,endc) /* returns - none*/
char *str; /* pointer to string buffer*/
int nchars; /* max number of characters*/
char endc; /* ending string character*/
{
register char *p;
register int i, c;
p = str;
*p++ = endc;
for( i = nchars-2; (c=ngetch()) != endc; ) {
if( c == EOF || c == '\n' ) {
error("string cannot cross line");
break;
}
if( --i > 0 ) /*BUG 1*/
*p++ = c;
else if( !i )
error("string too long");
if( c == '\\' ) {
c = ngetch();
if( --i > 0 ) /*BUG 1*/
*p++ = c;
else if( !i )
error("string too long");
}
}
*p++ = endc;
*p = '\0';
}
/* peekis - peeks at next character for specific character*/
/* Gets next (possibly pushed back) character, if it matches*/
/* the given character 1 is returned, otherwise the character*/
/* is put back.*/
peekis(tc) /* returns 1 if match, 0 otherwise*/
int tc; /* test character*/
{
register int c;
if( (c=ngetch()) == tc )
return(1);
putback(c);
return(0);
}
doputc(ch,buffer)
char ch;
struct iob *buffer;
{
if (!Eflag)
putc(ch,buffer);
else
putchar(ch);
}
#ifdef VAX11
getc(ibuf)
struct iob *ibuf;
{
if (ibuf->cc <= 0) {
ibuf->cp = &(ibuf->cbuf[0]);
ibuf->cc = read(ibuf->fd,ibuf->cp,BSIZE);
}
if (ibuf->cc <= 0)
return(-1);
ibuf->cc--;
return((int)(*(ibuf->cp)++)&0xff);
}
fopen(fname,ibuf)
char *fname;
register struct iob *ibuf;
{
ibuf->cc = 0; /* no chars */
ibuf->fd = open(fname,0);
return(ibuf->fd);
}
#endif

View File

@@ -0,0 +1,216 @@
.he "C68 Preprocessor"Change Log"Page %"
.de bg
.sp
.in +5
..
.de eg
.sp
.in -5
..
1. 4/20/82 - Long string bug
.bg
No error message for long string, caused in getstr checking for
"i-- > 0" then "i == 0". Also increased TOKSIZE to 300 to match
setting in parser.
.eg
2. 4/21/82 - Invalid characters not invalid
.bg
It was assumed that the only characters that would go thru the
preprocessor were those that were valid for the compiler. Using
preprocessor with the assembler (i.e. #define x $1) does not
work. Fixed cmap table.
.eg
3. 4/26/82 - Assembler temps not being deleted
.bg
Main not deleting assembler temps if more than one C file specified.
Added unlink to delete assembler temps.
.eg
4. 4/28/82 - Preprocessor enhancements
.bg
Changed '-D' flag to '-N' flag, Added '-D' flag to define a name.
Added built-in macros Newlabel[(num)] and Label[(num)] to
generate label numbers for assembler.
.eg
5. 5/8/82 - Added handling of ".s" files
.bg
Added code to check for ".s" files, which go thru the preprocessor
and then thru the assembler.
.eg
6. 5/8/82 - Suppress '\01' on macro file for -P flag
.bg
Added check in domacro to check for pflag, and if it is on, suppress
the outputting of '\01' to expanded macro file.
.eg
7. 5/20/82 - defines gobbling up parenthesised expressions
.bg
the syntax: #define x 1 (newline) x(1) resulted in only "1". This was
because expand always checked for a left parenthesis for any macro name.
Added NOARG flag at beginning of macro or argument count in dodefine
(although this is not used). The arguments are only collected if there
were args (or left parenthesis-right parenthesis) seen on the macro
definition.
.eg
8. 6/7/82 - multiple assembler files leaving temps
.bg
If more than one assembler file was given, the macro temp file was left.
Fixed problem in main.
.eg
9. 7/8/82 - added one pass logic
.bg
Added logic in main to add the "-1" flag, which runs the one pass
parser and code generator, which is 10% faster.
.eg
10. 7/17/82 - "-o" flag wiped out C file
.bg
The command "c68 -o x.c" would wipe out x.c.
Added code to main to check argument given for -o flag, made output file
the file name stripped of the ".c" or ".s".
.eg
11. 7/28/82 - checked for rubouts ignored
.bg
C68 was unconditionally catching rubouts whether its rubout signals were
ignored or not.
This had the (unfortunate) side effect of killing C68 in background
when you did a rubout from the terminal.
Added check to signal call to check if signal was ignored, and if so
the ignore condition was restored.
.eg
12. 8/26/82 - libraries not being handled properly
.bg
The -lX flag would be placed at the beginning of the loader's argument
list, thereby missing the library.
Changed main so that the loader arguments would be passed in the same
order as the c68 command line and the c068.o would be added before the
first .o file specified.
Also checked for: -o x.o and stripped off .o for output file name.
.eg
13. 9/1/82 - changed misleading "can't fork" message
.bg
Changed message in fexec so that "can't fork" message is now
"can't maketask [filename]".
This is to keep John Happy...
.eg
14. 11/15/82 - Multiple compiles define carry overs
.bg
The symbol table was not being cleared of defines which occured in
previous source files in a multi-source compile.
.eg
15. 11/15/82 - Paths of generated files
.bg
All files are now generated in the users current working directory
instead of the source directory by default.
.eg
16. 11/24/82 - Include file search paths
.bg
Added the -Idir flag to enable the user to alter the search path.
Also added searching of the parent directory of include files
specified using quotes.
.eg
17. 12/2/82 - Include file error messages
.bg
Added the include file name and line number to the preprocessor output
in order to generate error messages which specified the exact location
of errors which involve include files. Also suppressed output of
empty include file lines to the preprocessor temporary output file.
.eg
18. 12/28/82 - Temp files generated in the current directory
.bg
In generating all other files into the current directory the temp files
also were generated there.
.eg
18. 1/7/83 - Floating Point flags
.bg
Added the -e and -f flags for specification of the IEEE or FFP floating
point packages (constant evaluations and libraries).
.eg
19. 1/17/83 - Optimization flag
.bg
Recognize the -O optimization flag and ignore it.
.eg
20. 1/20/83 - Compatibility flags
.bg
Added the -3, -5, -6, -7 flags for system 3, system 5, version 6 and
version 7. Adds an include file on the search list, as well as a
default library.
.eg
21. 1/24/83 - include file error messages
.bg
Added explicit line number and file name's within the error messages if
processing an include file.
.eg
22. 1/24/83 - Symbol Table overflow
.bg
Added clearing of the symbol table between compiles (c68 *.c).
.eg
23. 2/7/83 - Preprocessor error status
.bg
If error's occurred in the preprocessor pass the exit status wasn't
reflecting it.
.eg
24. 2/22/83 - #line macro
.bg
Implemented the "#line LINENUM [FILENAME]" macro.
.eg
25. 2/23/83 - "-E" option flag
.bg
Implemented the "-E" flag, only the preprocessor is executed and the
output is written to the standard output device.
.eg
26. 3/3/83 - bus error on non-existent file error message
.bg
Error required certain variables to have been initialized in order to
generate the filename and the line number on which the error occured.
.eg
27. 3/28/83 - added two predefined macro's __FILE && __LINE
.bg
Added the two macro's __LINE and __FILE which are respectively
interpreted as the current line number and the current file name.
They may be redefined if desired as this test takes place after
the user defined macro expansions.
.eg
28. 3/29/83 - embedded macro arguments
.bg
Arguments from #define macro's which are not individual tokens but which
are embedded in quoted or non-quoted strings are now being expanded.
.eg
29. 3/29/83 - white space in macro call [vlh] 4.1
.bg
Allows tabs and spaces between a macro call identifier and the left
parenthesis associated with it's argument list.
.eg
30. 4/29/83 - embedded macro arguments [vlh] 4.1
.bg
An underscore '_' is no longer seen as a legitimate symbol separator.
Macro's which are embedded in strings are now expanded properly.
.eg
31. 6/13/83 - split preprocessor from main driver [vlh] 4.2
.bg
For more flexibility...
.eg
32. 7/6/83 - #line [vlh] 4.2
.bg
A blank line was not being added to the file for each line which was being
redirected or for the #line macro, and so for each case the line number
would be off by two from the original file and error's reported would
have the wrong line number associated with them.
Reworked the way #line was being handled. Now works properly if the line
referenced has a macro on it. Does not lose lines.
.eg
33. 7/15/83 - '-C' option [vlh] 4.2
.bg
Added the '-C' option to the preprocessor. This caused a major rewrite of
the way include files and the #line option were handled. The preprocessor
now outputs lines of the form: # 45 "file.h" for each include file, plus
one at the top of each source file, and one after each return from an include
file. The '-C' flag causes comments to be left in the output.
.eg
34. 7/18/83 - arguments [vlh] 4.2
.bg
The arguments are now handled as "cpp -[args] source". The destination
file is no longer required, the results are always written on the '.i'
name of the source.
.eg
35. 7/20/83 - -I option [vlh] 4.2
.bg
The concluding slash is no longer required.
.eg

View File

@@ -0,0 +1,845 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#include "preproc.h"
#include <ctype.h>
#ifndef VAX11
char *stdincl = "/usr/include"; /*standard include directory*/
#else
/* 11 apr 83, for vax */
char *stdincl = "/usr/include/c68"; /*standard include directory*/
#endif
int clabel = LABSTART;
int nlabel = LABSTART+1;
char null[] = "";
int nincl;
char *incl[10];
char tmp[NUMLEN]; /* temporary spot for line number itoa conversion */
char ctype[];
char lit_file[MAXPSIZE];
struct builtin {
char *b_name;
int b_type;
} btab[] = {
"define", DEFINE,
"include", INCLUDE,
"undef", UNDEF,
"ifdef", IFDEF,
"ifndef", IFNDEF,
"else", ELSE,
"endif", ENDIF,
"if", IF,
"line", LINE,
0,
};
char *getinclude();
char cstack[CSTKSIZE];
char *cstkptr, inclname[TOKSIZE];
/*
* domacro - do macro processing
* Does the macro pre-processing on the input file and leaves the
* result on the output file.
*/
domacro(nd)
int nd; /* number of defines*/
{
register char *l;
register struct symbol *sp;
register int x;
filep = &filestack[0]; /* [vlh] 4.0 moved for error msgs */
lineno = 1; /* [vlh] 4.0 moved for error msgs */
if( fopen(source,&inbuf,0) < 0 ) { /* 3rd arg for versados */
error("can't open source file %s\n",source);
return(0);
}
if (!Eflag)
if( fcreat(dest,&outbuf,0) < 0 ) { /* 3rd arg for versados */
error("can't creat %s\n",dest);
return(0);
}
putid(source,1); /* identify as first line in source file */
for (sp= &symtab[0]; sp<= &symtab[HSIZE-1]; sp++) /*3.4*/
sp->s_def = null; /* clear out symbol table */
defp = defap = sbrk(DEFSIZE);
if (defp == (char *)-1) {
error("define table overflow");
cexit();
}
defmax = defcount = DEFSIZE;
defused = 0;
pbp = &pbbuf[0];
cstkptr = &cstack[0];
install("Newlabel",NEWLABEL);
install("Label",LABEL);
while( --nd >= 0 )
dinstall(defs[nd].ptr,defs[nd].value);
while( getline(source) ) {
l = line;
if( filep == &filestack[0] && pbp == &pbbuf[0] )
lineno++;
else if (filep != &filestack[0]) /*[vlh] include file*/
(filep-1)->lineno++;
while( *l )
doputc(*l++,&outbuf);
doputc(' ',&outbuf);
doputc('\n',&outbuf);
if (literal) {
if (filep != &filestack[0]) {
(filep-1)->lineno++;
putid((filep-1)->ifile,(filep-1)->lineno);
}
else {
lineno++;
putid(source,lineno);
}
literal = 0;
}
}
if( cstkptr != &cstack[0] )
error("unmatched conditional");
if( defused > defmax )
defmax = defused;
v6flush(&outbuf);
if (!Eflag)
close(outbuf.fd);
close(inbuf.fd);
return(1);
}
putid(fname,lnum) /* [vlh] 4.0 SOH line header */
char *fname;
int lnum;
{
register char *p;
if (asflag || pflag)
return;
if (literal) {
strcpy(lit_file,fname);
lit_num = lnum;
}
doputc('#',&outbuf);
doputc(' ',&outbuf);
itoa(lnum,tmp,NUMLEN-1);
for (p = tmp; *p==' '; )
p++;
for ( ; *p; p++)
doputc(*p,&outbuf);
doputc(' ',&outbuf);
doputc('"',&outbuf);
for (p = fname; *p; p++)
doputc(*p,&outbuf);
doputc('"',&outbuf);
doputc('\n',&outbuf);
}
install(name,def)
char *name;
int def;
{
register struct symbol *sp;
sp = getsp(name);
symcopy(name,sp->s_name);
sp->s_def = defp;
putd(def);
putd('\0');
}
dinstall(name,def) /* returns - none*/
char *name; /* macro name*/
char *def; /* pointer to definition*/
{
register struct symbol *sp;
sp = getsp(name);
symcopy(name,sp->s_name);
sp->s_def = defp;
putd(NOARGS);
if (def) /* [vlh] character strings... */
while(*def)
putd(*def++);
else
putd('1'); /* [vlh] default define value */
putd('\0');
}
/* kwlook - look up the macro built-in names*/
/* Searches thru the built-in table for the name.*/
kwlook(name) /* returns keyword index or 0*/
char *name; /* keyword name to lookup*/
{
register struct builtin *bp;
for( bp = &btab[0]; bp->b_name; bp++ )
if( strcmp(bp->b_name,name) == 0 )
return(bp->b_type);
return(0);
}
/*
* getline - get input line handling macro statements
* Checks for a preprocessor statement on the line and if there
* is one there, it processes it. Note that most of the work is
* in determining whether we need to skip the current line or not.
* This is all handled with the condition stack and the skip variable.
* The skip variable is non-zero if any condition on the condition
* stack is SKIP.
*/
getline(infile) /* returns 0 for EOF, 1 otherwise*/
char *infile; /* [vlh] for quoted include files */
{
char token[TOKSIZE];
register int type, i;
register char *p;
initl();
if( (type=gettok(token)) == EOF )
return(0);
if( type == POUND ) {
if( (type=getntok(token)) == NEWL )
return(1);
switch( kwlook(token) ) {
case IFDEF:
if( getntok(token) == ALPHA && lookup(token) )
push(NOSKIP);
else {
push(SKIP);
skip++;
}
break;
case IFNDEF:
if( getntok(token) == ALPHA && lookup(token) ) {
push(SKIP);
skip++;
}
else
push(NOSKIP);
break;
case ENDIF:
if( (i=pop()) == SKIP )
skip--;
else
if( i != NOSKIP )
error("invalid #endif");
break;
case ELSE:
if( (i=pop()) == SKIP ) {
skip--;
push(NOSKIP);
}
else
if( i == NOSKIP ) {
skip++;
push(SKIP);
}
else
error("invalid #else");
break;
case DEFINE:
if( !skip ) /*if in skip, don't do define*/
dodefine();
break;
case UNDEF:
if( !skip ) { /*if in skip, don't undef*/
if( (type=getntok(token)) == ALPHA )
undefine(token);
}
break;
case INCLUDE:
if( !skip ) { /*if in skip, don't do include*/
doinclude(infile);
if (filep != &filestack[0])
i = getline((filep-1)->ifile);
else
i = getline(infile);
return(i);
}
break;
case IF:
if( cexpr() ) /*evaluate constant expression*/
push(NOSKIP); /*non-zero, so don't skip*/
else {
push(SKIP);
skip++;
}
break;
case LINE: /* [vlh] 4.0 */
doline();
return(getline(infile));
break;
default:
error("invalid preprocessor command");
break;
}
eatup();
}
else
if( type != NEWL ) {
if( skip )
eatup();
else {
for( ; type!=NEWL && type!=EOF ; type=gettok(token) )
if(type == ALPHA && (p=lookup(token)))
expand((struct symbol *)p);
else if (!special(token,infile)) /* [vlh] 4.1 */
for (p=token; *p; )
putl((int)(*p++));
}
}
putl((int)('\0'));
return(1);
}
/* special - check for predefined macros, if they exist expand them */
/* __FILE - current file name, __LINE - current line number */
special(token,infile) /* [vlh] 4.1 */
char *token, *infile;
{
register char *p;
int xline;
char buf[8];
if (strcmp(token,"__FILE") == 0) {
putl((int)('"'));
for (p = infile; *p; )
putl((int)(*p++));
putl((int)('"'));
}
else
if (strcmp(token,"__LINE") == 0) {
xline = (literal) ? lit_num : (filep == &filestack[0]) ? lineno
: (filep-1)->lineno;
itoa(xline,buf,7);
buf[7] = 0;
for (p = &buf[0]; *p == ' '; )
p++;
while (*p)
putl((int)(*p++));
}
else
return(0);
return(1);
}
/* eatup - eat up the rest of the input line until a newline or EOF*/
/* Does gettok calls.*/
eatup() /* returns - none*/
{
register int type;
char etoken[TOKSIZE];
while( (type=gettok(etoken)) != NEWL && type != EOF )
;
}
/* putl - put a character to the current output line*/
/* Checks for line overflow.*/
putl(c) /* returns - none*/
int c; /* character to put on line*/
{
if( linep < &line[LINESIZE] )
*linep++ = c;
else if ( !loverflow ) {
loverflow++;
error("line overflow");
}
}
/* initl - initialize current line*/
/* Sets the line pointer and the line overflow flag.*/
initl() /* returns - none*/
{
*(linep= &line[0]) = '\0';
loverflow = 0;
}
/* putd - put a character to the define buffer*/
/* Does dynamic allocation for define buffer*/
putd(c) /* returns - none*/
int c; /* character to put in buffer*/
{
if( !defcount ) {
if( sbrk(DEFSIZE) == (char *)-1 ) {
error("define table overflow");
cexit();
}
defcount = DEFSIZE;
}
defused++;
defcount--;
*defp++ = c;
}
/* undefine - does undef command*/
/* Sets the symbols definition to the null pointer*/
undefine(name) /* returns - none*/
char *name; /* pointer to name to undef*/
{
register struct symbol *sp;
sp = getsp(name);
if( sp->s_def )
sp->s_def = null;
}
/* dodefine - do #define processing*/
/* Checks the define name, collects formal arguements and saves*/
/* macro definition, substituting for formal arguments as it goes.*/
dodefine() /* returns - none*/
{
char token[TOKSIZE], *args[MAXARGS], argbuf[ARGBSIZE];
register char *abp, *p;
register int type, nargs, i;
register struct symbol *sp;
if( (type=getntok(token)) != ALPHA ) {
error("bad define name: %s",token);
return;
}
sp = getsp(token);
symcopy(token,sp->s_name);
sp->s_def = defp;
nargs = 0;
abp = argbuf;
if( (type=gettok(token)) == LPAREN ) {
for( ; (type=getfarg(token)) != RPAREN; nargs++ ) {
if( nargs >= MAXARGS ) {
error("too many arguments");
break;
}
args[nargs] = abp;
for( p = token; *abp++ = *p++; ) {
if( abp >= &argbuf[ARGBSIZE] ) {
error("argument buffer overflow");
break;
}
}
}
putd(nargs);
}
else {
pbtok(token);
putd(NOARGS);
}
type = getntok(token); /*get next non-white token*/
for( ; type != NEWL && type != EOF; type = gettok(token) ) {
if (type==ALPHA || type==SQUOTE || type==DQUOTE) { /* [vlh] 4.1 */
trymatch(token,type,nargs,args); /* [vlh] 4.1 */
continue;
}
else if( type == BSLASH ) {
if( (i=ngetch()) == '\n' ) { /*multi-line macro?*/
if( filep == &filestack[0] && pbp == &pbbuf[0] ) {
lineno++;
doputc('\n',&outbuf);
}
}
putd(i);
continue;
}
for( p = token; *p ; )
putd(*p++);
}
pbtok(token);
putd('\0');
}
/* trymatch - check for arguments */
trymatch(token,type,nargs,args) /* [vlh] 4.1 */
char *token;
int type, nargs;
char *args[];
{
register char *p;
register int i, len;
p = token;
if (type != ALPHA)
putd(*p++);
while (*p != 0) {
for(i = 0; i < nargs; i++)
if ((len = pattern(args[i],p)) != 0)
break;
if (i < nargs) { /* sub ARG marker for formal arg */
putd(i+1);
putd(ARG);
p += len;
}
else
do {
putd(*p++);
} while (isalnum(*p) || *p == '_');
while (!(isalnum(*p)) && *p != '_' && *p) /* get to next possible */
putd(*p++);
}
}
/* pattern - if the pattern occurs in the token starting at the first */
/* position in the string, pattern returns the length of the pattern */
/* else pattern returns a zero. */
pattern(pat,token) /* [vlh] 4.1 */
char *pat, *token;
{
register int len;
len = strlen(pat);
if (len > strlen(token)) /* couldn't possibly work */
return(0);
if (isalnum(token[len]) || token[len]=='_')
return(0); /* not deliminated by non-alphanumeric */
for (len = 0; *pat; ) {
if( *pat++ != *token++ )
return(0);
len++;
}
return( len );
}
/* expand - expands the macro definition*/
/* Checks for define recursion and #define x x problems, collects*/
/* the actual arguments using getaarg, and then expands the macro*/
/* by pushing it onto the push back buffer, substituting arguments*/
/* as it goes.*/
expand(sp) /* returns - none*/
struct symbol *sp; /* pointer to macro to expand*/
{
char argbuf[ARGBSIZE], *args[MAXARGS], token[TOKSIZE];
register char *p, *abp, *mdef;
register int i, j, nargs, type;
if( pbflag++ > 100 ) {
error("define recursion");
return;
}
if( strcmp(sp->s_name,mdef=sp->s_def) == 0 ) { /*handle #define x x*/
while( *mdef )
putl((int)(*mdef++));
return;
}
nargs = 0;
if( *mdef == NOARGS ) /*suppress grabbing of args*/
;
else if( getntok(token) != LPAREN ) /* [vlh] 4.1 ignore white space */
pbtok(token);
else {
abp = &argbuf[0];
while( (type=getaarg(token)) != EOF ) {
if( nargs >= MAXARGS ) {
error("too many arguments");
return;
}
args[nargs++] = abp;
for( p = token; *abp++ = *p++; ) {
if( abp >= &argbuf[ARGBSIZE] ) {
error("argument buffer overflow");
return;
}
}
if( type == RPAREN )
break;
}
}
if( *mdef == NEWLABEL ) {
clabel = nlabel;
if( !nargs )
nlabel++;
else
nlabel += atoi(args[0]);
}
else if( *mdef == LABEL ) {
if( !nargs )
i = clabel;
else
i = clabel + atoi(args[0]);
pbnum(i);
pbtok("_L");
}
else {
mdef++; /*skip no. of args*/
for( p = mdef + strlen(mdef) - 1; p >= mdef; p-- ) {
if( *p == ARG ) {
if( (j= *--p) <= nargs )
pbtok(args[j-1]);
}
else
putback(*p);
}
}
}
/* getfarg - get macro formal parameters*/
/* Skips blanks and handles "," and ")".*/
getfarg(token) /* returns token type*/
char *token; /* token returned*/
{
register int type;
if( (type=getntok(token)) == RPAREN || type == ALPHA )
return(type);
if( type != COMMA || (type=getntok(token)) != ALPHA )
error("bad argument:%s",token);
return(type);
}
/* getntok - get next token, suppressing white space*/
/* Merely gettok's until non-white space is there*/
getntok(token) /* returns token type*/
char *token; /* token returned*/
{
register int type;
while( (type=gettok(token)) == WHITE )
;
return(type);
}
/* getaarg - get macro actual argument*/
/* This handles the collecting of the macro's call arguments.*/
/* Note that you may have parenthesis as part of the macro argument,*/
/* hence you need to keep track of them.*/
getaarg(argp) /* returns token type*/
char *argp; /* argument returned*/
{
int type, plevel, i;
register char *p, *ap;
char token[TOKSIZE];
ap = argp;
*ap = '\0';
plevel = 0;
i = TOKSIZE;
while( ((type=gettok(token)) != COMMA && type != RPAREN) || plevel ) {
for( p = token; *ap = *p++; ap++ )
if( --i <= 0 ) {
error("macro argument too long");
return(EOF);
}
if( type == LPAREN )
plevel++;
else if( type == RPAREN )
plevel--;
else if( type == EOF ) {
error("unexpected EOF");
cexit();
}
}
if( ap == argp )
type = EOF;
return(type);
}
/* push - push a #ifdef condition value on condition stack*/
/* Checks for stack overflow.*/
push(val) /* returns - none*/
int val; /* value to push*/
{
if( cstkptr >= &cstack[CSTKSIZE] ) {
error("condition stack overflow");
cexit();
}
*cstkptr++ = val;
}
/* pop - pop the #ifdef, etc. condition stack*/
/* Checks for stack undeflow.*/
pop() /* returns - top of condition stack*/
{
if( cstkptr <= &cstack[0] )
return(-1);
return( *--cstkptr );
}
/* doinclude - handle #include command*/
/* Checks for file name or library file name and pushes file on*/
/* include file stack.*/
doinclude(infile) /* returns - none*/
char *infile; /* [vlh] for quoted include files */
{
register int type, fd, i;
char token[TOKSIZE], fname[TOKSIZE];
register char *p, *q, c, *ptr1, *ptr2;
p = fname;
if( (type=getntok(token)) == SQUOTE || type == DQUOTE ) {
for( c = token[0], q = &token[1]; *q != c; )
*p++ = *q++;
*p = '\0';
p = getinclude(fname,infile);
}
else if( type != LESS ) {
error("bad include file");
return;
}
else {
while( (type=gettok(token))!=GREAT && type!=NEWL && type!=EOF )
for( q = token; *p = *q++; p++ )
;
if( type != GREAT ) {
error("bad include file name");
pbtok(token);
return;
}
p = getinclude(fname,(char *)0L);
}
eatup(); /*need here...*/
if( filep >= &filestack[FSTACK] )
error("includes nested too deeply");
else {
fd = inbuf.fd;
#ifdef NONEST
filep->tcc = inbuf.cc;
filep->tcp = inbuf.cp;
ptr1 = &filep->tbuf[0];
ptr2 = &inbuf.cbuf[0];
for(i=0; i<BSIZE; i++)
*ptr1++ = *ptr2++;
#else
seek(fd,-inbuf.cc,1); /*back up file ptr*/
#endif
inbuf.cc = 0;
if( fopen(p,&inbuf,0) < 0 ) { /* 3rd arg for versados */
if (type != SQUOTE && type != DQUOTE)
error("can't open include file %s",p);
else
error("can't open include file %s",fname);
#ifdef NONEST
inbuf.cc = filep->tcc;
#endif
}
else {
filep->ifd = fd;
filep->lineno = 1; /* [vlh] */
putid(p,1); /* id for include file */
doifile(p);
filep++;
}
}
}
doifile(p) /* [vlh] */
char *p;
{
register char *iptr;
register int ndx;
for( iptr = filep->ifile; *p; )
*iptr++ = *p++;
*iptr = 0;
}
/* getinclude - get include file full pathname */
char *
getinclude(fname,parent) /* [vlh] */
char *fname;
char *parent; /* search parent-file home directory ? */
{
register char *q, *t;
register int i, fd, ndx;
for (i=0; i<nincl; i++) {
for(t=inclname, q=incl[i]; *t++ = *q++; )
;
*(t-1) = FILESEP;
for(q=fname; *t++ = *q++; ) ;
*t = 0;
if ((fd = open(inclname,0)) >= 0) {
close(fd);
return(&inclname[0]);
}
}
if (parent) { /* include filename surrounded by quotes */
q = (filep == &filestack[0]) ? parent : (filep-1)->ifile;
t = &inclname[0];
while ((ndx = index(q,FILESEP)) >= 0) {
ndx++;
while (ndx--) *t++ = *q++;
}
for (q=fname; *t++ = *q++; )
;
*t = 0;
if ((fd = open(inclname,0)) >= 0) { /* found it */
close(fd);
return(&inclname[0]);
}
}
for(t=inclname, q=stdincl; *t++ = *q++; )
;
*(t-1) = FILESEP;
for(q=fname; *t++ = *q++; ) ;
*t = 0;
return(&inclname[0]);
}
#define SKIPWHITE(ch) do { ch = ngetch(); } while (ctype[ch] == WHITE)
doline() /* [vlh] 4.0 : returns - none */
{
register char *ptr;
char token[TOKSIZE];
register int ch, lnum, type;
/* get line number associated with #LINE */
while ((type = gettok(token)) == WHITE); /* skip white space */
if (type != DIGIT) {
error("invalid #line args");
return;
}
lnum = atoi(token);
literal = 1;
SKIPWHITE(ch);
if (ctype[ch] != NEWL && ctype[ch] != EOF) { /* associated filename */
ptr = &token[0];
do {
*ptr++ = ch;
ch = ngetch();
} while (ctype[ch]!=NEWL && ctype[ch]!=EOF && ctype[ch]!=WHITE);
*ptr = 0;
putid(token,lnum);
}
else /* source or header file */
if (filep == &filestack[0])
putid(source,lnum); /* [vlh] 4.2.c */
else
putid((filep-1)->ifile,lnum); /* [vlh] 4.2.c */
if (ch != NEWL)
for( ; ctype[ch]!=NEWL && ctype[ch]!=EOF; )
ch = ngetch();
}
pbnum(num) /* returns - none*/
int num;
{
register int digit;
do {
digit = num % 10;
num /= 10;
putback(digit+'0');
} while( num > 0 );
}

View File

@@ -0,0 +1,280 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
char *version = "@(#)cpp68 preprocessor 4.2 - Sep 6, 1983";
#include "preproc.h"
#define NARGS 64
#define FLAGS "[-C] [-P] [-E] [-D] [-I] [-6] [-7] [-3]"
#define USAGE "usage: %s %s source [dest]\n"
#ifndef VAX11
char *v6incl = "/usr/include/v6"; /* [vlh] 3.4 */
char *v7incl = "/usr/include/v7"; /* [vlh] 3.4 */
char *s3incl = "/usr/include/sys3"; /* [vlh] 3.4 */
char *s5incl = "/usr/include/sys5"; /* [vlh] 3.4 */
#else
char *v6incl = "/usr/include/c68/v6"; /* [vlh] 3.4 */
char *v7incl = "/usr/include/c68/v7"; /* [vlh] 3.4 */
char *s3incl = "/usr/include/c68/sys3"; /* [vlh] 3.4 */
char *s5incl = "/usr/include/c68/sys5"; /* [vlh] 3.4 */
#endif
char *incl[NINCL];
int ndefs, nincl;
int status = 0;
extern int errno;
/*
* main - main routine for c68 Compiler system
* Handles the C68 arguments. For each C file given, the macro
* pre-processor is called, then the parser, code generator and
* assember are fexec'd. The loader arguments are collected and
* the loader is fexec'd.
*/
main(argc,argv)
int argc;
register char **argv;
{
register char *arg, *calledby;
register int c, i, j, x;
calledby = *argv++;
if (argc < 2) { /* cpp source */
printf(USAGE,calledby,FLAGS);
exit(-1);
}
for( ; --argc > 0 && **argv == '-'; ) { /*process arguments*/
*(arg = *argv++);
arg++;
for( i = 0; c = *arg++; ) {
switch( c ) {
case 'D':
defs[ndefs].ptr = arg;
if ((x=index(arg,'=')) != -1) {
defs[ndefs++].value = (arg+x+1);
arg[x] = 0; /*get rid of value*/
}
else
defs[ndefs++].value = 0;
i++;
break;
case 'I':
incl[nincl++] = arg;
i++;
break;
case 'C': /* [vlh] 4.2 Leave comments in... */
Cflag++;
case 'E': /* [vlh] 4.0 Preprocessor to stdout */
Eflag++;
continue;
case 'P': /* preprocessor pass only */
pflag++;
continue;
case '6': /* [vlh] 3.4 v6 compatibility */
incl[nincl++] = v6incl;
continue;
case '7': /* [vlh] 3.4 v7 compatibility */
incl[nincl++] = v7incl;
continue;
case '3': /* [vlh] 3.4 s3 compatibility */
incl[nincl++] = s3incl;
continue;
case '5': /* [vlh] 3.4 s5 compatiblity */
incl[nincl++] = s5incl;
continue;
default:
printf(USAGE,calledby,FLAGS);
exit(-1);
} /* end of case statement */
if (i)
break;
} /* end of for statement */
} /* end of for statement */
if (argc > 2) { /* source [dest] */
printf(USAGE,calledby,FLAGS);
exit(-1);
}
source = *argv++;
if ( !Eflag )
if (argc==2) /* destination file specified */
strcpy(dest,*argv);
else
make_intermediate();
asflag = (source[strlen(source)-1] == 's');
domacro(ndefs);
cexit();
}
/* cexit - exit from C compiler driver*/
/* This deletes any existing temps and exits with the error status.*/
cexit() /* returns - none*/
{
exit(status);
}
/**
* itoa - integer to ASCII conversion
* Converts integer to ASCII string, handles '-'.
**/
itoa(n,s,w) /* returns - none*/
int n; /* number to convert*/
char *s; /* resulting string*/
int w; /* minimum width of string*/
{
register char *tp;
register int sign, i;
char temp[6];
if( (sign=n) < 0 )
n = -n;
i = 0;
tp = &temp[0];
do {
i++;
*tp++ = n % 10 + '0';
} while( (n /= 10) > 0 );
if( sign < 0 ) {
i++;
*tp++ = '-';
}
while( --w >= i ) /*pad on left with blanks*/
*s++ = ' ';
while( --i >= 0 ) /*move chars reversed*/
*s++ = *--tp;
*s = '\0';
}
/* index - find the index of a character in a string*/
/* This is identical to Software Tools index.*/
index(str,chr) /* returns index of c in str or -1*/
char *str; /* pointer to string to search*/
char chr; /* character to search for*/
{
register char *s;
register int i;
for( s = str, i = 0; *s != '\0'; i++ )
if( *s++ == chr )
return(i);
return(-1);
}
atoi(as)
char *as;
{
register int n, sign;
register char *s;
s = as;
while( *s==' ' || *s=='\n' || *s == '\t')
s++;
sign = 1;
if( *s == '+' || *s == '-' )
sign = (*s++=='+') ? 1 : -1;
for( n = 0; *s >= '0' && *s <= '9'; s++ )
n = (n * 10) + (*s - '0');
return( sign * n );
}
make_intermediate() /* returns pointer to string*/
{ /* if source t.c dest <= t.i */
register char *d, *s;
register int ndx;
s = source;
while ((ndx = index(s,'/')) != -1)
s += ndx+1; /* [vlh] */
for( d = dest; *d++ = *s++; ) ;
*(d-2) = 'i'; /* overwrite termination character */
}
/* cputc - put a character to a file descriptor (used by error) */
cputc(c, fn)
char c;
int fn;
{
#ifdef VERSADOS
versaputchar(c);
#else
if (fn == STDERR)
write(STDERR, &c, 1);
else
putchar(c);
#endif
}
v6flush(v6buf)
struct iob *v6buf;
{
register i;
i = BSIZE - v6buf->cc;
v6buf->cc = BSIZE;
v6buf->cp = &(v6buf->cbuf[0]);
if(write(v6buf->fd,v6buf->cp,i) != i)
return(-1);
return(0);
}
#ifdef VERSADOS
#define BSIZE 512
struct iob versfout { 1, BSIZE, &versfout.cbuf[0]};
versaputchar(c)
char c;
{
if (c == '\n') { /* end of line */
if (versaflush()) /* write one line */
return(-1);
return(c);
}
/* buffered output */
if (versfout.cc <= 0) {
versfout.cp = &(versfout.cbuf[0]);
if (write(versfout.fd,versfout.cp,BSIZE) != BSIZE)
return(-1);
versfout.cc = BSIZE;
}
*(versfout.cp)++ = c;
versfout.cc--;
return(c);
}
versaflush()
{
register short size, fildes;
if ((size = (BSIZE - versfout.cc)) == 0)
return(0);
versfout.cc = BSIZE;
versfout.cp = &(versfout.cbuf[0]);
fildes = (versfout.fd <= STDERR) ? 6 : versfout.fd;
if (write(fildes,versfout.cp,size) < 0)
return(-1);
return(0);
}
#endif

View File

@@ -0,0 +1,61 @@
CC = cc
C68 = nc68
VAXOBJS = vaxobj/cexpr.o \
vaxobj/lex.o \
vaxobj/macro.o \
vaxobj/main.o
C68OBJS = 68obj/cexpr.o \
68obj/lex.o \
68obj/macro.o \
68obj/main.o
CFLAGS = -O -DVAX11
C68FLAGS = -L -r -DMC68000 -t0 -t1
LIB = -lV6
C68LIB = -l6
vax: ${VAXOBJS}
mkver -e "Preprocessor -"
${CC} ${CFLAGS} -n version.c ${VAXOBJS} -o cpp68.vax ${LIB}
cpp: ${C68OBJS}
mkver -e "Preprocessor -"
${C68} ${C68FLAGS} version.c ${C68OBJS} -o cpp68.68 ${C68LIB}
setstack cpp68.68 8000 8000
2k: ${C68OBJS}
mkver -e "Preprocessor -"
${C68} ${C68FLAGS} -n2 version.c ${C68OBJS} -o cpp68.2k ${C68LIB}
setstack cpp68.2k 8000 8000
4k: ${C68OBJS}
mkver -e "Preprocessor -"
${C68} ${C68FLAGS} -n version.c ${C68OBJS} -o cpp68.4k ${C68LIB}
setstack cpp68.4k 8000 8000
all: vax 4k
vaxobj/cexpr.o: cexpr.c
${CC} ${CFLAGS} -c cexpr.c;mv -f cexpr.o vaxobj/cexpr.o
vaxobj/lex.o: lex.c
${CC} ${CFLAGS} -c lex.c;mv -f lex.o vaxobj/lex.o
vaxobj/macro.o: macro.c
${CC} ${CFLAGS} -c macro.c;mv -f macro.o vaxobj/macro.o
vaxobj/main.o: main.c
${CC} ${CFLAGS} -c main.c;mv -f main.o vaxobj/main.o
68obj/cexpr.o: cexpr.c
${C68} ${C68FLAGS} -c cexpr.c;mv -f cexpr.o 68obj/cexpr.o
68obj/lex.o: lex.c
${C68} ${C68FLAGS} -c lex.c;mv -f lex.o 68obj/lex.o
68obj/macro.o: macro.c
${C68} ${C68FLAGS} -c macro.c;mv -f macro.o 68obj/macro.o
68obj/main.o: main.c
${C68} ${C68FLAGS} -c main.c;mv -f main.o 68obj/main.o

View File

@@ -0,0 +1,14 @@
CC = c68
OBJS = cexpr.o lex.o macro.o main.o util.o
CFLAGS = -L
LIB = -l6 -l7
st: ${OBJS}
@mkver -e "preprocessor - "
${CC} ${CFLAGS} -n -r ${OBJS} version.c ${LIB} -o c68.st
@setstack c68.st 8192 8192 ;size c68.st
c68: ${OBJS}
@mkver -e "preprocessor - "
${CC} ${CFLAGS} -r ${OBJS} version.c ${LIB} -o c68.68
@setstack c68.68 8192 8192 ;size c68.68

View File

@@ -0,0 +1,182 @@
/*
Copyright 1982
Alcyon Corporation
8716 Production Ave.
San Diego, Ca. 92121
*/
#ifdef DRI
# include <stdio.h>
# include <klib.h>
#endif
#ifdef VERSADOS
# define NONEST 1
# define NOFORKS 1
#endif
#ifdef VMS
# define NONEST 1
#endif
/*cexpr operators*/
#define EOF 0
#define SUB 1
#define ADD 2
#define NOT 3
#define NEG 4
#define LPAREN 5
#define RPAREN 6
#define QMARK 7
#define COLON 8
#define OR 9
#define AND 10
#define XOR 11
#define EQUAL 12
#define NEQUAL 13
#define LESS 14
#define LSEQUAL 15
#define GREAT 16
#define GREQUAL 17
#define LSHIFT 18
#define RSHIFT 19
#define MULT 20
#define DIV 21
#define MOD 22
#define COMPL 23
#define CONST 24
#define LASTOP COMPL /*up to here used by cexpr*/
#define SQUOTE 25
#define DQUOTE 26
#define ANYC 27
#define BADC 28
#define COMMA 29
#define NEWL 30
#define POUND 31
#define ALPHA 32
#define DIGIT 33
#define BSLASH 34
#define WHITE 35
/* Types of preprocessor macros */
#define DEFINE 1
#define UNDEF 2
#define INCLUDE 3
#define IFDEF 4
#define IFNDEF 5
#define ELSE 6
#define ENDIF 7
#define IF 8
#define LINE 9
/* Magic Numbers used in Macros */
#define ARG -1
#define NEWLABEL -2
#define LABEL -3
#define NOARGS -4
/* Skip state, using #ifdef... */
#define SKIP 0
#define NOSKIP 1
/* General Defines */
#define SOH '\01'
#define SSIZE 8
#define BSIZE 512
#define LINESIZE 512
#define MAXARGS 60
#define ARGBSIZE 1000
#define TOKSIZE 300 /*BUG 4/20/82 was 128*/
#define DEFSIZE 1024
#define PBSIZE 1000
#define STDERR 2 /* [vlh] 4.2, write errors to.... */
#define TRUE 1
#define FALSE 0
#define NDEFS 20
#define CSTKSIZE 20
#define FILESEP '/'
#define NINCL 10
#define LABSTART 1000
#define NUMLEN 6
#ifndef VERSADOS
# define HSIZE 1024
#else
# define HSIZE 2048
#endif
/* Symbol Table Entry structure */
struct symbol {
char s_name[SSIZE];
char *s_def;
} symtab[HSIZE];
/*buffered I/O structure*/
struct iob {
int fd;
int cc;
char *cp;
char cbuf[BSIZE];
} inbuf, outbuf;
/* command line define structure */
struct defstruc {
char *ptr;
char *value;
} defs[NDEFS];
#define FSTACK 10
#define MAXPSIZE 128
struct stackstruc { /* [vlh] */
int ifd;
char ifile[MAXPSIZE];
int lineno;
#ifdef NONEST
char tbuf[BSIZE]; /* hold buffer in include... */
int tcc; /* hold count into buffer... */
char *tcp; /* pointer into buffer... */
#endif
} filestack[FSTACK], *filep; /* stack of incl files, ptr to... */
/* Variables used by #line macros */
int literal; /*[vlh] 4.0 using #line */
int lit_num; /* for error messages */
char lit_file[]; /* for error messages */
/* Flag Variable Declarations */
int pflag;
int Cflag;
int Eflag;
int asflag;
char *source; /* preprocessor source file */
char dest[MAXPSIZE]; /* preprocessor destination file */
/* Miscellaneous Variable Declarations */
int skip; /*skipping current line*/
char *defap; /*pointer to available define area*/
char *defp; /*pointer to next avail define byte*/
int defcount; /*bytes left in define area*/
int defused; /*number of bytes used in define area*/
int defmax; /*maximum define area used*/
/*line to output after macro substitution*/
char line[LINESIZE+2]; /*line buffer*/
char *linep; /*current line pointer*/
int loverflow; /*line overflow flag*/
int lineno;
/*push back buffer*/
char pbbuf[PBSIZE]; /*push back buffer*/
char *pbp; /*push back pointer*/
int pbflag; /*checks for recursive definition*/
/* Function declarations */
char *lookup();
char *setend();
char *makecopy();
char *maketemp();
char *sbrk();
struct symbol *getsp();

View File

@@ -0,0 +1,8 @@
This is a list of the files in this directory:
cexpr.c: Constant expressions in #if statements
lex.c: Lexical analysis
macro.c: Macro preprocessor statements processing
main.c: Main routine and utilities
log: Log of bugs and their fixes
ERRORS: List of error messages preprocessor produces
a.out: Last Absolute version loaded, should be same as /bin/c68

View File

@@ -0,0 +1 @@
char *compiled = "@(#) Preprocessor - Tue Sep 6 14:36 1983";