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

📄 preproc.c

📁 微软的基于HMM的人脸识别原代码, 非常经典的说
💻 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 PPCLIB
int _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"

#else
static 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 -2


int 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;
}


#endif

static 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  2

typedef 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 1

static 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
#endif

static 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 + -