mojoshader_preprocessor.c
changeset 614 0f2f298003ae
parent 612 72ccfe69eaf1
child 615 5467d19b4d7d
equal deleted inserted replaced
613:f48e56a16437 614:0f2f298003ae
   504     Context *ctx = (Context *) _ctx;
   504     Context *ctx = (Context *) _ctx;
   505     return ctx->out_of_memory;
   505     return ctx->out_of_memory;
   506 } // preprocessor_outofmemory
   506 } // preprocessor_outofmemory
   507 
   507 
   508 
   508 
       
   509 static int require_newline(IncludeState *state)
       
   510 {
       
   511     const char *source = state->source;
       
   512     const Token token = preprocessor_internal_lexer(state);
       
   513     if (token == TOKEN_INCOMPLETE_COMMENT)
       
   514     {
       
   515         state->source = source;  // pick this up later.
       
   516         return 1;  // call it an eol.
       
   517     } // if
       
   518     return ( (token == ((Token) '\n')) || (token == TOKEN_EOI) );
       
   519 } // require_newline
       
   520 
       
   521 
   509 static void handle_pp_include(Context *ctx)
   522 static void handle_pp_include(Context *ctx)
   510 {
   523 {
   511     IncludeState *state = ctx->include_stack;
   524     IncludeState *state = ctx->include_stack;
   512     Token token = preprocessor_internal_lexer(state);
   525     Token token = preprocessor_internal_lexer(state);
   513     MOJOSHADER_includeType incltype;
   526     MOJOSHADER_includeType incltype;
   547         state->token++;  // skip '<' or '\"'...
   560         state->token++;  // skip '<' or '\"'...
   548         const unsigned int len = ((unsigned int) (state->source-state->token));
   561         const unsigned int len = ((unsigned int) (state->source-state->token));
   549         filename = (char *) alloca(len);
   562         filename = (char *) alloca(len);
   550         memcpy(filename, state->token, len-1);
   563         memcpy(filename, state->token, len-1);
   551         filename[len-1] = '\0';
   564         filename[len-1] = '\0';
   552 
   565         bogus = !require_newline(state);
   553         // make sure this is EOL.
       
   554         const char *source = state->source;
       
   555         token = preprocessor_internal_lexer(state);
       
   556         if (token == TOKEN_INCOMPLETE_COMMENT)
       
   557             state->source = source;  // pick this up later.
       
   558         bogus = ( (token != ((Token) '\n')) && (token != TOKEN_EOI) );
       
   559     } // if
   566     } // if
   560 
   567 
   561     if (bogus)
   568     if (bogus)
   562     {
   569     {
   563         fail(ctx, "Invalid #include directive");
   570         fail(ctx, "Invalid #include directive");
   578     {
   585     {
   579         assert(ctx->out_of_memory);
   586         assert(ctx->out_of_memory);
   580         ctx->close_callback(newdata, ctx->malloc, ctx->free, ctx->malloc_data);
   587         ctx->close_callback(newdata, ctx->malloc, ctx->free, ctx->malloc_data);
   581     } // if
   588     } // if
   582 } // handle_pp_include
   589 } // handle_pp_include
       
   590 
       
   591 
       
   592 static void handle_pp_line(Context *ctx)
       
   593 {
       
   594     IncludeState *state = ctx->include_stack;
       
   595     char *filename = NULL;
       
   596     int linenum = 0;
       
   597     int bogus = 0;
       
   598 
       
   599     if (preprocessor_internal_lexer(state) != TOKEN_INT_LITERAL)
       
   600         bogus = 1;
       
   601     else
       
   602     {
       
   603         const unsigned int len = ((unsigned int) (state->source-state->token));
       
   604         char *buf = (char *) alloca(len+1);
       
   605         memcpy(buf, state->token, len);
       
   606         buf[len] = '\0';
       
   607         linenum = atoi(buf);
       
   608     } // else
       
   609 
       
   610     if (!bogus)
       
   611         bogus = (preprocessor_internal_lexer(state) != TOKEN_STRING_LITERAL);
       
   612 
       
   613     if (!bogus)
       
   614     {
       
   615         state->token++;  // skip '\"'...
       
   616         const unsigned int len = ((unsigned int) (state->source-state->token));
       
   617         filename = (char *) alloca(len);
       
   618         memcpy(filename, state->token, len-1);
       
   619         filename[len-1] = '\0';
       
   620         bogus = !require_newline(state);
       
   621     } // if
       
   622 
       
   623     if (bogus)
       
   624     {
       
   625         fail(ctx, "Invalid #line directive");
       
   626         return;
       
   627     } // if
       
   628 
       
   629     const char *cached = cache_filename(ctx, filename);
       
   630     assert((cached != NULL) || (ctx->out_of_memory));
       
   631     state->filename = cached;
       
   632     state->line = linenum;
       
   633 } // handle_pp_line
   583 
   634 
   584 
   635 
   585 static void handle_pp_error(Context *ctx)
   636 static void handle_pp_error(Context *ctx)
   586 {
   637 {
   587     IncludeState *state = ctx->include_stack;
   638     IncludeState *state = ctx->include_stack;
   645             *_len = 0;
   696             *_len = 0;
   646             return NULL;  // we're done!
   697             return NULL;  // we're done!
   647         } // if
   698         } // if
   648 
   699 
   649         // !!! FIXME: todo.
   700         // !!! FIXME: todo.
   650         // TOKEN_PP_LINE,
       
   651         // TOKEN_PP_DEFINE,
   701         // TOKEN_PP_DEFINE,
   652         // TOKEN_PP_UNDEF,
   702         // TOKEN_PP_UNDEF,
   653         // TOKEN_PP_IF,
   703         // TOKEN_PP_IF,
   654         // TOKEN_PP_IFDEF,
   704         // TOKEN_PP_IFDEF,
   655         // TOKEN_PP_IFNDEF,
   705         // TOKEN_PP_IFNDEF,
   673 
   723 
   674         else if (token == TOKEN_PP_INCLUDE)
   724         else if (token == TOKEN_PP_INCLUDE)
   675         {
   725         {
   676             handle_pp_include(ctx);
   726             handle_pp_include(ctx);
   677             continue;  // will return error or use new top of include_stack.
   727             continue;  // will return error or use new top of include_stack.
       
   728         } // else if
       
   729 
       
   730         else if (token == TOKEN_PP_LINE)
       
   731         {
       
   732             handle_pp_line(ctx);
       
   733             continue;  // get the next thing.
   678         } // else if
   734         } // else if
   679 
   735 
   680         else if (token == TOKEN_PP_ERROR)
   736         else if (token == TOKEN_PP_ERROR)
   681         {
   737         {
   682             handle_pp_error(ctx);
   738             handle_pp_error(ctx);