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; |
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); |