home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
messroms.de
/
2007-01-13_www.messroms.de.zip
/
VZ200
/
TOOLS
/
ZCCSRC.ZIP
/
scc
/
preproc.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-03-06
|
6KB
|
442 lines
/* File preproc.c: 2.3 (84/11/27,11:47:40) */
/*% cc -O -c %
*
*/
#include <stdio.h>
#include <string.h>
#include "defs.h"
#include "data.h"
#include "proto.h"
/*
* open an include file
*/
void doinclude(void)
{
FILE *inp2;
blanks();
if (NULL!=(inp2 = fixiname()))
if (inclsp < INCLSIZ)
{
inclstk[inclsp++] = input2;
input2 = inp2;
}
else
{
fclose(inp2);
error("too many nested includes");
}
else
{
error("Could not open include file");
}
kill();
}
/*
* fixiname - remove "brackets" around include file name
*/
FILE *fixiname(void)
{
char c1, c2, *p, *ibp;
char buf[20];
FILE *fp;
char buf2[100];
ibp = &buf[0];
if ((c1 = gch()) != '"' && c1 != '<')
return (NULL);
for (p = line + lptr; *p;)
*ibp++ = *p++;
c2 = *(--p);
if (c1 == '"' ? (c2 != '"') : (c2 != '>'))
{
error("incorrect delimiter");
return (NULL);
}
*(--ibp) = 0;
fp = NULL;
if (c1 == '<' || !(fp = fopen(buf, "r")))
{
strcpy(buf2, DEFLIB);
strcat(buf2, buf);
fp = fopen(buf2, "r");
}
return (fp);
}
/*
* "asm" pseudo-statement
*
* enters mode where assembly language statements are passed
* intact through parser
*
*/
void doasm(void)
{
cmode = 0;
for (;;)
{
xinline();
if (match("#endasm"))
break;
if (feof(input))
break;
outstr(line);
nl();
}
kill();
cmode = 1;
}
/*
* This one is called from the pseudo function asm("code")
*/
void asmfunc(void)
{
char c;
needbrack("(");
if (!match(quote))
{
error("Missing opening \" in asm call");
return;
}
do
{
while (ch() != '"')
{
if (ch() == 0)
break;
c = gch();
outbyte(c == '\\' ? spechar() : c);
}
gch();
} while (match(quote));
needbrack(")");
ns();
}
void dodefine(void)
{
addmac();
}
void doundef(void)
{
int mp;
char sname[NAMESIZE];
if (!symname(sname))
{
illname();
kill();
return;
}
if (0!=(mp = findmac(sname)))
delmac(mp);
kill();
}
void preprocess(void)
{
if (ifline())
return;
while (cpp())
;
}
void doifdef(int ifdef)
{
char sname[NAMESIZE];
int k;
blanks();
++iflevel;
if (skiplevel)
return;
k = symname(sname) && findmac(sname);
if (k != ifdef)
skiplevel = iflevel;
}
int ifline(void)
{
for (;;)
{
xinline();
if (feof(input))
return (1);
if (match("#ifdef"))
{
doifdef(YES);
continue;
}
else
if (match("#ifndef"))
{
doifdef(NO);
continue;
}
else
if (match("#else"))
{
if (iflevel)
{
if (skiplevel == iflevel)
skiplevel = 0;
else if (skiplevel == 0)
skiplevel = iflevel;
}
else
noiferr();
continue;
}
else
if (match("#endif"))
{
if (iflevel)
{
if (skiplevel == iflevel)
skiplevel = 0;
--iflevel;
}
else
noiferr();
continue;
}
if (!skiplevel)
return (0);
}
}
void noiferr(void)
{
error("no matching #if...");
}
int cpp(void)
{
int k;
char c, sname[NAMESIZE];
int tog;
int cpped; /* non-zero if something expanded */
cpped = 0;
/* don't expand lines with preprocessor commands in them */
if (!cmode || line[0] == '#')
return (0);
mptr = lptr = 0;
while (ch())
{
if (ch() == ' ' || ch() == 9)
{
keepch(' ');
while (ch() == ' ' || ch() == 9)
gch();
}
else
if (ch() == '"')
{
keepch(ch());
gch();
while (ch() != '"')
{
if (ch() == 0)
{
error("missing quote");
break;
}
if (ch() == '\\')
keepch(gch());
keepch(gch());
}
gch();
keepch('"');
}
else
if (ch() == 39)
{
keepch(39);
gch();
while (ch() != 39)
{
if (ch() == 0)
{
error("missing apostrophe");
break;
}
if (ch() == '\\')
keepch(gch());
keepch(gch());
}
gch();
keepch(39);
}
else
if (ch() == '/' && nch() == '*')
{
inchar();
inchar();
while ( !((c = ch()) == '*' && nch() == '/') )
{
if (c == '$')
{
inchar();
tog = TRUE;
if (ch() == '-')
{
tog = FALSE;
inchar();
}
if (alpha(c = ch()))
{
inchar();
toggle(c, tog);
}
}
else
{
if (ch() == 0)
xinline();
else
inchar();
if (feof(input))
break;
}
}
inchar();
inchar();
}
else
if (an(ch()))
{
k = 0;
while (an(ch()))
{
if (k < NAMEMAX)
sname[k++] = ch();
gch();
}
sname[k] = 0;
if (0!=(k = findmac(sname)))
{
cpped = 1;
while (0!=(c = macq[k++]))
keepch(c);
}
else
{
k = 0;
while (0!=(c = sname[k++]))
keepch(c);
}
}
else
keepch(gch());
}
keepch(0);
if (mptr >= MPMAX)
error("line too long");
lptr = mptr = 0;
while (0!=(line[lptr++] = mline[mptr++]))
;
lptr = 0;
return (cpped);
}
char keepch(char c)
{
mline[mptr] = c;
if (mptr < MPMAX)
mptr++;
return (c);
}
void defmac(char *s)
{
kill();
strcpy(line, s);
addmac();
}
void addmac(void)
{
char sname[NAMESIZE];
int k;
int mp;
if (!symname(sname))
{
illname();
kill();
return;
}
if (0!=(mp = findmac(sname)))
{
error("Duplicate define");
delmac(mp);
}
k = 0;
while (putmac(sname[k++]))
;
while (ch() == ' ' || ch() == 9)
gch();
while (putmac(gch()))
;
if (macptr >= MACMAX)
error("macro table full");
}
void delmac(int mp)
{
--mp;
--mp; /* step over previous null */
while (mp >= 0 && macq[mp])
macq[mp--] = '%';
}
char putmac(char c)
{
macq[macptr] = c;
if (macptr < MACMAX)
macptr++;
return (c);
}
int findmac(char *sname)
{
int k;
k = 0;
while (k < macptr)
{
if (astreq(sname, macq + k, NAMEMAX))
{
while (macq[k++]) ;
return (k);
}
while (macq[k++]) ;
while (macq[k++]) ;
}
return NULL;
}
void toggle(char name, int onoff)
{
switch (name)
{
case 'C':
ctext = onoff;
break;
}
}