📄 cpp.c
字号:
#ifndef lintstatic char *sccsid = "@(#)cpp.c 4.1 ULTRIX 7/3/90";#endif lint/************************************************************************ * * Modification History * * Jon Reeves, 25-Apr-89 * 013- Add new features from MIPS V2.0 beta: Pascal comment handling * (if LANGUAGE_PASCAL defined); pragma passing; -mips2 flag passed * Some source recorrelating: 006's INCLDIR is now MAXIDIRS * * A note for posterity, since it almost changed here: macro names * cannot be allowed to start with $, since it makes cpp unusable with * assembler immediate constants (like libc syscall jackets). * * Jon Reeves, 31-Oct-88 * 012- Fix eob handling; if eob fired at the end of a // comment, we * infinite looped. * * Jon Reeves, 26-Sep-88 * 011- Merge in features from MIPS cpp (-I<null>; ignore -v). * * Jon Reeves, 14-Jan-88 * 010- Up 'symsiz' (the size of the symbol table for define constants) * from 2500 to 5000. (Contrary to comments on change 8, that * change only removed restrictions on the side buffer. Change 5 * is still obsolete.) * * Jon Reeves, 03-Dec-87 * 009- Merge mod.sources v07i023 patches: add #elif (code from Doug * Gwyn) and, if the -B option is present, recognize //.*\n * comments for C++ (code by Arnold Robbins, Emory U.). * Corrections for line number handling by jlr. * * Jon Reeves, 28-May-87 * 008- Merge BSD 4.3 changes, including: removal of arbitrary limits * (makes 005 obsolete); detect unclosed comments; recognize #ident * for V.3 compatibility; handle # line "file" better; -M same as -Em * (subsumes first part of 004). * * Jon Reeves, 27-May-87 * 007- Copy newlines appearing between macro name and opening paren. * Keeps dbx line counts happy. * * David Metsky, 06-May-87 * 006- Upped the nuber of include directories (-I) from 10 to 32. * Added the defined constant INCLDIR, set to 32. * * David Metsky, 08-Jan-87 * 005- Upped size of SBSIZE from 20*BUFSIZ to 30*BUFSIZ. * * Lu Anne Van de Pas, 01-Apr-86 * 004- Add support for -Em switch to output include file dependencies * and increase symsiz from 2000 to 2500 * * David L Ballenger, 27-Nov-1984 * 003- Increase value of NPREDEF so that more -D and -U options can be * used. * * Stephen Reilly, 29-Dec-83 * 002- Add copyright date * * APS, 27-Dec-83 * 001- Added new defaults symbols bsd4_2 and ultrix * ***********************************************************************//************************************************************************ * * * Copyright (c) 1983 - 1989 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, MIPS Computer Systems, Inc., * * and from Bell Laboratories. Use, duplication, or disclosure is * * subject to restrictions under license agreements with University * * of California, MIPS Computer Systems, Inc., and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************/#ifdef FLEXNAMES#define NCPS 128#else#define NCPS 8#endif# include "stdio.h"# include "ctype.h"/* C command/* written by John F. Reiser/* July/August 1978*/#define STATIC #define FIRSTOPEN -2#define STDIN 0#define READ 0#define WRITE 1#define SALT '#'#if !defined BUFSIZ || BUFSIZ < 8192#undef BUFSIZ#define BUFSIZ 8192#endif#define WORK_AREA 12288char *pbeg,*pbuf,*pend;char *outp,*inp;char *newp;char cinit;/* some code depends on whether characters are sign or zero extended *//* #if '\377' < 0 not used here, old cpp doesn't understand */#if pdp11 | vax | mc68000#define COFF 128#else#define COFF 0#endif# if gcos#define ALFSIZ 512 /* alphabet size */# else#define ALFSIZ 256 /* alphabet size */# endifchar macbit[ALFSIZ+11];char toktyp[ALFSIZ];#define BLANK 1#define IDENT 2#define NUMBR 3/* a superimposed code is used to reduce the number of calls to the/* symbol table lookup routine. (if the kth character of an identifier/* is 'a' and there are no macro names whose kth character is 'a'/* then the identifier cannot be a macro name, hence there is no need/* to look in the symbol table.) 'scw1' enables the test based on/* single characters and their position in the identifier. 'scw2'/* enables the test based on adjacent pairs of characters and their/* position in the identifier. scw1 typically costs 1 indexed fetch,/* an AND, and a jump per character of identifier, until the identifier/* is known as a non-macro name or until the end of the identifier./* scw1 is inexpensive. scw2 typically costs 4 indexed fetches,/* an add, an AND, and a jump per character of identifier, but it is also/* slightly more effective at reducing symbol table searches./* scw2 usually costs too much because the symbol table search is/* usually short; but if symbol table search should become expensive,/* the code is here./* using both scw1 and scw2 is of dubious value.*/#define scw1 1#define scw2 0#if scw2char t21[ALFSIZ],t22[ALFSIZ],t23[ALFSIZ+NCPS];#endif#if scw1#define b0 1#define b1 2#define b2 4#define b3 8#define b4 16#define b5 32#define b6 64#define b7 128#endif#define IB 1#define SB 2#define NB 4#define CB 8#define QB 16#define WB 32char fastab[ALFSIZ];char slotab[ALFSIZ];char *ptrtab;#define isslo (ptrtab==(slotab+COFF))#define isid(a) ((fastab+COFF)[a]&IB)#define isspc(a) (ptrtab[a]&SB)#define isnum(a) ((fastab+COFF)[a]&NB)#define iscom(a) ((fastab+COFF)[a]&CB)#define isquo(a) ((fastab+COFF)[a]&QB)#define iswarn(a) ((fastab+COFF)[a]&WB)#define eob(a) ((a)>=pend)#define bob(a) (pbeg>=(a))# define cputc(a,b) if(!flslvl) putc(a,b)char buffer[NCPS+BUFSIZ+BUFSIZ+NCPS];char *lastcopy;char *malloc(), *realloc();# define DROP 0xFE /* special character not legal ASCII or EBCDIC */# define WARN DROP# define SAME 0# define MAXINC 30 /* was 10. bumped for rel. 1.30 --uk 11/30/87 */# define MAXFRE 14 /* max buffers of macro pushback */# define MAXFRM 64 /* max number of formals/actuals to a macro */# define MAXIDIRS 50 /* max number of -I's, added const --mad 7/23/86 */ /* bumped for rel. 1.30--uk 12/1/87 */static char warnc = WARN;int mactop,fretop;char *instack[MAXFRE],*bufstack[MAXFRE],*endbuf[MAXFRE];int plvl; /* parenthesis level during scan for macro actuals */int maclin; /* line number of macro call requiring actuals */char *macfil; /* file name of macro call requiring actuals */char *macnam; /* name of macro requiring actuals */int maclvl; /* # calls since last decrease in nesting level */char *macforw; /* pointer which must be exceeded to decrease nesting level */int macdam; /* offset to macforw due to buffer shifting *//* LFL 3-9-88 */int pascal_file = 0; /* True if LANGUAGE_PASCAL is defined */#if tgpint tgpscan; /* flag for dump(); */#endifSTATIC int inctop[MAXINC];STATIC char *fnames[MAXINC];STATIC char *dirnams[MAXINC]; /* actual directory of #include files */STATIC int fins[MAXINC];STATIC int lineno[MAXINC];STATIC char *dirs[MAXIDIRS]; /* -I and <> directories */char *strdex(), *copy(), *subst(), *trmdir();struct symtab *stsym();STATIC int fin = FIRSTOPEN;STATIC FILE *fout = stdout;STATIC int nd = 1;STATIC int pflag; /* don't put out lines "# 12 foo.c" */int passcom; /* don't delete comments */int eolcom; /* allow // ... \n comments */int incomment; /* True if parsing a comment */STATIC int rflag; /* allow macro recursion */STATIC int mflag; /* generate makefile dependencies */STATIC char *infile; /* name of .o file to build dependencies from */STATIC FILE *mout; /* file to place dependencies on */#define START 1#define CONT 2#define BACK 3STATIC int ifno;# define NPREDEF 100STATIC char *prespc[NPREDEF];STATIC char **predef = prespc;STATIC char *punspc[NPREDEF];STATIC char **prund = punspc;STATIC int exfail;struct symtab { char *name; char *value;} *lastsym, *lookup(), *slookup();# if gcos#include <setjmp.h>static jmp_buf env;# define main mainpp# undef exit# define exit(S) longjmp(env, 1)# define open(S,D) fileno(fopen(S, "r"))# define close(F) fclose(_f[F])extern FILE *_f[];# define symsiz 8000# else# define symsiz 8000# endifSTATIC struct symtab stab[symsiz];STATIC struct symtab *defloc;STATIC struct symtab *udfloc;STATIC struct symtab *incloc;STATIC struct symtab *ifloc;STATIC struct symtab *eliloc; /* DAG -- added */STATIC struct symtab *elsloc;STATIC struct symtab *eifloc;STATIC struct symtab *ifdloc;STATIC struct symtab *ifnloc;STATIC struct symtab *pragmaloc;STATIC struct symtab *ysysloc;STATIC struct symtab *varloc;STATIC struct symtab *lneloc;STATIC struct symtab *ulnloc;STATIC struct symtab *uflloc;STATIC struct symtab *identloc; /* Sys 5r3 compatibility */STATIC int trulvl;STATIC int flslvl;#define MAX_IF_NESTING 64 /* DAG -- added (must be at least6) */STATIC int ifdone[MAX_IF_NESTING]; /* DAG -- added */sayline(where) int where;{ if (mflag && where==START) fprintf(mout, "%s: %s\n", infile, fnames[ifno]); if (pflag==0) fprintf(fout,"# %d \"%s\"\n", lineno[ifno], fnames[ifno]);}/* data structure guide/*/* most of the scanning takes place in the buffer:/*/* (low address) (high address)/* pbeg pbuf pend/* | <-- BUFSIZ chars --> | <-- BUFSIZ chars --> |/* _______________________________________________________________________/* |_______________________________________________________________________|/* | | |/* |<-- waiting -->| |<-- waiting -->/* | to be |<-- current -->| to be/* | written | token | scanned/* | | |/* outp inp p/*/* *outp first char not yet written to output file/* *inp first char of current token/* *p first char not yet scanned/*/* macro expansion: write from *outp to *inp (chars waiting to be written),/* ignore from *inp to *p (chars of the macro call), place generated/* characters in front of *p (in reverse order), update pointers,/* resume scanning./*/* symbol table pointers point to just beyond the end of macro definitions;/* the first preceding character is the number of formal parameters./* the appearance of a formal in the body of a definition is marked by/* 2 chars: the char WARN, and a char containing the parameter number./* the first char of a definition is preceded by a zero character./*/* when macro expansion attempts to back up over the beginning of the/* buffer, some characters preceding *pend are saved in a side buffer,/* the address of the side buffer is put on 'instack', and the rest/* of the main buffer is moved to the right. the end of the saved buffer/* is kept in 'endbuf' since there may be nulls in the saved buffer./*/* similar action is taken when an 'include' statement is processed,/* except that the main buffer must be completely emptied. the array/* element 'inctop[ifno]' records the last side buffer saved when/* file 'ifno' was included. these buffers remain dormant while/* the file is being read, and are reactivated at end-of-file./*/* instack[0 : mactop] holds the addresses of all pending side buffers./* instack[inctop[ifno]+1 : mactop-1] holds the addresses of the side/* buffers which are "live"; the side buffers instack[0 : inctop[ifno]]/* are dormant, waiting for end-of-file on the current file./*/* space for side buffers is obtained from 'malloc' and is never returned./* bufstack[0:fretop-1] holds addresses of side buffers which/* are available for use.*/dump() {/* write part of buffer which lies between outp and inp ./* this should be a direct call to 'write', but the system slows to a crawl/* if it has to do an unaligned copy. thus we buffer. this silly loop/* is 15% of the total time, thus even the 'putc' macro is too slow.*/ register char *p1,*p2; register FILE *f; if ((p1=outp)==inp || flslvl!=0) return;#if tgp#define MAXOUT 80 if (!tgpscan) {/* scan again to insure <= MAXOUT chars between linefeeds */ register char c,*pblank; char savc,stopc,brk; tgpscan=1; brk=stopc=pblank=0; p2=inp; savc= *p2; *p2='\0'; while (c= *p1++) { if (c=='\\') c= *p1++; if (stopc==c) stopc=0; else if (c=='"' || c=='\'') stopc=c; if (p1-outp>MAXOUT && pblank!=0) { *pblank++='\n'; inp=pblank; dump(); brk=1; pblank=0; } if (c==' ' && stopc==0) pblank=p1-1; } if (brk) sayline(CONT); *p2=savc; inp=p2; p1=outp; tgpscan=0; }#endif f=fout;# if gcos/* filter out "$ program c" card if first line of input *//* gmatch is a simple pattern matcher in the GCOS Standard Library */{ static int gmfirst = 0; if (!gmfirst) { ++gmfirst; if (gmatch(p1, "^$*program[ \t]*c*")) p1 = strdex(p1, '\n'); }}# endif /* Performance improvement - skip the writes if doing makefile - rr */ if (!mflag) while (p1<inp) putc(*p1++,f); outp = inp;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -