input.c (2928B)
1 #include "c.h" 2 3 4 static void pragma(void); 5 static void resynch(void); 6 7 static int bsize; 8 static unsigned char buffer[MAXLINE+1 + BUFSIZE+1]; 9 unsigned char *cp; /* current input character */ 10 char *file; /* current input file name */ 11 char *firstfile; /* first input file */ 12 unsigned char *limit; /* points to last character + 1 */ 13 char *line; /* current line */ 14 int lineno; /* line number of current line */ 15 16 void nextline(void) { 17 do { 18 if (cp >= limit) { 19 fillbuf(); 20 if (cp >= limit) 21 cp = limit; 22 if (cp == limit) 23 return; 24 } else { 25 lineno++; 26 for (line = (char *)cp; *cp==' ' || *cp=='\t'; cp++) 27 ; 28 if (*cp == '#') { 29 resynch(); 30 nextline(); 31 } 32 } 33 } while (*cp == '\n' && cp == limit); 34 } 35 void fillbuf(void) { 36 if (bsize == 0) 37 return; 38 if (cp >= limit) 39 cp = &buffer[MAXLINE+1]; 40 else 41 { 42 int n = limit - cp; 43 unsigned char *s = &buffer[MAXLINE+1] - n; 44 assert(s >= buffer); 45 line = (char *)s - ((char *)cp - line); 46 while (cp < limit) 47 *s++ = *cp++; 48 cp = &buffer[MAXLINE+1] - n; 49 } 50 if (feof(stdin)) 51 bsize = 0; 52 else 53 bsize = fread(&buffer[MAXLINE+1], 1, BUFSIZE, stdin); 54 if (bsize < 0) { 55 error("read error\n"); 56 exit(EXIT_FAILURE); 57 } 58 limit = &buffer[MAXLINE+1+bsize]; 59 *limit = '\n'; 60 } 61 void input_init(int argc, char *argv[]) { 62 static int inited; 63 64 if (inited) 65 return; 66 inited = 1; 67 main_init(argc, argv); 68 limit = cp = &buffer[MAXLINE+1]; 69 bsize = -1; 70 lineno = 0; 71 file = NULL; 72 fillbuf(); 73 if (cp >= limit) 74 cp = limit; 75 nextline(); 76 } 77 78 /* pragma - handle #pragma ref id... */ 79 static void pragma(void) { 80 if ((t = gettok()) == ID && strcmp(token, "ref") == 0) 81 for (;;) { 82 while (*cp == ' ' || *cp == '\t') 83 cp++; 84 if (*cp == '\n' || *cp == 0) 85 break; 86 if ((t = gettok()) == ID && tsym) { 87 tsym->ref++; 88 use(tsym, src); 89 } 90 } 91 } 92 93 /* resynch - set line number/file name in # n [ "file" ] and #pragma ... */ 94 static void resynch(void) { 95 for (cp++; *cp == ' ' || *cp == '\t'; ) 96 cp++; 97 if (limit - cp < MAXLINE) 98 fillbuf(); 99 if (strncmp((char *)cp, "pragma", 6) == 0) { 100 cp += 6; 101 pragma(); 102 } else if (*cp >= '0' && *cp <= '9') { 103 line: for (lineno = 0; *cp >= '0' && *cp <= '9'; ) 104 lineno = 10*lineno + *cp++ - '0'; 105 lineno--; 106 while (*cp == ' ' || *cp == '\t') 107 cp++; 108 if (*cp == '"') { 109 file = (char *)++cp; 110 while (*cp && *cp != '"' && *cp != '\n') 111 cp++; 112 file = stringn(file, (char *)cp - file); 113 if (*cp == '\n') 114 warning("missing \" in preprocessor line\n"); 115 if (firstfile == 0) 116 firstfile = file; 117 } 118 } else if (strncmp((char *)cp, "line", 4) == 0) { 119 for (cp += 4; *cp == ' ' || *cp == '\t'; ) 120 cp++; 121 if (*cp >= '0' && *cp <= '9') 122 goto line; 123 if (Aflag >= 2) 124 warning("unrecognized control line\n"); 125 } else if (Aflag >= 2 && *cp != '\n') 126 warning("unrecognized control line\n"); 127 while (*cp) 128 if (*cp++ == '\n') 129 if (cp == limit + 1) 130 nextline(); 131 else 132 break; 133 } 134