cpp6.c
来自「类PASCAL语言的编译器,LINUX环境的,我没试过是否正确.」· C语言 代码 · 共 1,221 行 · 第 1/3 页
C
1,221 行
} while (!done) { /* Process curr. char. */ /* * Note that this algorithm accepts "012e4" and "03.4" * as legitimate floating-point numbers. */ if (radix != 16 && (c == 'e' || c == 'E')) { if (expseen) /* Already saw 'E'? */ break; /* Exit loop, bad nbr. */ expseen = TRUE; /* Set exponent seen */ signseen = FALSE; /* We can read '+' now */ radix = 10; /* Decimal exponent */ } else if (radix != 16 && c == '.') { if (dotflag) /* Saw dot already? */ break; /* Exit loop, two dots */ dotflag = TRUE; /* Remember the dot */ radix = 10; /* Decimal fraction */ } else if (c == '+' || c == '-') { /* 1.0e+10 */ if (signseen) /* Sign in wrong place? */ break; /* Exit loop, not nbr. */ /* signseen = TRUE; */ /* Remember we saw it */ } else { /* Check the digit */ switch (c) { case '8': case '9': /* Sometimes wrong */ octal89 = TRUE; /* Do check later */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': break; /* Always ok */ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': if (radix == 16) /* Alpha's are ok only */ break; /* if reading hex. */ default: /* At number end */ done=TRUE; /* Break from for loop */ continue; } /* End of switch */ } /* End general case */ ret=(*outfun)(global, c); /* Accept the character */ if(ret) return(ret); signseen = TRUE; /* Don't read sign now */ c = get(global); /* Read another char */ } /* End of scan loop */ /* * When we break out of the scan loop, c contains the first * character (maybe) not in the number. If the number is an * integer, allow a trailing 'L' for long and/or a trailing 'U' * for unsigned. If not those, push the trailing character back * on the input stream. Floating point numbers accept a trailing * 'L' for "long double". */ if (dotflag || expseen) { /* Floating point? */ if (c == 'l' || c == 'L') { ret=(*outfun)(global, c); if(ret) return(ret); c = get(global); /* Ungotten later */ } } else { /* Else it's an integer */ /* * We know that dotflag and expseen are both zero, now: * dotflag signals "saw 'L'", and * expseen signals "saw 'U'". */ char done=TRUE; while(done) { switch (c) { case 'l': case 'L': if (dotflag) { done=FALSE; continue; } dotflag = TRUE; break; case 'u': case 'U': if (expseen) { done=FALSE; continue; } expseen = TRUE; break; default: done=FALSE; continue; } ret=(*outfun)(global, c); /* Got 'L' or 'U'. */ if(ret) return(ret); c = get(global); /* Look at next, too. */ } } unget(global); /* Not part of a number */ if (octal89 && radix == 8) cwarn(global, WARN_ILLEGAL_OCTAL); return(FPP_OK);}ReturnCode save(struct Global *global, int c){ if (global->workp >= &global->work[NWORK]) { cfatal(global, FATAL_WORK_BUFFER_OVERFLOW); return(FPP_WORK_AREA_OVERFLOW); } else *global->workp++ = c; return(FPP_OK);}char *savestring(struct Global *global, char *text){ /* * Store a string into free memory. */ char *result; result = Getmem(global, strlen(text) + 1); strcpy(result, text); return (result);}ReturnCode getfile(struct Global *global, int bufsize, /* Line or define buffer size */ char *name, FILEINFO **file) /* File or macro name string */{ /* * Common FILEINFO buffer initialization for a new file or macro. */ int size; size = strlen(name); /* File/macro name */ if(!size) { name = "[stdin]"; size = strlen(name); } *file = (FILEINFO *) Getmem(global, (int)(sizeof (FILEINFO) + bufsize + size)); if(!*file) return(FPP_OUT_OF_MEMORY); (*file)->parent = global->infile; /* Chain files together */ (*file)->fp = NULL; /* No file yet */ (*file)->filename = savestring(global, name); /* Save file/macro name */ (*file)->progname = NULL; /* No #line seen yet */ (*file)->unrecur = 0; /* No macro fixup */ (*file)->bptr = (*file)->buffer; /* Initialize line ptr */ (*file)->buffer[0] = EOS; /* Force first read */ (*file)->line = 0; /* (Not used just yet) */ if (global->infile != NULL) /* If #include file */ global->infile->line = global->line; /* Save current line */ global->infile = (*file); /* New current file */ global->line = 1; /* Note first line */ return(FPP_OK); /* All done. */}void Freemem(void *ptr){ /* * Free a block of memory! */ Free(ptr);}char *Getmem(struct Global *global, int size){ /* * Get a block of free memory. */ char *result; if ((result = (char *)Malloc((unsigned) size)) == NULL) cfatal(global, FATAL_OUT_OF_MEMORY); return(result);}FILE_LOCALchar *incmem(struct Global *global, char *obj, int size){ /* * Get a block of free memory. */ char *result; if ((result = Realloc(obj, (unsigned) size)) == NULL) cfatal(global, FATAL_OUT_OF_MEMORY); return(result);}/* * C P P S y m b o l T a b l e s */ DEFBUF *lookid(struct Global *global, int c) /* First character of token */{ /* * Look for the next token in the symbol table. Returns token in tokenbuf. * If found, returns the table pointer; Else returns NULL. */ int nhash; DEFBUF *dp; int ct; int temp; int isrecurse; /* For #define foo foo */ nhash = 0; if ((isrecurse = (c == DEF_MAGIC))) /* If recursive macro */ c = get(global); /* hack, skip DEF_MAGIC */ ct = 0; do { if (ct == global->tokenbsize) global->tokenbuf = incmem(global, global->tokenbuf, 1 + (global->tokenbsize *= 2)); global->tokenbuf[ct++] = c; /* Store token byte */ nhash += c; /* Update hash value */ c = get(global); } while (type[c] == LET || type[c] == DIG); unget(global); /* Rescan terminator */ global->tokenbuf[ct] = EOS; /* Terminate token */ if (isrecurse) /* Recursive definition */ return(NULL); /* undefined just now */ nhash += ct; /* Fix hash value */ dp = global->symtab[nhash % SBSIZE]; /* Starting bucket */ while (dp != (DEFBUF *) NULL) { /* Search symbol table */ if (dp->hash == nhash /* Fast precheck */ && (temp = strcmp(dp->name, global->tokenbuf)) >= 0) break; dp = dp->link; /* Nope, try next one */ } return((temp == 0) ? dp : NULL);}DEFBUF *defendel(struct Global *global, char *name, int delete) /* TRUE to delete a symbol */{ /* * Enter this name in the lookup table (delete = FALSE) * or delete this name (delete = TRUE). * Returns a pointer to the define block (delete = FALSE) * Returns NULL if the symbol wasn't defined (delete = TRUE). */ DEFBUF *dp; DEFBUF **prevp; char *np; int nhash; int temp; int size; for (nhash = 0, np = name; *np != EOS;) nhash += *np++; size = (np - name); nhash += size; prevp = &global->symtab[nhash % SBSIZE]; while ((dp = *prevp) != (DEFBUF *) NULL) { if (dp->hash == nhash && (temp = strcmp(dp->name, name)) >= 0) { if (temp > 0) dp = NULL; /* Not found */ else { *prevp = dp->link; /* Found, unlink and */ if (dp->repl != NULL) /* Free the replacement */ Freemem(dp->repl); /* if any, and then */ Freemem((char *) dp); /* Free the symbol */ } break; } prevp = &dp->link; } if (!delete) { dp = (DEFBUF *) Getmem(global, (int) (sizeof (DEFBUF) + size)); dp->link = *prevp; *prevp = dp; dp->hash = nhash; dp->repl = NULL; dp->nargs = 0; strcpy(dp->name, name); } return(dp);}void outdefines(struct Global *global){ DEFBUF *dp; DEFBUF **syp; deldefines(global); /* Delete built-in #defines */ for (syp = global->symtab; syp < &global->symtab[SBSIZE]; syp++) { if ((dp = *syp) != (DEFBUF *) NULL) { do { outadefine(global, dp); } while ((dp = dp->link) != (DEFBUF *) NULL); } }}INLINE FILE_LOCALvoid outadefine(struct Global *global, DEFBUF *dp){ char *cp; int c; /* printf("#define %s", dp->name); */ Putstring(global, "#define "); Putstring(global, dp->name); if (dp->nargs > 0) { int i; Putchar(global, '('); for (i = 1; i < dp->nargs; i++) { /* printf("__%d,", i); */ Putstring(global, "__"); Putint(global, i); Putchar(global, ','); } /* printf("__%d)", i); */ Putstring(global, "__"); Putint(global, i); Putchar(global, ')'); } else if (dp->nargs == 0) { Putstring(global, "()"); } if (dp->repl != NULL) { Putchar(global, '\t'); for (cp = dp->repl; (c = *cp++ & 0xFF) != EOS;) { if (c >= MAC_PARM && c < (MAC_PARM + PAR_MAC)) { /* printf("__%d", c - MAC_PARM + 1); */ Putstring(global, "__"); Putint(global, c - MAC_PARM + 1); } else if (isprint(c) || c == '\t' || c == '\n') Putchar(global, c); else switch (c) { case QUOTE_PARM: Putchar(global, '#'); break; case DEF_MAGIC: /* Special anti-recursion */ case MAC_PARM + PAR_MAC: /* Special "arg" marker */ break; case COM_SEP:#if COMMENT_INVISIBLE Putstring(global, "/**/");#else Putchar(global, ' ');#endif break; case TOK_SEP: Putstring(global, "##"); break; default: { /* Octal output! */ char buffer[32]; sprintf(buffer, "\\0%o", c); Putstring(global, buffer); } } } } Putchar(global, '\n');}/* * G E T */int get(struct Global *global){ /* * Return the next character from a macro or the current file. * Handle end of file from #include files. */ int c; FILEINFO *file; int popped; /* Recursion fixup */ long comments=0; popped = 0; get_from_file: if ((file = global->infile) == NULL) return (EOF_CHAR); newline: /* * Read a character from the current input line or macro. * At EOS, either finish the current macro (freeing temp. * storage) or read another line from the current input file. * At EOF, exit the current file (#include) or, at EOF from * the cpp input file, return EOF_CHAR to finish processing. */ if ((c = *file->bptr++ & 0xFF) == EOS) { /* * Nothing in current line or macro. Get next line (if * input from a file), or do end of file/macro processing. * In the latter case, jump back to restart from the top. */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?