基础函数:
缓冲定义:
static unsigned char buffer[MAXLINE+1 + BUFSIZE+1];
MAXLINE是作为缓冲,当未处理完所有缓冲时,复制未读完的数据,在fillbuf可以看到应用。
获取下一行
- 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(); // 读一行
- }
- iden预处理
- static void ident(void) {
- while (*cp != '/n' && *cp != '/0')
- cp++;
- }
预处理
- /* 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'; ) // #line 处理,记录文件名以及修正行数
- 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;
- }