示例#1
0
文件: cpp3.c 项目: cjapes/core
void initdefines()
/*
 * Initialize the built-in #define's.  There are two flavors:
 *      #define decus   1               (static definitions)
 *      #define __FILE__ ??             (dynamic, evaluated by magic)
 * Called only on cpp startup.
 *
 * Note: the built-in static definitions are supressed by the -N option.
 * __LINE__, __FILE__, and __DATE__ are always present.
 */
{
        register char           **pp;
        register char           *tp;
        register DEFBUF         *dp;
        int                     i;
        time_t                  tvec;

#if !defined( WNT ) && !defined(G3)
        extern char             *ctime();
#endif

        /*
         * Predefine the built-in symbols.  Allow the
         * implementor to pre-define a symbol as "" to
         * eliminate it.
         */
        if (nflag == 0) {
            for (pp = preset; *pp != NULL; pp++) {
                if (*pp[0] != EOS) {
                    dp = defendel(*pp, FALSE);
                    dp->repl = savestring("1");
                    dp->nargs = DEF_NOARGS;
                }
            }
        }
        /*
         * The magic pre-defines (__FILE__ and __LINE__ are
         * initialized with negative argument counts.  expand()
         * notices this and calls the appropriate routine.
         * DEF_NOARGS is one greater than the first "magic" definition.
         */
        if (nflag < 2) {
            for (pp = magic, i = DEF_NOARGS; *pp != NULL; pp++) {
                dp = defendel(*pp, FALSE);
                dp->nargs = --i;
            }
#if OK_DATE
            /*
             * Define __DATE__ as today's date.
             */
            dp = defendel("__DATE__", FALSE);
            dp->repl = tp = getmem(27);
            dp->nargs = DEF_NOARGS;
            time( &tvec);
            *tp++ = '"';
            strcpy(tp, ctime(&tvec));
            tp[24] = '"';                       /* Overwrite newline    */
#endif
        }
}
示例#2
0
文件: cpp3.c 项目: StefanBruens/core
/*
 * Initialize the built-in #define's.  There are two flavors:
 *      #define decus   1               (static definitions)
 *      #define __FILE__ ??             (dynamic, evaluated by magic)
 * Called only on cpp startup.
 *
 * Note: the built-in static definitions are suppressed by the -N option.
 * __LINE__, __FILE__, and __DATE__ are always present.
 */
void initdefines()
{
    char** pp;
    char* tp;
    DEFBUF* dp;
    int i;
    time_t tvec;

    /*
     * Predefine the built-in symbols.  Allow the
     * implementor to pre-define a symbol as "" to
     * eliminate it.
     */
    if (nflag == 0)
    {
        for (pp = preset; *pp != NULL; pp++)
        {
            if (*pp[0] != EOS)
            {
                dp = defendel(*pp, FALSE);
                dp->repl = savestring("1");
                dp->nargs = DEF_NOARGS;
            }
        }
    }
    /*
     * The magic pre-defines (__FILE__ and __LINE__ are
     * initialized with negative argument counts.  expand()
     * notices this and calls the appropriate routine.
     * DEF_NOARGS is one greater than the first "magic" definition.
     */
    if (nflag < 2)
    {
        for (pp = magic, i = DEF_NOARGS; *pp != NULL; pp++)
        {
            dp = defendel(*pp, FALSE);
            dp->nargs = --i;
        }
#if OK_DATE
        /*
         * Define __DATE__ as today's date.
         */
        dp = defendel("__DATE__", FALSE);
        dp->repl = tp = getmem(27);
        dp->nargs = DEF_NOARGS;
        time( &tvec);
        *tp++ = '"';
        strcpy(tp, ctime(&tvec));
        tp[24] = '"';                       /* Overwrite newline    */
#endif
    }
}
示例#3
0
文件: cpp4.c 项目: Akaito/bgfx
void doundef(struct Global *global)
  /*
   * Remove the symbol from the defined list.
   * Called from the #control processor.
   */
{
  int c;
  if (type[(c = skipws(global))] != LET)
    cerror(global, ERROR_ILLEGAL_UNDEF);
  else {
    scanid(global, c);                         /* Get name to tokenbuf */
    (void) defendel(global, global->tokenbuf, TRUE);
  }
}
示例#4
0
文件: cpp3.c 项目: vidarh/FPL
void deldefines(struct Global *global)
{
  /*
   * Delete the built-in #define's.
   */
  char **pp;
  int i;
  
  
  /*
   * Delete the built-in symbols, unless -WW.
   */
  if (global->wflag < 2) {
    for (pp = global->preset; *pp != NULL; pp++) {
      defendel(global, *pp, TRUE);
    }
  }
  /*
   * The magic pre-defines __FILE__ and __LINE__
   */
  for (pp = global->magic, i = DEF_NOARGS; *pp != NULL; pp++) {
    defendel(global, *pp, TRUE);
  }
#if OK_DATE
  /*
   * Undefine __DATE__.
   */
  defendel(global, "__DATE__", TRUE);
  
  /*
   * Undefine __TIME__.
   */
  defendel(global, "__TIME__", TRUE);
#endif
  return;
}
示例#5
0
文件: cpp4.c 项目: sdmckenzie/core
/*
 * Remove the symbol from the defined list.
 * Called from the #control processor.
 */
