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 + -
显示快捷键?