blob: a11d6c3e950236742315aacd19d0b8d0bb59cbaf [file] [log] [blame]
#include "c.h"
static char rcsid[] = "$Id: input.c 355 2007-02-18 22:08:49Z drh $";
static void pragma(void);
static void resynch(void);
static int bsize;
static unsigned char buffer[MAXLINE+1 + BUFSIZE+1];
unsigned char *cp; /* current input character */
char *file; /* current input file name */
char *firstfile; /* first input file */
unsigned char *limit; /* points to last character + 1 */
char *line; /* current line */
int lineno; /* line number of current line */
void nextline(void) {
do {
if (cp >= limit) {
fillbuf();
if (cp >= limit)
cp = limit;
if (cp == limit)
return;
} else {
lineno++;
for (line = (char *)cp; *cp==' ' || *cp=='\t'; cp++)
;
if (*cp == '#') {
resynch();
nextline();
}
}
} while (*cp == '\n' && cp == limit);
}
void fillbuf(void) {
if (bsize == 0)
return;
if (cp >= limit)
cp = &buffer[MAXLINE+1];
else
{
int n = limit - cp;
unsigned char *s = &buffer[MAXLINE+1] - n;
assert(s >= buffer);
line = (char *)s - ((char *)cp - line);
while (cp < limit)
*s++ = *cp++;
cp = &buffer[MAXLINE+1] - n;
}
if (feof(stdin))
bsize = 0;
else
bsize = fread(&buffer[MAXLINE+1], 1, BUFSIZE, stdin);
if (bsize < 0) {
error("read error\n");
exit(EXIT_FAILURE);
}
limit = &buffer[MAXLINE+1+bsize];
*limit = '\n';
}
void input_init(int argc, char *argv[]) {
static int inited;
if (inited)
return;
inited = 1;
main_init(argc, argv);
limit = cp = &buffer[MAXLINE+1];
bsize = -1;
lineno = 0;
file = NULL;
fillbuf();
if (cp >= limit)
cp = limit;
nextline();
}
/* ident - handle #ident "string" */
static void ident(void) {
while (*cp != '\n' && *cp != '\0')
cp++;
}
/* pragma - handle #pragma ref id... */
static void pragma(void) {
if ((t = gettok()) == ID && strcmp(token, "ref") == 0)
for (;;) {
while (*cp == ' ' || *cp == '\t')
cp++;
if (*cp == '\n' || *cp == 0)
break;
if ((t = gettok()) == ID && tsym) {
tsym->ref++;
use(tsym, src);
}
}
}
/* resynch - set line number/file name in # n [ "file" ], #pragma, etc. */
static void resynch(void) {
for (cp++; *cp == ' ' || *cp == '\t'; )
cp++;
if (limit - cp < MAXLINE)
fillbuf();
if (strncmp((char *)cp, "pragma", 6) == 0) {
cp += 6;
pragma();
} else if (strncmp((char *)cp, "ident", 5) == 0) {
cp += 5;
ident();
} else if (*cp >= '0' && *cp <= '9') {
line: for (lineno = 0; *cp >= '0' && *cp <= '9'; )
lineno = 10*lineno + *cp++ - '0';
lineno--;
while (*cp == ' ' || *cp == '\t')
cp++;
if (*cp == '"') {
file = (char *)++cp;
while (*cp && *cp != '"' && *cp != '\n')
cp++;
file = stringn(file, (char *)cp - file);
if (*cp == '\n')
warning("missing \" in preprocessor line\n");
if (firstfile == 0)
firstfile = file;
}
} else if (strncmp((char *)cp, "line", 4) == 0) {
for (cp += 4; *cp == ' ' || *cp == '\t'; )
cp++;
if (*cp >= '0' && *cp <= '9')
goto line;
if (Aflag >= 2)
warning("unrecognized control line\n");
} else if (Aflag >= 2 && *cp != '\n')
warning("unrecognized control line\n");
while (*cp)
if (*cp++ == '\n')
if (cp == limit + 1) {
nextline();
if (cp == limit)
break;
} else
break;
}