void doundef()
{
    int c;

    if (type[(c = skipws())] != LET)
        cerror("Illegal #undef argument", NULLST);
    else
    {
        scanid(c);                          /* Get name to token[]  */
        if (defendel(token, TRUE) == NULL)
        {
#ifdef STRICT_UNDEF
            cwarn("Symbol \"%s\" not defined in #undef", token);
#endif
        }
    }
}
示例#6
0
文件: cpp3.c 项目: cjapes/core
int
dooptions(int argc, char** argv)
/*
 * dooptions is called to process command line arguments (-Detc).
 * It is called only at cpp startup.
 */
{
        register char           *ap;
        register DEFBUF         *dp;
        register int            c;
        int                     i, j;
        char                    *arg;
        SIZES                   *sizp;          /* For -S               */
        int                     size;           /* For -S               */
        int                     isdatum;        /* FALSE for -S*        */
        int                     endtest;        /* For -S               */

        for (i = j = 1; i < argc; i++) {
            arg = ap = argv[i];

            if (*ap++ != '-' || *ap == EOS)
            {
                    argv[j++] = argv[i];
            }
            else {
                c = *ap++;                      /* Option byte          */
                if (islower(c))                 /* Normalize case       */
                    c = toupper(c);
                switch (c) {                    /* Command character    */
                case 'C':                       /* Keep comments        */
                    cflag = TRUE;
                    keepcomments = TRUE;
                    break;

                case 'D':                       /* Define symbol        */
                    /*
                     * If the option is just "-Dfoo", make it -Dfoo=1
                     */
                    while (*ap != EOS && *ap != '=')
                        ap++;
                    if (*ap == EOS)
                        ap = "1";
                    else
                        *ap++ = EOS;
                    /*
                     * Now, save the word and its definition.
                     */
                    dp = defendel(argv[i] + 2, FALSE);
                    dp->repl = savestring(ap);
                    dp->nargs = DEF_NOARGS;
                    break;

                case 'E':                       /* Ignore non-fatal     */
                    eflag = TRUE;               /* errors.              */
                    break;

                case 'I':                       /* Include directory    */
                    AddInclude( ap );           /* BP, 11.09.91 */
                    break;

                case 'N':                       /* No predefineds       */
                    nflag++;                    /* Repeat to undefine   */
                    break;                      /* __LINE__, etc.       */

                case 'S':
                    sizp = size_table;
                    if (0 != (isdatum = (*ap != '*'))) /* If it's just -S,     */
                        endtest = T_FPTR;       /* Stop here            */
                    else {                      /* But if it's -S*      */
                        ap++;                   /* Step over '*'        */
                        endtest = 0;            /* Stop at end marker   */
                    }
                    while (sizp->bits != endtest && *ap != EOS) {
                        if (!isdigit(*ap)) {    /* Skip to next digit   */
                            ap++;
                            continue;
                        }
                        size = 0;               /* Compile the value    */
                        while (isdigit(*ap)) {
                            size *= 10;
                            size += (*ap++ - '0');
                        }
                        if (isdatum)
                            sizp->size = size;  /* Datum size           */
                        else
                            sizp->psize = size; /* Pointer size         */
                        sizp++;
                    }
                    if (sizp->bits != endtest)
                        cwarn("-S, too few values specified in %s", argv[i]);
                    else if (*ap != EOS)
                        cwarn("-S, too many values, \"%s\" unused", ap);
                    break;

                case 'U':                       /* Undefine symbol      */
                    if (defendel(ap, TRUE) == NULL)
                        cwarn("\"%s\" wasn't defined", ap);
                    break;

#if OSL_DEBUG_LEVEL > 1
                case 'X':                       /* Debug                */
                    debug = (isdigit(*ap)) ? atoi(ap) : 1;
#if (HOST == SYS_VMS || HOST == SYS_UNIX)
                    signal(SIGINT, (void (*)(int)) abort); /* Trap "interrupt" */
#endif
                    fprintf(stderr, "Debug set to %d\n", debug);
                    break;
#endif

#if OSL_DEBUG_LEVEL > 1
                case 'P':                       /* #define's dump       */
                    bDumpDefs = 1;
                    fprintf(stderr, "Dump #define's is on\n");
                    break;
#endif

                default:                        /* What is this one?    */
                    cwarn("Unknown option \"%s\"", arg);
                    fprintf(stderr, "The following options are valid:\n\
  -C\t\t\tWrite source file comments to output\n\
  -Dsymbol=value\tDefine a symbol with the given (optional) value\n\
  -Idirectory\t\tAdd a directory to the #include search list\n\
  -N\t\t\tDon't predefine target-specific names\n\
  -Stext\t\tSpecify sizes for #if sizeof\n\
  -Usymbol\t\tUndefine symbol\n");
#if OSL_DEBUG_LEVEL > 1
                    fprintf(stderr, "  -Xvalue\t\tSet internal debug flag\n");
                    fprintf(stderr, "  -P\t\t\tdump #define's\n");
#endif
                    break;
                }                       /* Switch on all options        */
            }                           /* If it's a -option            */
        }                               /* For all arguments            */
#if OSL_DEBUG_LEVEL > 1
        if ( (bDumpDefs ? j > 4 : j > 3) ) {
#else
        if (j > 3) {
#endif
            cerror(
                "Too many file arguments.  Usage: cpp [input [output]]",
                NULLST);
        }
        return (j);                     /* Return new argc              */
}

int
readoptions(char* filename, char*** pfargv)
{
        FILE           *fp;
        int c;
        int bInQuotes = 0;
        char optbuff[1024], *poptbuff;
        int fargc=0, back;
        char *fargv[PARALIMIT], **pfa;

        pfa=*pfargv=malloc(sizeof(fargv));

        poptbuff=&optbuff[0];
        filename++;
        if ((fp = fopen(filename, "r")) == NULL) {
#if OSL_DEBUG_LEVEL > 1
            if ( debug || !bDumpDefs )
                perror(filename);
#endif
            return (FALSE);
        }
        do
        {
            /*
             *  #i27914# double ticks '"' now have a duplicate function:
             *  1. they define a string ( e.g. -DFOO="baz" )
             *  2. a string can contain spaces, so -DFOO="baz zum" defines one
             *  argument no two !
             */
            c=fgetc(fp);
            if ( c != ' ' && c != CR && c != NL && c != HT && c != EOF)
            {
                *poptbuff++=(char)c;
                if( c == '"' )
                    bInQuotes = ~bInQuotes;
            }
            else
            {
                if( c != EOF && bInQuotes )
                    *poptbuff++=(char)c;
                else
                {
                    *poptbuff=EOS;
                    if (strlen(optbuff)>0)
                    {
                        pfa[fargc+1]=malloc(strlen(optbuff)+1);
                        strcpy(pfa[fargc+1],optbuff);
                        fargc++;
                        pfa[fargc+1]=0;
                        poptbuff=&optbuff[0];
                    }
                }
            }
        }
        while ( c != EOF );

        fclose(fp);
        back=dooptions(fargc+1,pfa);

        return (back);
}
示例#7
0
文件: cpp3.c 项目: vidarh/FPL
ReturnCode initdefines(struct Global *global)
{
  /*
   * Initialize the built-in #define's.  There are two flavors:
   *	#define decus	1		(static definitions)
   *	#define __FILE__ ??		(dynamic, evaluated by magic)
   * Called only on cpp startup.
   *
   * Note: the built-in static definitions are supressed by the -N option.
   * __LINE__, __FILE__, __TIME__ and __DATE__ are always present.
   */

  char **pp;
  char *tp;
  DEFBUF *dp;
  struct tm *tm;
  
  int i;
  time_t tvec;
  
  static char months[12][4] = {
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    };
  
  /*
   * Predefine the built-in symbols.  Allow the
   * implementor to pre-define a symbol as "" to
   * eliminate it.
   */
  if (!(global->nflag & NFLAG_BUILTIN)) {
    for (pp = global->preset; *pp != NULL; pp++) {
      if (*pp[0] != EOS) {
	dp = defendel(global, *pp, FALSE);
	if(!dp)
	  return(FPP_OUT_OF_MEMORY);
	dp->repl = savestring(global, "1");
	dp->nargs = DEF_NOARGS;
      }
    }
  }
  /*
   * The magic pre-defines (__FILE__ and __LINE__ are
   * initialized with negative argument counts.  expand()
   * notices this and calls the appropriate routine.
   * DEF_NOARGS is one greater than the first "magic" definition.
   */
  if (!(global->nflag & NFLAG_PREDEFINE)) {
    for (pp = global->magic, i = DEF_NOARGS; *pp != NULL; pp++) {
      dp = defendel(global, *pp, FALSE);
      if(!dp)
	return(FPP_OUT_OF_MEMORY);
      dp->nargs = --i;
    }
#if OK_DATE
    /*
     * Define __DATE__ as today's date.
     */
    dp = defendel(global, "__DATE__", FALSE);
    tp = Getmem(global, 14);
    if(!tp || !dp)
      return(FPP_OUT_OF_MEMORY);
    dp->repl = tp;
    dp->nargs = DEF_NOARGS;
    time(&tvec);
    tm = localtime(&tvec);
    sprintf(tp, "\"%3s %2d %4d\"",      /* "Aug 20 1988" */
	    months[tm->tm_mon],
	    tm->tm_mday,
	    tm->tm_year + 1900);
    
    /*
     * Define __TIME__ as this moment's time.
     */
    dp = defendel(global, "__TIME__", FALSE);
    tp = Getmem(global, 11);
    if(!tp || !dp)
      return(FPP_OUT_OF_MEMORY);
    dp->repl = tp;
    dp->nargs = DEF_NOARGS;
    sprintf(tp, "\"%2d:%02d:%02d\"",    /* "20:42:31" */
	    tm->tm_hour,
	    tm->tm_min,
	    tm->tm_sec);
#endif
  }
  return(FPP_OK);
}
示例#8
0
文件: cpp3.c 项目: vidarh/FPL
int dooptions(struct Global *global, struct fppTag *tags)
{
  /*
   * dooptions is called to process command line arguments (-Detc).
   * It is called only at cpp startup.
   */
  DEFBUF *dp;
  char end=FALSE; /* end of taglist */

  while(tags && !end) {
    switch(tags->tag) {
    case FPPTAG_END:
      end=TRUE;
      break;
    case FPPTAG_INITFUNC:
      global->initialfunc = (char *) tags->data;
      break;
    case FPPTAG_DISPLAYFUNCTIONS:
      global->outputfunctions = TRUEFALSE(tags->data);
      break;
    case FPPTAG_RIGHTCONCAT:
      global->rightconcat = TRUEFALSE(tags->data);
      break;
    case FPPTAG_OUTPUTMAIN:
      global->outputfile = TRUEFALSE(tags->data);
      break;
    case FPPTAG_NESTED_COMMENTS:
      global->nestcomments = TRUEFALSE(tags->data);
      break;
    case FPPTAG_WARNMISSINCLUDE:
      global->warnnoinclude = TRUEFALSE(tags->data);
      break;
    case FPPTAG_WARN_NESTED_COMMENTS:
      global->warnnestcomments = TRUEFALSE(tags->data);
      break;
    case FPPTAG_OUTPUTSPACE:
      global->showspace = TRUEFALSE(tags->data);
      break;
    case FPPTAG_OUTPUTBALANCE:
      global->showbalance = TRUEFALSE(tags->data);
      break;
    case FPPTAG_OUTPUTINCLUDES:
      global->showincluded = TRUEFALSE(tags->data);
      break;
    case FPPTAG_IGNOREVERSION:
      global->showversion = TRUEFALSE(tags->data);
      break;
    case FPPTAG_WARNILLEGALCPP:
      global->warnillegalcpp=TRUEFALSE(tags->data);
      break;
    case FPPTAG_OUTPUTLINE:
      global->outputLINE= TRUEFALSE(tags->data);
      break;
    case FPPTAG_KEEPCOMMENTS:
      if(tags->data) {
	global->cflag = TRUE;
	global->keepcomments = TRUE;
      }
      break;
    case FPPTAG_DEFINE:
      /*
       * If the option is just "-Dfoo", make it -Dfoo=1
       */
      {
	char *symbol=(char *)tags->data;
	char *text=symbol;
	while (*text != EOS && *text != '=')
	  text++;
	if (*text == EOS)
	  text = "1";
	else
	  *text++ = EOS;
	/*
	 * Now, save the word and its definition.
	 */
	dp = defendel(global, symbol, FALSE);
	if(!dp)
	  return(FPP_OUT_OF_MEMORY);
	dp->repl = savestring(global, text);
	dp->nargs = DEF_NOARGS;
      }
      break;
    case FPPTAG_IGNORE_NONFATAL:
      global->eflag = TRUE;
      break;
    case FPPTAG_INCLUDE_DIR:
      if (global->incend >= &global->incdir[NINCLUDE]) {
	  cfatal(global, FATAL_TOO_MANY_INCLUDE_DIRS);
	  return(FPP_TOO_MANY_INCLUDE_DIRS);
      }
      *global->incend++ = (char *)tags->data;
      break;
    case FPPTAG_INCLUDE_FILE:
    case FPPTAG_INCLUDE_MACRO_FILE:
      if (global->included >= NINCLUDE) {
	  cfatal(global, FATAL_TOO_MANY_INCLUDE_FILES);
	  return(FPP_TOO_MANY_INCLUDE_FILES);
      }
      global->include[global->included] = (char *)tags->data;

      global->includeshow[global->included] =
	  (tags->tag == FPPTAG_INCLUDE_FILE);

      global->included++;
      break;
    case FPPTAG_BUILTINS:
      global->nflag|=(tags->data?NFLAG_BUILTIN:0);
      break;
    case FPPTAG_PREDEFINES:
      global->nflag|=(tags->data?NFLAG_PREDEFINE:0);
      break;
    case FPPTAG_IGNORE_CPLUSPLUS:
      global->cplusplus=!tags->data;
      break;
    case FPPTAG_SIZEOF_TABLE:
      {
	SIZES *sizp;	/* For -S		*/
	int size;	/* For -S		*/
	int isdatum;	/* FALSE for -S*	*/
	int endtest;	/* For -S		*/

	char *text=(char *)tags->data;

	sizp = size_table;
	if (isdatum = (*text != '*')) /* If it's just -S,     */
	  endtest = T_FPTR;	/* Stop here		*/
	else {			/* But if it's -S*      */
	  text++;		/* Step over '*'        */
	  endtest = 0;		/* Stop at end marker	*/
	}
	while (sizp->bits != endtest && *text != EOS) {
	  if (!isdigit(*text)) {    /* Skip to next digit   */
	    text++;
	    continue;
	  }
	  size = 0;		/* Compile the value	*/
	  while (isdigit(*text)) {
	    size *= 10;
	    size += (*text++ - '0');
	  }
	  if (isdatum)
	    sizp->size = size;	/* Datum size		*/
	  else
	    sizp->psize = size; /* Pointer size 	*/
	  sizp++;
	}
	if (sizp->bits != endtest)
	  cwarn(global, WARN_TOO_FEW_VALUES_TO_SIZEOF, NULL);
	else if (*text != EOS)
	  cwarn(global, WARN_TOO_MANY_VALUES_TO_SIZEOF, NULL);
      }
      break;
    case FPPTAG_UNDEFINE:
      if (defendel(global, (char *)tags->data, TRUE) == NULL)
	cwarn(global, WARN_NOT_DEFINED, tags->data);
      break;
    case FPPTAG_OUTPUT_DEFINES:
      global->wflag++;
      break;
    case FPPTAG_INPUT_NAME:
      strcpy(global->work, tags->data);    /* Remember input filename */
      global->first_file=tags->data;
      break;
    case FPPTAG_INPUT:
      global->input=(char *(*)(char *, int, void *))tags->data;
      break;
    case FPPTAG_OUTPUT:
      global->output=(void (*)(int, void *))tags->data;
      break;      
    case FPPTAG_ERROR:
      global->error=(void (*)(void *, char *, va_list))tags->data;
      break;
    case FPPTAG_USERDATA:
      global->userdata=tags->data;
      break;
    case FPPTAG_LINE:
      global->linelines= TRUEFALSE(tags->data);
      break;
    case FPPTAG_EXCLFUNC:
      global->excludedinit[ global->excluded++ ] = (char *)tags->data;
      break;
    default:
      cwarn(global, WARN_INTERNAL_ERROR, NULL);
      break;
    }
    tags++;
  }
  return(0);
}
示例#9
0
文件: cpp4.c 项目: sdmckenzie/core
/*
 * Called from control when a #define is scanned.  This module
 * parses formal parameters and the replacement string.  When
 * the formal parameter name is encountered in the replacement
 * string, it is replaced by a character in the range 128 to
 * 128+NPARAM (this allows up to 32 parameters within the
 * Dec Multinational range).
 *
 * There is some special case code to distinguish
 *      #define foo     bar
 * from #define foo()   bar
 *
 * Also, we make sure that
 *      #define foo     foo
 * expands to "foo" but doesn't put cpp into an infinite loop.
 *
 * A warning message is printed if you redefine a symbol to a
 * different text.  I.e,
 *      #define foo     123
 *      #define foo     123
 * is ok, but
 *      #define foo     123
 *      #define foo     +123
 * is not.
 *
 * The following subroutines are called from define():
 * checkparm    called when a token is scanned.  It checks through the
 *              array of formal parameters.  If a match is found, the
 *              token is replaced by a control byte which will be used
 *              to locate the parameter when the macro is expanded.
 * textput      puts a string in the macro work area (parm[]), updating
 *              parmp to point to the first free byte in parm[].
 *              textput() tests for work buffer overflow.
 * charput      puts a single character in the macro work area (parm[])
 *              in a manner analogous to textput().
 */
void dodefine()
{
    int c;
    DEFBUF* dp;            /* -> new definition    */
    int isredefine;        /* TRUE if redefined    */
    char* old = NULL;         /* Remember redefined   */

    if (type[(c = skipws())] != LET)
        goto bad_define;
    isredefine = FALSE;                     /* Set if redefining    */
    if ((dp = lookid(c)) == NULL)           /* If not known now     */
        dp = defendel(token, FALSE);        /* Save the name        */
    else                                    /* It's known:          */
    {
        isredefine = TRUE;                  /* Remember this fact   */
        old = dp->repl;                     /* Remember replacement */
        dp->repl = NULL;                    /* No replacement now   */
    }
    parlist[0] = parmp = parm;              /* Setup parm buffer    */
    if ((c = get()) == '(')                 /* With arguments?      */
    {
        nargs = 0;                          /* Init formals counter */
        do                                  /* Collect formal parms */
        {
            if (nargs >= LASTPARM)
                cfatal("Too many arguments for macro", NULLST);
            else if ((c = skipws()) == ')')
                break;                      /* Got them all         */
            else if (type[c] != LET)        /* Bad formal syntax    */
                goto bad_define;
            scanid(c);                      /* Get the formal param */
            parlist[nargs++] = parmp;       /* Save its start       */
            textput(token);                 /* Save text in parm[]  */
        }
        while ((c = skipws()) == ',');      /* Get another argument */
        if (c != ')')                       /* Must end at )        */
            goto bad_define;
        c = ' ';                            /* Will skip to body    */
    }
    else
    {
        /*
         * DEF_NOARGS is needed to distinguish between
         * "#define foo" and "#define foo()".
         */
        nargs = DEF_NOARGS;                 /* No () parameters     */
    }
    if (type[c] == SPA)                     /* At whitespace?       */
        c = skipws();                       /* Not any more.        */
    workp = work;                           /* Replacement put here */
    inmacro = TRUE;                         /* Keep \<newline> now  */
    while (c != EOF_CHAR && c != '\n')      /* Compile macro body   */
    {
        if (c == '#')                       /* Token concatenation? */
        {
            while (workp > work && type[(int)workp[-1]] == SPA)
                --workp;                    /* Erase leading spaces */
            save(TOK_SEP);                  /* Stuff a delimiter    */
            c = skipws();                   /* Eat whitespace       */
            if (type[c] == LET)             /* Another token here?  */
                ;                           /* Stuff it normally    */
            else if (type[c] == DIG)        /* Digit string after?  */
            {
                while (type[c] == DIG)      /* Stuff the digits     */
                {
                    save(c);
                    c = get();
                }
                save(TOK_SEP);              /* Delimit 2nd token    */
            }
            else
            {
                ciwarn("Strange character after # (%d.)", c);
            }
            continue;
        }
        switch (type[c])
        {
        case LET:
            checkparm(c, dp);               /* Might be a formal    */
            break;

        case DIG:                           /* Number in mac. body  */
        case DOT:                           /* Maybe a float number */
            scannumber(c, save);            /* Scan it off          */
            break;

        case QUO:                           /* String in mac. body  */
            stparmscan(c);
            break;

        case BSH:                           /* Backslash            */
            save('\\');
            if ((c = get()) == '\n')
                wrongline = TRUE;
            save(c);
            break;

        case SPA:                           /* Absorb whitespace    */
            /*
             * Note: the "end of comment" marker is passed on
             * to allow comments to separate tokens.
             */
            if (workp[-1] == ' ')           /* Absorb multiple      */
                break;                      /* spaces               */
            else if (c == '\t')
                c = ' ';                    /* Normalize tabs       */
            /* Fall through to store character                      */
        default:                            /* Other character      */
            save(c);
            break;
        }
        c = get();
    }
    inmacro = FALSE;                        /* Stop newline hack    */
    unget();                                /* For control check    */
    if (workp > work && workp[-1] == ' ')   /* Drop trailing blank  */
        workp--;
    *workp = EOS;                           /* Terminate work       */
    dp->repl = savestring(work);            /* Save the string      */
    dp->nargs = nargs;                      /* Save arg count       */
#if OSL_DEBUG_LEVEL > 1
    if (debug)
        dumpadef("macro definition", dp);
    else if (bDumpDefs)
        dumpadef(NULL, dp);
#endif
    if (isredefine)                         /* Error if redefined   */
    {
        if ((old != NULL && dp->repl != NULL && !streq(old, dp->repl)) ||
            (old == NULL && dp->repl != NULL) ||
            (old != NULL && dp->repl == NULL))
        {
#ifdef STRICT_UNDEF
            cerror("Redefining defined variable \"%s\"", dp->name);
#else
            cwarn("Redefining defined variable \"%s\"", dp->name);
#endif
        }
        if (old != NULL)                    /* We don't need the    */
            free(old);                      /* old definition now.  */
    }
    return;

  bad_define:
    cerror("#define syntax error", NULLST);
    inmacro = FALSE;                        /* Stop <newline> hack  */
}
示例#10
0
文件: cpp3.c 项目: StefanBruens/core
/*
 * dooptions is called to process command line arguments (-Detc).
 * It is called only at cpp startup.
 */
int dooptions(int argc, char** argv)
{
    char* ap;
    DEFBUF* dp;
    int c;
    int i, j;
    char* arg;
    SIZES* sizp;        /* For -S               */
    int size;           /* For -S               */
    int isdatum;        /* FALSE for -S*        */
    int endtest;        /* For -S               */

    for (i = j = 1; i < argc; i++)
    {
        arg = ap = argv[i];

        if (*ap++ != '-' || *ap == EOS)
        {
            argv[j++] = argv[i];
        }
        else
        {
            c = *ap++;                      /* Option byte          */
            if (islower(c))                 /* Normalize case       */
                c = toupper(c);
            switch (c)                      /* Command character    */
            {
            case 'C':                       /* Keep comments        */
                cflag = TRUE;
                keepcomments = TRUE;
                break;

            case 'D':                       /* Define symbol        */
                /*
                 * If the option is just "-Dfoo", make it -Dfoo=1
                 */
                while (*ap != EOS && *ap != '=')
                    ap++;
                if (*ap == EOS)
                    ap = "1";
                else
                    *ap++ = EOS;
                /*
                 * Now, save the word and its definition.
                 */
                dp = defendel(argv[i] + 2, FALSE);
                dp->repl = savestring(ap);
                dp->nargs = DEF_NOARGS;
                break;

            case 'E':                       /* Ignore non-fatal     */
                eflag = TRUE;               /* errors.              */
                break;

            case 'I':                       /* Include directory    */
                AddInclude( ap );           /* BP, 11.09.91 */
                break;

            case 'N':                       /* No predefineds       */
                nflag++;                    /* Repeat to undefine   */
                break;                      /* __LINE__, etc.       */

            case 'S':
                sizp = size_table;
                if (0 != (isdatum = (*ap != '*'))) /* If it's just -S,     */
                    endtest = T_FPTR;       /* Stop here            */
                else                        /* But if it's -S*      */
                {
                    ap++;                   /* Step over '*'        */
                    endtest = 0;            /* Stop at end marker   */
                }
                while (sizp->bits != endtest && *ap != EOS)
                {
                    if (!isdigit(*ap))      /* Skip to next digit   */
                    {
                        ap++;
                        continue;
                    }
                    size = 0;               /* Compile the value    */
                    while (isdigit(*ap))
                    {
                        size *= 10;
                        size += (*ap++ - '0');
                    }
                    if (isdatum)
                        sizp->size = size;  /* Datum size           */
                    else
                        sizp->psize = size; /* Pointer size         */
                    sizp++;
                }
                if (sizp->bits != endtest)
                    cwarn("-S, too few values specified in %s", argv[i]);
                else if (*ap != EOS)
                    cwarn("-S, too many values, \"%s\" unused", ap);
                break;

            case 'U':                       /* Undefine symbol      */
                if (defendel(ap, TRUE) == NULL)
                    cwarn("\"%s\" wasn't defined", ap);
                break;

#if OSL_DEBUG_LEVEL > 1
            case 'X':                       /* Debug                */
                debug = (isdigit(*ap)) ? atoi(ap) : 1;
#if (HOST == SYS_UNIX)
                signal(SIGINT, (void (*)(int)) abort); /* Trap "interrupt" */
#endif
                fprintf(stderr, "Debug set to %d\n", debug);
                break;
#endif

#if OSL_DEBUG_LEVEL > 1
            case 'P':                       /* #define's dump       */
                bDumpDefs = 1;
                fprintf(stderr, "Dump #define's is on\n");
                break;
#endif

            default:                        /* What is this one?    */
                cwarn("Unknown option \"%s\"", arg);
                fprintf(stderr, "The following options are valid:\n\
  -C\t\t\tWrite source file comments to output\n\
  -Dsymbol=value\tDefine a symbol with the given (optional) value\n\
  -Idirectory\t\tAdd a directory to the #include search list\n\
  -N\t\t\tDon't predefine target-specific names\n\
  -Stext\t\tSpecify sizes for #if sizeof\n\
  -Usymbol\t\tUndefine symbol\n");
#if OSL_DEBUG_LEVEL > 1
                fprintf(stderr, "  -Xvalue\t\tSet internal debug flag\n");
                fprintf(stderr, "  -P\t\t\tdump #define's\n");
#endif
                break;
            }                       /* Switch on all options        */
        }                           /* If it's a -option            */
    }                               /* For all arguments            */
#if OSL_DEBUG_LEVEL > 1
    if ( (bDumpDefs ? j > 4 : j > 3) )
#else
    if (j > 3)
#endif
    {
        cerror( "Too many file arguments.  Usage: cpp [input [output]]",
                NULLST);
    }
    return (j);                     /* Return new argc              */
}
示例#11
0
文件: cpp4.c 项目: Akaito/bgfx
ReturnCode dodefine(struct Global *global)
{
  /*
   * Called from control when a #define is scanned.  This module
   * parses formal parameters and the replacement string.  When
   * the formal parameter name is encountered in the replacement
   * string, it is replaced by a character in the range 128 to
   * 128+NPARAM (this allows up to 32 parameters within the
   * Dec Multinational range).  If cpp is ported to an EBCDIC
   * machine, you will have to make other arrangements.
   *
   * There is some special case code to distinguish
   *	#define foo	bar
   * from #define foo()   bar
   *
   * Also, we make sure that
   *	#define foo	foo
   * expands to "foo" but doesn't put cpp into an infinite loop.
   *
   * A warning message is printed if you redefine a symbol to a
   * different text.  I.e,
   *	#define foo	123
   *	#define foo	123
   * is ok, but
   *	#define foo	123
   *	#define foo	+123
   * is not.
   *
   * The following subroutines are called from define():
   * checkparm	called when a token is scanned.  It checks through the
   *		array of formal parameters.  If a match is found, the
   *		token is replaced by a control byte which will be used
   *		to locate the parameter when the macro is expanded.
   * textput	puts a string in the macro work area (parm[]), updating
   *		parmp to point to the first free byte in parm[].
   *		textput() tests for work buffer overflow.
   * charput	puts a single character in the macro work area (parm[])
   *		in a manner analogous to textput().
   */
  int c;
  DEFBUF *dp;	/* -> new definition	*/
  int isredefine;	/* TRUE if redefined	*/
  char *old = NULL;		/* Remember redefined	*/
  ReturnCode ret;
#if OK_CONCAT
  int quoting;	/* Remember we saw a #	*/
#endif
  
  if (type[(c = skipws(global))] != LET) {
    cerror(global, ERROR_DEFINE_SYNTAX);
    global->inmacro = FALSE;		/* Stop <newline> hack	*/
    return(FPP_OK);
  }
  isredefine = FALSE;			/* Set if redefining	*/
  if ((dp = lookid(global, c)) == NULL) { /* If not known now     */
    dp = defendel(global, global->tokenbuf, FALSE); /* Save the name  */
    if(!dp)
      return(FPP_OUT_OF_MEMORY);
  } else {				/* It's known:          */
    isredefine = TRUE;			/* Remember this fact	*/
    old = dp->repl;			/* Remember replacement */
    dp->repl = NULL;			/* No replacement now	*/
  }
  global->parlist[0] = global->parmp = global->parm; /* Setup parm buffer */
  if ((c = get(global)) == '(') {       /* With arguments?      */
    global->nargs = 0;			/* Init formals counter */
    do {				/* Collect formal parms */
      if (global->nargs >= LASTPARM) {
	cfatal(global, FATAL_TOO_MANY_ARGUMENTS_MACRO);
	return(FPP_TOO_MANY_ARGUMENTS);
      } else if ((c = skipws(global)) == ')')
	break;			/* Got them all 	*/
      else if (type[c] != LET) {         /* Bad formal syntax    */
	cerror(global, ERROR_DEFINE_SYNTAX);
	global->inmacro = FALSE;		/* Stop <newline> hack	*/
	return(FPP_OK);
      }
      scanid(global, c);                        /* Get the formal param */
      global->parlist[global->nargs++] = global->parmp; /* Save its start */
      ret=textput(global, global->tokenbuf); /* Save text in parm[]  */
      if(ret)
	return(ret);
    } while ((c = skipws(global)) == ',');    /* Get another argument */
    if (c != ')') {                     /* Must end at )        */
      cerror(global, ERROR_DEFINE_SYNTAX);
      global->inmacro = FALSE;		/* Stop <newline> hack	*/
      return(FPP_OK);
    }
    c = ' ';                            /* Will skip to body    */
  }
  else {
    /*
     * DEF_NOARGS is needed to distinguish between
     * "#define foo" and "#define foo()".
     */
    global->nargs = DEF_NOARGS;		/* No () parameters     */
  }
  if (type[c] == SPA)                   /* At whitespace?       */
    c = skipws(global);                 /* Not any more.        */
  global->workp = global->work;		/* Replacement put here */
  global->inmacro = TRUE;		/* Keep \<newline> now	*/
  quoting = 0;				/* No # seen yet.	*/
  while (c != EOF_CHAR && c != '\n') {  /* Compile macro body   */
#if OK_CONCAT
    if (c == '#') {                     /* Token concatenation? */
      if ((c = get(global)) != '#') {   /* No, not really       */
	quoting = 1;		        /* Maybe quoting op.	*/
	continue;
      }
      while (global->workp > global->work && type[(unsigned)*(global->workp - 1)] == SPA)
	--global->workp;		/* Erase leading spaces */
      if((ret=save(global, TOK_SEP)))     /* Stuff a delimiter    */
	return(ret);
      c = skipws(global);               /* Eat whitespace       */
      continue;
    }
#endif
    switch (type[c]) {
    case LET:
#if OK_CONCAT
      ret=checkparm(global, c, dp, quoting);      /* Might be a formal    */
#else
      ret=checkparm(c, dp);               /* Might be a formal    */
#endif
      if(ret)
	return(ret);
      break;
	
    case DIG:				/* Number in mac. body	*/
    case DOT:				/* Maybe a float number */
      ret=scannumber(global, c, save);  /* Scan it off          */
      if(ret)
	return(ret);
      break;
	
    case QUO:				/* String in mac. body	*/
      ret=stparmscan(global, c);
      if(ret)
	return(ret);
      break;
	
    case BSH:				/* Backslash		*/
      ret=save(global, '\\');
      if(ret)
	return(ret);
      if ((c = get(global)) == '\n')
	global->wrongline = TRUE;
      ret=save(global, c);
      if(ret)
	return(ret);
      break;
      
    case SPA:				/* Absorb whitespace	*/
      /*
       * Note: the "end of comment" marker is passed on
       * to allow comments to separate tokens.
       */
      if (global->workp[-1] == ' ')   /* Absorb multiple      */
	break;			/* spaces		*/
      else if (c == '\t')
	c = ' ';                      /* Normalize tabs       */
      /* Fall through to store character			*/
    default:				/* Other character	*/
      ret=save(global, c);
      if(ret)
	return(ret);
      break;
    }
    c = get(global);
    quoting = 0;			/* Only when immediately*/
    /* preceding a formal	*/
  }
  global->inmacro = FALSE;		/* Stop newline hack	*/
  unget(global);                            /* For control check    */
  if (global->workp > global->work && global->workp[-1] == ' ') /* Drop trailing blank  */
    global->workp--;
  *global->workp = EOS;		/* Terminate work	*/
  dp->repl = savestring(global, global->work); /* Save the string      */
  dp->nargs = global->nargs;			/* Save arg count	*/
  if (isredefine) {                   /* Error if redefined   */
    if ((old != NULL && dp->repl != NULL && !streq(old, dp->repl))
	|| (old == NULL && dp->repl != NULL)
	|| (old != NULL && dp->repl == NULL)) {
      cerror(global, ERROR_REDEFINE, dp->name);
    }
    if (old != NULL)                  /* We don't need the    */
      free(old);                      /* old definition now.  */
  }
  return(FPP_OK);
}