⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 preproc.c

📁 guide and some example with visualC++
💻 C
📖 第 1 页 / 共 3 页
字号:
/* preproc.c * *	(C) Copyright Apr 15 1995, Edmond J. Breen. *		   ALL RIGHTS RESERVED. * This code may be copied for personal, non-profit use only. * *    Developed initially from *    p -- Small-C preprocessor by A.T. Schreiner 6/83. *             DDJ #93 (July) 1984. * *    However, many changes have been implemented and *    extensions made. * *              Grammar *  #define identifier token-sequence *  #define identifier(arg-list) token-sequence *  #undef  identifier *  #include <file-name> *  #include "file-name" *  #include token-sequence *  #if   constant-expr *  #elif constant-expr *  #ifdef  identifier *  #ifndef identifier *  #else *  #endif *  #error  token-sequence #  #pragma token-sequence #  #pragma  * *  The defined operator can be used in #if and #elif *  expressions only: *          #if defined(_EiC) && !defined(UNIX) *           ... *          #elif defined(MSDOS) *           ... *          #endif * *  token-sequence: *            [token-sequence] #token [token-sequence] *            [token-sequence] token##token [token-sequence] *            token-sequence token * *    arg-list: *           identifier [,identifier]* * * Predefined Macros: * *  __LINE__ The line number of the current source program, expressed *           as an integer. *  __FILE__ The name of the current source file, expressed as a *           string. *  __DATE__ resolves to a string literal containing the calender *           date in the form: Mmm dd yyyy. *  __TIME__ resolves to a string literal containing the current time *            in the form hh:mm:ss. *  __STDC__  resolves to 1. * */#include <stdio.h>#include <ctype.h>#include <string.h>#include <stdlib.h>#ifndef WIN32#include <unistd.h>#endif#include <fcntl.h>#include <time.h>#include <sys/types.h>#ifndef WIN32#include <unistd.h>#endif#include <stddef.h>#include <stdarg.h>#include "stab.h"#include "error.h"#include "func.h"#ifdef PPCLIBint _stsptr,persist;char *startstr;char *ppcgets(char *str);#endif#ifdef _STANDALONE#include "preproc.h"int EiC_verboseON=1;int showON = 1;#define xmalloc(x)    malloc(x)#define xcalloc(x,y)  calloc(x,y)#define xrealloc(x,y) realloc(x,y)#define xfree(x)      free(x)#define xmark(x,y)union VaL {        char cval;              /* char value */        int ival;               /* integer value */	char *cpval;	void *pval;};typedef union VaL val_t;typedef struct {        int n;        val_t * val;}eicstack_t;typedef struct {    char *id;    int  token;} keyword_t;#include "preexpr.c"#elsestatic int showON = 0;#include "global.h"#include "xalloc.h"#include "preproc.h"#include "symbol.h"#endif/* TODO: constant from eicmod.c needs header */extern int EiC_showIncludes;fitem_t *EiC_Infile = NULL;int EiC_ptrSafe = 1;static int file_cnt = 0;static stab_t  FileNames = {NULL,0};#define crt_fitem()   (fitem_t*)calloc(sizeof(fitem_t),1)#define free_fitem(x)  free(x)#define STRINGID -2int EiC_IsIncluded(char *fname){    return EiC_stab_FindString(&FileNames,fname) >= 0;}void EiC_showIncludedFiles(void){    EiC_stab_ShowStrings(&FileNames);}void EiC_rmIncludeFileName(char *fname){    EiC_stab_RemoveString(&FileNames,fname);}#if 0/* this is the start of getting the :clear *  command to recursively remove the contents *  of an include file */typedef struct nameTab {    char * fname;    char * inc;    struct nameTab *nxt;};static struct nameTab *incTab = NULL;static void EiC_addIncAssoc(char *fname, char *inc){    struct nameTab *new = xcalloc(sizeof(new), 1);        new->fname = fname;    new->inc = inc;    new->nxt = incTab;    incTab = new;}#endifstatic void NewInfile(int fd, char * fname, char *filep){    fitem_t * f = crt_fitem();    f->fd = fd;    f->fname = EiC_stab_SaveString(&FileNames,fname);    f->next = EiC_Infile;    EiC_Infile = f;    if(EiC_showIncludes) {	int k = file_cnt;	while(--k)	  fputs("   ",stdout);	if((filep && !*filep) || !filep)	  filep = fname;	fprintf(stdout,"%d:%s\n",file_cnt,filep);    }    file_cnt++;}static void NextInfile(){    if(EiC_Infile->next) {	fitem_t * h = EiC_Infile->next;	if(EiC_Infile->fd != STRINGID) {	    close(EiC_Infile->fd);	    if(EiC_Infile->buf)		free(EiC_Infile->buf);	}	free(EiC_Infile);	EiC_Infile = h;	file_cnt--;    }}	static eicstack_t macros = {0, NULL};#define Item(stack,i,item)   ((stack)->val[i].item)  #define STDIN 	0#define STDOUT 	1#define STDERR  2typedef struct {    char * line;    char * lp;    unsigned len;}Line;static size_t NINCLUDES = 0;static char **Include_prefixes = NULL;static char *empty_string = " ";typedef struct {    char *id;          /* token name */    char *tok_seq;     /* token replacement sequence */    int nparms;        /* number of parameters */    char *protect;     /* if one then no expansion before			  replacement for a given parameter*/    long unsigned hcode; /* `id' string hash code */    char *fname;         /* file name pointer */} macro_t;static macro_t defmacro = {NULL, NULL, 0, NULL};static int skip = 0;char cmode;static int linelen, olinelen, iflevel =0;static char *line = NULL, *lp, *oline = NULL, *olp;enum {    DEFAULT, DEFINE,    ELIF, ELSE, ENDIF,     IF, IFDEF, IFNDEF, INCLUDE,    UNDEF, ERROR, PRAGMA};static keyword_t pwords[] ={{"define", DEFINE,},{"elif", ELIF,},{"else", ELSE,},{"endif",ENDIF,},{"error", ERROR,},{"if", IF,},	{"ifdef", IFDEF,},{"ifndef",IFNDEF,},{"include",INCLUDE,},{"pragma", PRAGMA,},{"undef", UNDEF,},	};/** PROTOTYPES from preproc.c **/static int Rgetc();static void rebuff(char **buf, int *len);static void in(char c);static char *out(char c);static char *outChar(char *s, char c, int mod, int i);static int getline();static void expr_list(eicstack_t *parms, char **p,int more);static int findparm(eicstack_t *parms,char *name, size_t len);static void mergeTokens(macro_t *mac);static void parameterise(eicstack_t *parms);static void markmacro(macro_t * mac, char mark);static void kill_Items(eicstack_t *parms);static void freemacro(macro_t * mac);static void remmacroid(int k);static void newmacro(eicstack_t *parms);static void dodefmacro(char *s);static int control_line(void);static char * stringise(char * seq);static char * EiC_expand(char *fld,char **end, int bot, int top);static void process(void);/* TODO: extern from eicmod.c needs header */extern int EiC_verboseON;static unsigned long get_hcode(unsigned char *s){    unsigned long t, h,i;    h = 0;    while(*s) {	for(t = i=0;*s && i<32;i+=8)	    t |= (*s++ << i); 	h += t;    }    return h;}               /*CUT preprocerror.cut*/extern void EiC_pre_error(char *msg, ...){    char *buff1, *buff2;    va_list args;        va_start(args,msg);    buff1 = malloc(strlen(msg) + 256);    buff2 = malloc(strlen(msg) + 512);        EiC_errs++;    EiC_ParseError = 1;    sprintf(buff1,"Error in %s near line %d: %s\n",	    CurrentFileName(),	    CurrentLineNo(),	    msg);    vsprintf(buff2,buff1,args);    EiC_messageDisplay(buff2);    free(buff1);    free(buff2);    va_end(args);}              /*END CUT*/static size_t ninclude = 0;static size_t bot_stab = 0;size_t EiC_pp_NextEntryNum(void){    ninclude = NINCLUDES;    bot_stab = EiC_stab_NextEntryNum(&FileNames);    return macros.n;}size_t EiC_get_EiC_PP_NINCLUDES(void){ return NINCLUDES;}size_t EiC_get_EiC_bot_stab(void) {return EiC_stab_NextEntryNum(&FileNames);}void EiC_set_EiC_PPtoStart(int bot_stab, int ninclude){    NINCLUDES = ninclude;    FileNames.n = bot_stab;}void EiC_pp_CleanUp(size_t bot){    iflevel = 0;    skip = 0;    /* clean up macros */    while(macros.n > bot)	remmacroid(macros.n-1);    /* close opened files */    while(EiC_Infile->next) 	NextInfile();    /* clean up path inclusion */    while(NINCLUDES > ninclude)	EiC_removepath(Include_prefixes[NINCLUDES - 1]);    /* remove included file names */    EiC_stab_CleanUp(&FileNames,bot_stab);}static unsigned putback = 0;#define Ugetc(x)  (putback = x)#define BUFSIZE   512#if 1static void doPragma(char *s){  static  char * Stack = NULL;  static  int N = 0;  if(strstr(s,"push_safeptr")) {    Stack = realloc(Stack,++N);    Stack[N-1] = EiC_ptrSafe = 1;  } else if(strstr(s,"push_unsafeptr")) {    Stack = realloc(Stack,++N);    Stack[N-1] = EiC_ptrSafe = 0;  } else if(strstr(s,"pop_ptr") ) {    if(N-2 >= 0) {      N--;      EiC_ptrSafe = Stack[N-1];    } else      EiC_ptrSafe = 1;  } else      EiC_formatMessage("Warning: Unrecognised pragma (%s): %s line  %d\n",	      s,EiC_Infile->fname, EiC_Infile->lineno);}#endif#if defined(_STANDALONE)#define gchar(fd,c) (c = (read(fd,&c,1) > 0)? c : EOF)static int rline(int fd, char *s, int limit){    int c =0, i;    limit--;    for(i=0;i<limit && gchar(fd,c) != EOF && c != '\n';i++)	s[i] = c;    if(c == '\n')	s[i++] = c;    s[i] = '\0';    return i;}static int Rgetc(){    int c;    static int lastln = 0;    if(putback) {	c = putback;	putback = 0;    } else {	if(EiC_Infile->n <= 0) {	    if(showON && lastln && !skip && EiC_Infile->buf)		fputs(EiC_Infile->buf,stdout);	    EiC_Infile->n = 0;	    if(EiC_Infile->buf == NULL)		EiC_Infile->buf = (char *)malloc(BUFSIZE+1);	    EiC_Infile->n = rline(EiC_Infile->fd,				EiC_Infile->buf,				BUFSIZE);	    EiC_Infile->bufp = EiC_Infile->buf;	    if(showON) {		lastln = 0;		if(!skip) 		    fprintf(stdout,"%s",EiC_Infile->buf);		else {		    lastln  = 1;		    putchar('\n');		}	    }	}	c = ((EiC_Infile->n-- > 0) ? *EiC_Infile->bufp++ : EOF);    }    return c;}#else/* TODO: global from starteic.c needs header */extern int EiC_Interact;static int Rgetc(){    static char prompt[20];    unsigned char * EiC_readline(char *);    void EiC_add_history(unsigned char *);    int c;    #ifdef PPCLIB    void prs(char *str);    static char getsbuf[120];    #endif#ifdef WIN32#define SBUFSIZE	120    static char getsbuf[SBUFSIZE];#endif    if(putback) {	c = putback;	putback = 0;    } else {	if(EiC_Infile->n <= 0) {	    if(EiC_Infile->fd != STDIN || !EiC_Interact) {		if(EiC_Infile->buf == NULL)		    EiC_Infile->buf = malloc(BUFSIZE+1);		if(EiC_Infile->fd != STRINGID)		    EiC_Infile->n = read(EiC_Infile->fd,				     EiC_Infile->buf,BUFSIZE);	    } else {		#ifdef NO_READLINE		fflush(stdout);		fflush(stderr);                sprintf(prompt,"\nEiC %d> ",EiC_Infile->lineno+1);				  #ifdef PPCLIB                prs(prompt);                if(_stsptr!=-1)                 {                   EiC_Infile->buf=startstr;                   _stsptr=-1;                   }                else 		  #endif		      EiC_Infile->buf = ppcgets(getsbuf);                if(EiC_Infile->buf && *EiC_Infile->buf) {                      EiC_Infile->n = strlen(EiC_Infile->buf);                      EiC_Infile->buf[EiC_Infile->n] = '\n';                      EiC_Infile->n++;                  } else                      EiC_Infile->n = 0;                #else		if(EiC_Infile->buf) {		    free(EiC_Infile->buf);		    EiC_Infile->buf = NULL;		}		sprintf(prompt,"EiC %d> ",EiC_Infile->lineno+1);		EiC_Infile->buf = EiC_readline(prompt);		if(EiC_Infile->buf && *EiC_Infile->buf) {		    EiC_add_history(EiC_Infile->buf);		    EiC_Infile->n = strlen((char*)EiC_Infile->buf);		    EiC_Infile->buf[EiC_Infile->n] = '\n';		    EiC_Infile->n++;		} else		    EiC_Infile->n = 0;		#endif	    }	    EiC_Infile->bufp = EiC_Infile->buf;	}	c = ((EiC_Infile->n-- > 0) ? *EiC_Infile->bufp++ : EOF);    }    return c;}#endif /* _STANDALONE */char *EiC_prolineString(char *str){    NewInfile(STRINGID,"STRING","::EiC::");    EiC_Infile->n = strlen(str);    EiC_Infile->buf=EiC_Infile->bufp=(unsigned char*)str;    return str;}static void rebuff(char **buf, int *len){    *buf = (char *) realloc(*buf, (*len + REBUFF_INCREMENT) * sizeof(char));    *len += REBUFF_INCREMENT;}static void in(char c){    *lp++ = c;    if (lp >= line + linelen) {	ptrdiff_t d;	d = lp - line;	rebuff(&line, &linelen);	lp = line + (size_t) d;    }}static char *out(char c){    *olp++ = c;    if (olp >= oline + olinelen) {	ptrdiff_t d;	d = olp - oline;	rebuff(&oline, &olinelen);	olp = oline + (size_t) d;    }    *olp = '\0';    return olp - 1;}static char *outChar(char *s, char c, int mod, int i){    if(!(i%mod)) {	if(!s) 	    s = (char *)xmalloc(sizeof(char)*(i+mod + 1));	else	    s = (char *)xrealloc(s,sizeof(char)*(i+mod + 1));    }    s[i] = c;    return s;}#ifdef _STANDALONE#define EiC_saveComment() NULL#endifstatic int getline(){    /* automatically strips out comments and     * performs line splicing.     */    char c;    int lcom = 0;    lp = line;    while(1) {	switch ((c = Rgetc())) {	case '\\': /* look for line continuation */	    switch ((c = Rgetc())) {	    case EOF:		EiC_pre_error("Unexpected end of file");	    case '\n':		++EiC_Infile->lineno;		continue;	    case '\r': /* ignore carriage returns */	      if((c = Rgetc()) == '\n') {		++EiC_Infile->lineno;		continue;	      }	    }	    in('\\');	default:	    if(!isspace(c) || lp != line) /* skip leading white */		in(c);			       /* space */	    continue;	case EOF:	    if(iflevel && file_cnt == 2)		EiC_pre_error("unterminated `#if' conditional");	    ++EiC_Infile->lineno;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -