975 lines · 19.1 KB · C
RawDownload
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <assert.h> FILE *infile;int line=1; #define INCSIZE 16FILE **incfile;char **incname;int *incline;int incn,incsize; #define PP_TSIZE 1024 /*FIXME*/#define ierror(x) abort();#define mymalloc(x) malloc(x)#define myrealloc(x,y) realloc(x,y) /* must not collide with source character-set */enum {  TKKEYWORD=-32,  TKMARG,  TKIDENTIFIER,  TKNUMBER,  TKPLUSPLUS,  TKMINMIN,  TKEOL,  TKLTLT,  TKGTGT,  TKSREF,  TKLE,  TKGE,  TKEQ,  TKNE,  TKLAND,  TKLOR,  TKMULEQ,  TKDIVEQ,  TKMODEQ,  TKPLUSEQ,  TKMINEQ,  TKLTLTEQ,  TKGTGTEQ,  TKANDEQ,  TKOREQ,  TKXOREQ,  TKDDD,  TKNUMNUM}; static char *tokout[]={"err","err","err","err","++","--","","<<",">>","->","<=",">=","==",		       "!=","&&","||","*=","/=","%=","+=","-=","<<=",">>=","&=",		       "|=","^=","...","##"}; static char *desc[]={  "TKKEYWORD",  "TKMARG",  "TKIDENTIFIER",  "TKNUMBER",  "TKPLUSPLUS",  "TKMINMIN",  "TKEOL",  "TKLTLT",  "TKGTGT",  "TKSREF",  "TKLE",  "TKGE",  "TKEQ",  "TKNE",  "TKLAND",  "TKLOR",  "TKMULEQ",  "TKDIVEQ",  "TKMODEQ",  "TKPLUSEQ",  "TKMINEQ",  "TKLTLTEQ",  "TKGTGTEQ",  "TKANDEQ",  "TKOREQ",  "TKXOREQ",  "TKDDD",  "TKNUMNUM"}; typedef struct {  int size;  int next;  int *tokens;} tokenlist; #ifndef OBFUSCATOR #define VARARG_MACRO  1#define BUILTIN_MACRO 2#define NEED_PAREN    4 typedef struct {  char *name;  int flags;  int nargs;  tokenlist repl;} macro; #define PP_HSIZE 16384static int **hash_table; #define PP_MSIZE 128static macro *macro_table;static int macro_cnt=1,macro_size; void print_tokenlist(FILE *,tokenlist *); static void copy_tokenlist(tokenlist *new,tokenlist *old){  if(new->size<old->next+new->next){    new->size=old->next+new->next;    new->tokens=myrealloc(new->tokens,new->size*sizeof(*new->tokens));  }  memcpy(new->tokens+new->next,old->tokens,old->next*sizeof(*new->tokens));  new->next+=old->next;} static int new_macro(char *name,int flags,int nargs,tokenlist *repl){  int i,*p;  if(macro_cnt>=macro_size){    macro_size+=PP_MSIZE;    macro_table=myrealloc(macro_table,macro_size*sizeof(*macro_table));    macro_table[0].name=0; /* dummy */  }  macro_table[macro_cnt].name=mymalloc(strlen(name)+1);  strcpy(macro_table[macro_cnt].name,name);  macro_table[macro_cnt].flags=flags;  macro_table[macro_cnt].nargs=nargs;  macro_table[macro_cnt].repl.size=0;  macro_table[macro_cnt].repl.next=0;  macro_table[macro_cnt].repl.tokens=0;    copy_tokenlist(&macro_table[macro_cnt].repl,repl);  return macro_cnt++;} static void free_macro(int n){  free(macro_table[n].name);  free(macro_table[n].repl.tokens);  macro_table[n].name=0;} static int hash(char *p){  int s=0;  while(*p)    s+=*p++;  return s%PP_HSIZE;} static int find_macro(char *name){  int i=hash(name),n,*p;  if(!(p=hash_table[i])) return 0;  n=p[0];  for(i=1;i<=n;i++)    if(macro_table[p[i]].name&&!strcmp(macro_table[p[i]].name,name))      return p[i];  return 0;} static void add_macro(int n){  int i=hash(macro_table[n].name),*p;  if(!(p=hash_table[i])){    hash_table[i]=p=mymalloc(2*sizeof(*hash_table[i]));    p[0]=1;    p[1]=n;  }else{    p=hash_table[i]=myrealloc(p,(p[0]+1)*sizeof(*p));    p[0]++;    p[p[0]]=n;printf("hash_collisio, depth=%d\n",p[0]);  }} #endif /* OBFUSCATOR */ static FILE *include_file(const char *name){    if(incn>=incsize){	incsize+=INCSIZE;	incfile=myrealloc(incfile,incsize*sizeof(*incfile));	incname=myrealloc(incname,incsize*sizeof(*incname));	incline=myrealloc(incline,incsize*sizeof(*incline));    }    if(!name){	incfile[incn]=stdin;	name="<stdin>";    }else{	incfile[incn]=fopen(name,"r");    }printf("include file %s\n",name);    incname[incn]=mymalloc(strlen(name)+1);    strcpy(incname[incn],name);    incn++;    return incfile[incn-1];} static FILE *close_file(void){    --incn;    free(incname[incn]);    if(incfile[incn])      fclose(incfile[incn]);    if(incn<=0)	return 0;    return incfile[incn-1];} static void add_token(tokenlist *p,int c){  if(p->next>=p->size){    p->size+=PP_TSIZE;    p->tokens=myrealloc(p->tokens,p->size*sizeof(*p->tokens));  }  p->tokens[p->next]=c;  p->next++;} int read_char(void)/* Read next input character. Counts line numbers. */{  int tmp=getc(infile);  if(tmp=='\n') line++;  return tmp;} static int push_back=EOF; static int get_next_char(void)/* Read next character. Handles trigraphs and line-concatenation. */{  static int buf[2],inbuf;  int tmp,tmp2;  if(push_back!=EOF){    tmp=push_back;    push_back=EOF;    return tmp;  }  if(inbuf==0){    tmp=read_char();    if(tmp!='\\'&&tmp!='?'){      return tmp;    }else{      buf[0]=tmp;      inbuf=1;      /* fall through */    }  }  if(inbuf==1){    if(buf[0]!='?'&&buf[0]!='\\'){      inbuf=0;      return buf[0];    }else{      tmp=read_char();      if(buf[0]=='\\'){	if(tmp=='\n'){	  inbuf=0;	  return get_next_char();	}else{	  buf[0]=tmp;	  return '\\';	}      }else{	if(tmp=='?'){	  buf[1]='?';	  inbuf=2;	  /* fall through */	}else{	  buf[0]=tmp;	  return '?';	}      }    }  }  if(inbuf==2){    if(buf[0]!='?') ierror(0);    if(buf[1]!='?'){      inbuf=1;      tmp=buf[0];      buf[0]=buf[1];      return tmp;    }else{      tmp2=tmp=read_char();;      /* FIXME: only if on */      if(tmp=='=') tmp2='#';      else if(tmp=='(') tmp2='[';      else if(tmp=='/') tmp2='\\';      else if(tmp==')') tmp2=']';      else if(tmp=='\'') tmp2='^';      else if(tmp=='<') tmp2='{';      else if(tmp=='!') tmp2='|';      else if(tmp=='>') tmp2='}';      else if(tmp=='-') tmp2='~';      if(tmp!=tmp2){	/* FIXME: warning */	if(tmp2!='\\'){	  inbuf=0;	  return tmp2;	}else{	  inbuf=1;	  buf[0]=tmp2;	  return get_next_char();	}      }else{	tmp=buf[0];	buf[0]=buf[1];	buf[1]=tmp2;	return tmp;      }    }  }  ierror(0);} static int get_next_token(tokenlist *p){  int c,z,tmp,*cnt;  while(1){    c=get_next_char();    if(c=='"'||c=='\''){      int term=c,escape=0;      add_token(p,c);            z=p->next;      add_token(p,0);      while(1){	c=get_next_char();	/* FIXME */	if(c==EOF||c=='\n'){	  puts("unterminated string");	  return 0;	}	if(c==term&&!escape) return 0;	if(escape&&c=='\\')	    escape=0;	else	    escape=(c=='\\');	add_token(p,c);	p->tokens[z]++;      }    }else if(c=='_'||isalpha((unsigned char)c)){      add_token(p,TKIDENTIFIER);      z=p->next;      add_token(p,1);      add_token(p,c);      while((c=get_next_char())=='_'||isalnum((unsigned char)c)){	add_token(p,c);	p->tokens[z]++;      }      push_back=c;      return 0;    }else if(isdigit((unsigned char)c)){      tmp=c;      c=TKNUMBER;    }else if(c=='.'){      tmp=get_next_char();      if(isdigit((unsigned char)tmp)){	push_back=tmp;	tmp='.';	c=TKNUMBER;      }else if(tmp=='.'){	c=get_next_char();	if(c!='.'){puts("..x-token");return 0;}/*FIXME*/	add_token(p,TKDDD);	return 0;      }else	push_back=tmp;      /* fall through */    }else if(c=='+'){      c=get_next_char();      if(c=='+'){	add_token(p,TKPLUSPLUS);      }else if(c=='='){	add_token(p,TKPLUSEQ);      }else{	add_token(p,'+');	push_back=c;      }      return 0;    }else if(c=='-'){      c=get_next_char();      if(c=='-'){	add_token(p,TKMINMIN);      }else if(c=='='){	add_token(p,TKMINEQ);      }else if(c=='>'){	add_token(p,TKSREF);      }else{	add_token(p,'-');	push_back=c;      }      return 0;    }else if(c=='|'){      c=get_next_char();      if(c=='|'){	add_token(p,TKLOR);      }else if(c=='='){	add_token(p,TKOREQ);      }else{	add_token(p,'|');	push_back=c;      }      return 0;    }else if(c=='&'){      c=get_next_char();      if(c=='&'){	add_token(p,TKLAND);      }else if(c=='='){	add_token(p,TKANDEQ);      }else{	add_token(p,'&');	push_back=c;      }      return 0;    }else if(c=='<'){      c=get_next_char();      if(c=='<'){	c=get_next_char();	if(c=='='){	  add_token(p,TKLTLTEQ);	}else{	  add_token(p,TKLTLT);	  push_back=c;	}      }else if(c=='='){	add_token(p,TKLE);      }else{	add_token(p,'<');	push_back=c;      }      return 0;    }else if(c=='>'){      c=get_next_char();      if(c=='>'){	c=get_next_char();	if(c=='=')	  add_token(p,TKGTGTEQ);	else{	  add_token(p,TKGTGT);	  push_back=c;	}      }else if(c=='='){	add_token(p,TKGE);      }else{	add_token(p,'>');	push_back=c;      }      return 0;    }else if(c=='!'){      c=get_next_char();      if(c=='='){	add_token(p,TKNE);      }else{	add_token(p,'!');	push_back=c;      }      return 0;    }else if(c=='*'){      c=get_next_char();      if(c=='='){	add_token(p,TKMULEQ);      }else{	add_token(p,'*');	push_back=c;      }      return 0;    }else if(c=='%'){      c=get_next_char();      if(c=='='){	add_token(p,TKMODEQ);      }else{	add_token(p,'%');	push_back=c;      }      return 0;    }else if(c=='#'){      c=get_next_char();      if(c=='#'){	add_token(p,TKNUMNUM);      }else{	add_token(p,'#');	push_back=c;      }      return 0;    }else if(c=='/'){      /*FIXME*/      c=get_next_char();

Lines 1–500 of 975.