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

📄 cpp4.c

📁 类PASCAL语言的编译器,LINUX环境的,我没试过是否正确.
💻 C
📖 第 1 页 / 共 2 页
字号:
  else {    scanid(global, c);                         /* Get name to tokenbuf */    (void) defendel(global, global->tokenbuf, TRUE);  }}INLINE FILE_LOCAL  ReturnCode textput(struct Global *global, char *text){  /*   * Put the string in the parm[] buffer.   */  int size;    size = strlen(text) + 1;  if ((global->parmp + size) >= &global->parm[NPARMWORK]) {    cfatal(global, FATAL_MACRO_AREA_OVERFLOW);    return(FPP_WORK_AREA_OVERFLOW);  } else {    strcpy(global->parmp, text);    global->parmp += size;  }  return(FPP_OK);}FILE_LOCALReturnCode charput(struct Global *global, int c){  /*   * Put the byte in the parm[] buffer.   */    if (global->parmp >= &global->parm[NPARMWORK]) {    cfatal(global, FATAL_MACRO_AREA_OVERFLOW);    return(FPP_WORK_AREA_OVERFLOW);  }  *global->parmp++ = c;  return(FPP_OK);}/* *		M a c r o   E x p a n s i o n */ReturnCode expand(struct Global *global, DEFBUF *tokenp){  /*   * Expand a macro.  Called from the cpp mainline routine (via subroutine   * macroid()) when a token is found in the symbol table.  It calls   * expcollect() to parse actual parameters, checking for the correct number.   * It then creates a "file" containing a single line containing the   * macro with actual parameters inserted appropriately.  This is   * "pushed back" onto the input stream.  (When the get() routine runs   * off the end of the macro line, it will dismiss the macro itself.)   */  int c;  FILEINFO *file;  ReturnCode ret=FPP_OK;        /*   * If no macro is pending, save the name of this macro   * for an eventual error message.   */  if (global->recursion++ == 0)    global->macro = tokenp;  else if (global->recursion == RECURSION_LIMIT) {    cerror(global, ERROR_RECURSIVE_MACRO, tokenp->name, global->macro->name);    if (global->rec_recover) {      do {	c = get(global);      } while (global->infile != NULL && global->infile->fp == NULL);      unget(global);      global->recursion = 0;      return(FPP_OK);    }  }  /*   * Here's a macro to expand.   */  global->nargs = 0;			/* Formals counter	*/  global->parmp = global->parm;		/* Setup parm buffer	*/  switch (tokenp->nargs) {  case (-2):                              /* __LINE__             */      if(global->infile->fp)	  /* This is a file */	  sprintf(global->work, "%d", global->line);      else	  /* This is a macro! Find out the file line number! */	  for (file = global->infile; file != NULL; file = file->parent) {	      if (file->fp != NULL) {		  sprintf(global->work, "%d", file->line);		  break;	      }	  }      ret=ungetstring(global, global->work);      if(ret)	  return(ret);      break;      case (-3):                              /* __FILE__             */    for (file = global->infile; file != NULL; file = file->parent) {      if (file->fp != NULL) {	sprintf(global->work, "\"%s\"", (file->progname != NULL)		? file->progname : file->filename);	ret=ungetstring(global, global->work);	if(ret)	  return(ret);	break;      }    }    break;  case (-4):				/* __FUNC__ */    sprintf(global->work, "\"%s\"", global->functionname[0]?	    global->functionname : "<unknown function>");    ret=ungetstring(global, global->work);    if(ret)	return(ret);    break;  case (-5):                              /* __FUNC_LINE__ */    sprintf(global->work, "%d", global->funcline);    ret=ungetstring(global, global->work);    if(ret)      return(ret);    break;  default:    /*     * Nothing funny about this macro.     */    if (tokenp->nargs < 0) {      cfatal(global, FATAL_ILLEGAL_MACRO, tokenp->name);      return(FPP_ILLEGAL_MACRO);    }    while ((c = skipws(global)) == '\n')      /* Look for (, skipping */      global->wrongline = TRUE;		/* spaces and newlines	*/    if (c != '(') {      /*       * If the programmer writes       *	#define foo() ...       *	...       *	foo [no ()]       * just write foo to the output stream.       */      unget(global);      cwarn(global, WARN_MACRO_NEEDS_ARGUMENTS, tokenp->name);      /* fputs(tokenp->name, stdout); */      Putstring(global, tokenp->name);      return(FPP_OK);    } else if (!(ret=expcollect(global))) {     /* Collect arguments    */      if (tokenp->nargs != global->nargs) {     /* Should be an error?  */	cwarn(global, WARN_WRONG_NUMBER_ARGUMENTS, tokenp->name);      }    } else {				/* Collect arguments		*/      return(ret); /* We failed in argument colleting! */    }  case DEF_NOARGS:			/* No parameters just stuffs	*/    ret=expstuff(global, tokenp->name, tokenp->repl); /* expand macro   */  }					/* nargs switch 		*/  return(ret);}INLINE FILE_LOCALReturnCode expcollect(struct Global *global){  /*   * Collect the actual parameters for this macro.   */  int c;  int paren;		    /* For embedded ()'s    */  ReturnCode ret;        for (;;) {    paren = 0;			    /* Collect next arg.    */    while ((c = skipws(global)) == '\n')/* Skip over whitespace */      global->wrongline = TRUE;		/* and newlines.	*/    if (c == ')') {                     /* At end of all args?  */      /*       * Note that there is a guard byte in parm[]       * so we don't have to check for overflow here.       */      *global->parmp = EOS;	    /* Make sure terminated */      break;			    /* Exit collection loop */    }    else if (global->nargs >= LASTPARM) {      cfatal(global, FATAL_TOO_MANY_ARGUMENTS_EXPANSION);      return(FPP_TOO_MANY_ARGUMENTS);    }    global->parlist[global->nargs++] = global->parmp; /* At start of new arg */    for (;; c = cget(global)) {               /* Collect arg's bytes  */      if (c == EOF_CHAR) {	cerror(global, ERROR_EOF_IN_ARGUMENT);	return(FPP_EOF_IN_MACRO); /* Sorry.               */      }      else if (c == '\\') {             /* Quote next character */	charput(global, c);             /* Save the \ for later */	charput(global, cget(global));  /* Save the next char.  */	continue;			/* And go get another   */      }      else if (type[c] == QUO) {        /* Start of string?     */	ret=scanstring(global, c, (ReturnCode (*)(struct Global *, int))charput); /* Scan it off    */	if(ret)	  return(ret);	continue;			    /* Go get next char     */      }      else if (c == '(')                /* Worry about balance  */	paren++;			/* To know about commas */      else if (c == ')') {              /* Other side too       */	if (paren == 0) {               /* At the end?          */	  unget(global);                /* Look at it later     */	  break;			/* Exit arg getter.     */	}	paren--;			/* More to come.        */      }      else if (c == ',' && paren == 0)  /* Comma delimits args  */	break;      else if (c == '\n')               /* Newline inside arg?  */	global->wrongline = TRUE;	/* We'll need a #line   */      charput(global, c);               /* Store this one       */    }				        /* Collect an argument  */    charput(global, EOS);               /* Terminate argument   */  }				        /* Collect all args.    */  return(FPP_OK);                       /* Normal return        */}    #if OK_CONCAT  INLINE FILE_LOCALchar *doquoting(char *to, char *from){  *to++ = '"';  while (*from) {    if (*from == '\\' || *from == '"')      *to++ = '\\';    *to++ = *from++;  }  *to++ = '"';        return to;}  #endif  ReturnCode expstuff(struct Global *global,		    char *MacroName,		    char *MacroReplace){  /*   * Stuff the macro body, replacing formal parameters by actual parameters.   */  int c;		/* Current character	*/  char *inp;		/* -> repl string	*/  char *defp;		/* -> macro output buff */  int size;		/* Actual parm. size	*/  char *defend;		/* -> output buff end	*/  int string_magic;	/* String formal hack	*/  FILEINFO *file;	/* Funny #include	*/  ReturnCode ret;#if OK_CONCAT  char quoting;	/* Quote macro argument */#endif        ret = getfile(global, NBUFF, MacroName, &file);  if(ret)    return(ret);  inp = MacroReplace;			/* -> macro replacement */  defp = file->buffer;			/* -> output buffer	*/  defend = defp + (NBUFF - 1);              /* Note its end         */  if (inp != NULL) {    quoting = 0;    while ((c = (*inp++ & 0xFF)) != EOS) {#if OK_CONCAT      if (c == QUOTE_PARM) {                /* Special token for #  */	quoting = 1;			/* set flag, for later	*/	continue;				/* Get next character	*/      }#endif      if (c >= MAC_PARM && c <= (MAC_PARM + PAR_MAC)) {	string_magic = (c == (MAC_PARM + PAR_MAC));	if (string_magic)	  c = (*inp++ & 0xFF);	/*	 * Replace formal parameter by actual parameter string.	 */	if ((c -= MAC_PARM) < global->nargs) {	  size = strlen(global->parlist[c]);#if OK_CONCAT	  if (quoting) {	    size++;	    size *= 2;		/* worst case condition */	  }#endif	  if ((defp + size) >= defend) {	    cfatal(global, FATAL_OUT_OF_SPACE_IN_ARGUMENT, MacroName);	    return(FPP_OUT_OF_SPACE_IN_MACRO_EXPANSION);	  }	  /*	   * Erase the extra set of quotes.	   */	  if (string_magic && defp[-1] == global->parlist[c][0]) {	    strcpy(defp-1, global->parlist[c]);	    defp += (size - 2);	  }#if OK_CONCATelse if (quoting)  defp = doquoting(defp, global->parlist[c]);#endifelse {  strcpy(defp, global->parlist[c]);  defp += size;}	}      }      else if (defp >= defend) {	cfatal(global, FATAL_OUT_OF_SPACE_IN_ARGUMENT, MacroName);	return(FPP_OUT_OF_SPACE_IN_MACRO_EXPANSION);      } else	*defp++ = c;      quoting = 0;    }  }  *defp = EOS;  return(FPP_OK);}

⌨️ 快捷键说明

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