mojoshader_preprocessor.c
changeset 606 63e7a66ac320
parent 605 197c9f2999b7
child 607 40d903561ff8
equal deleted inserted replaced
605:197c9f2999b7 606:63e7a66ac320
    25 
    25 
    26 typedef struct Context
    26 typedef struct Context
    27 {
    27 {
    28     int isfail;
    28     int isfail;
    29     int out_of_memory;
    29     int out_of_memory;
    30     char failstr[128];
    30     char failstr[256];
    31     IncludeState *include_stack;
    31     IncludeState *include_stack;
    32     DefineHash *define_hashtable[256];
    32     DefineHash *define_hashtable[256];
    33     int pushedback;
    33     int pushedback;
    34     const char *token;
    34     const char *token;
    35     unsigned int tokenlen;
    35     unsigned int tokenlen;
   390     Context *ctx = (Context *) _ctx;
   390     Context *ctx = (Context *) _ctx;
   391     return ctx->out_of_memory;
   391     return ctx->out_of_memory;
   392 } // preprocessor_outofmemory
   392 } // preprocessor_outofmemory
   393 
   393 
   394 
   394 
       
   395 static void handle_pp_error(Context *ctx)
       
   396 {
       
   397     IncludeState *state = ctx->include_stack;
       
   398     const char *data = NULL;
       
   399     int done = 0;
       
   400 
       
   401     while (!done)
       
   402     {
       
   403         const char *source = state->source;
       
   404         const Token token = preprocessor_internal_lexer(state);
       
   405         switch (token)
       
   406         {
       
   407             case TOKEN_INCOMPLETE_COMMENT:
       
   408                 state->source = source;  // move back so we catch this later.
       
   409                 done = 1;
       
   410                 break;
       
   411 
       
   412             case ((Token) '\n'):
       
   413             case TOKEN_EOI:
       
   414                 done = 1;
       
   415                 break;
       
   416 
       
   417             default:
       
   418                 if (data == NULL)
       
   419                     data = state->token;  // skip #error token.
       
   420                 break;
       
   421         } // switch
       
   422     } // while
       
   423 
       
   424     const char *prefix = "#error ";
       
   425     const size_t prefixlen = strlen(prefix);
       
   426     const int len = (int) (state->source - data);
       
   427     const int cpy = Min(len, sizeof (ctx->failstr) - prefixlen);
       
   428     strcpy(ctx->failstr, prefix);
       
   429     if (cpy > 0)
       
   430         memcpy(ctx->failstr + prefixlen, data, cpy);
       
   431     ctx->failstr[cpy + prefixlen] = '\0';
       
   432     ctx->isfail = 1;
       
   433 } // handle_pp_error
       
   434 
       
   435 
   395 static inline const char *_preprocessor_nexttoken(Preprocessor *_ctx,
   436 static inline const char *_preprocessor_nexttoken(Preprocessor *_ctx,
   396                                              unsigned int *_len, Token *_token)
   437                                              unsigned int *_len, Token *_token)
   397 {
   438 {
   398     Context *ctx = (Context *) _ctx;
   439     Context *ctx = (Context *) _ctx;
   399 
   440 
   424         // TOKEN_PP_IFDEF,
   465         // TOKEN_PP_IFDEF,
   425         // TOKEN_PP_IFNDEF,
   466         // TOKEN_PP_IFNDEF,
   426         // TOKEN_PP_ELSE,
   467         // TOKEN_PP_ELSE,
   427         // TOKEN_PP_ELIF,
   468         // TOKEN_PP_ELIF,
   428         // TOKEN_PP_ENDIF,
   469         // TOKEN_PP_ENDIF,
   429         // TOKEN_PP_ERROR,
       
   430 
   470 
   431         Token token = preprocessor_internal_lexer(state);
   471         Token token = preprocessor_internal_lexer(state);
   432         if (token == TOKEN_EOI)
   472         if (token == TOKEN_EOI)
   433         {
   473         {
   434             assert(state->bytes_left == 0);
   474             assert(state->bytes_left == 0);
   437         } // if
   477         } // if
   438 
   478 
   439         else if (token == TOKEN_INCOMPLETE_COMMENT)
   479         else if (token == TOKEN_INCOMPLETE_COMMENT)
   440         {
   480         {
   441             fail(ctx, "Incomplete multiline comment");
   481             fail(ctx, "Incomplete multiline comment");
       
   482             continue;  // will return at top of loop.
       
   483         } // else if
       
   484 
       
   485         else if (token == TOKEN_PP_ERROR)
       
   486         {
       
   487             handle_pp_error(ctx);
   442             continue;  // will return at top of loop.
   488             continue;  // will return at top of loop.
   443         } // else if
   489         } // else if
   444 
   490 
   445         *_token = token;
   491         *_token = token;
   446         *_len = (unsigned int) (state->source - state->token);
   492         *_len = (unsigned int) (state->source - state->token);