668 Context *ctx = (Context *) _ctx; |
668 Context *ctx = (Context *) _ctx; |
669 return ctx->out_of_memory; |
669 return ctx->out_of_memory; |
670 } // preprocessor_outofmemory |
670 } // preprocessor_outofmemory |
671 |
671 |
672 |
672 |
|
673 static inline void pushback(IncludeState *state) |
|
674 { |
|
675 #if DEBUG_PREPROCESSOR |
|
676 printf("PREPROCESSOR PUSHBACK\n"); |
|
677 #endif |
|
678 assert(!state->pushedback); |
|
679 state->pushedback = 1; |
|
680 } // pushback |
|
681 |
|
682 |
|
683 static Token lexer(IncludeState *state) |
|
684 { |
|
685 if (!state->pushedback) |
|
686 return preprocessor_lexer(state); |
|
687 state->pushedback = 0; |
|
688 return state->tokenval; |
|
689 } // lexer |
|
690 |
|
691 |
673 // !!! FIXME: parsing fails on preprocessor directives should skip rest of line. |
692 // !!! FIXME: parsing fails on preprocessor directives should skip rest of line. |
674 static int require_newline(IncludeState *state) |
693 static int require_newline(IncludeState *state) |
675 { |
694 { |
676 const char *source = state->source; |
695 const Token token = lexer(state); |
677 const unsigned int bytes_left = state->bytes_left; |
696 pushback(state); // rewind no matter what. |
678 const unsigned int linenum = state->line; |
697 return ( (token == TOKEN_INCOMPLETE_COMMENT) // call it an eol. |
679 const Token token = preprocessor_lexer(state); |
698 (token == ((Token) '\n')) || (token == TOKEN_EOI) ); |
680 state->source = source; // rewind no matter what. |
|
681 state->bytes_left = bytes_left; |
|
682 state->line = linenum; |
|
683 if (token == TOKEN_INCOMPLETE_COMMENT) |
|
684 return 1; // call it an eol. |
|
685 return ( (token == ((Token) '\n')) || (token == TOKEN_EOI) ); |
|
686 } // require_newline |
699 } // require_newline |
687 |
700 |
688 |
701 |
689 static void handle_pp_include(Context *ctx) |
702 static void handle_pp_include(Context *ctx) |
690 { |
703 { |
691 IncludeState *state = ctx->include_stack; |
704 IncludeState *state = ctx->include_stack; |
692 Token token = preprocessor_lexer(state); |
705 Token token = lexer(state); |
693 MOJOSHADER_includeType incltype; |
706 MOJOSHADER_includeType incltype; |
694 char *filename = NULL; |
707 char *filename = NULL; |
695 int bogus = 0; |
708 int bogus = 0; |
696 |
709 |
697 if (token == TOKEN_STRING_LITERAL) |
710 if (token == TOKEN_STRING_LITERAL) |
761 IncludeState *state = ctx->include_stack; |
774 IncludeState *state = ctx->include_stack; |
762 char *filename = NULL; |
775 char *filename = NULL; |
763 int linenum = 0; |
776 int linenum = 0; |
764 int bogus = 0; |
777 int bogus = 0; |
765 |
778 |
766 if (preprocessor_lexer(state) != TOKEN_INT_LITERAL) |
779 if (lexer(state) != TOKEN_INT_LITERAL) |
767 bogus = 1; |
780 bogus = 1; |
768 else |
781 else |
769 { |
782 { |
770 char *buf = (char *) alloca(state->tokenlen+1); |
783 char *buf = (char *) alloca(state->tokenlen+1); |
771 memcpy(buf, state->token, state->tokenlen); |
784 memcpy(buf, state->token, state->tokenlen); |
772 buf[state->tokenlen] = '\0'; |
785 buf[state->tokenlen] = '\0'; |
773 linenum = atoi(buf); |
786 linenum = atoi(buf); |
774 } // else |
787 } // else |
775 |
788 |
776 if (!bogus) |
789 if (!bogus) |
777 bogus = (preprocessor_lexer(state) != TOKEN_STRING_LITERAL); |
790 bogus = (lexer(state) != TOKEN_STRING_LITERAL); |
778 |
791 |
779 if (!bogus) |
792 if (!bogus) |
780 { |
793 { |
781 state->token++; // skip '\"'... |
794 state->token++; // skip '\"'... |
782 filename = (char *) alloca(state->tokenlen); |
795 filename = (char *) alloca(state->tokenlen); |
812 strcpy(ctx->failstr, prefix); |
824 strcpy(ctx->failstr, prefix); |
813 avail -= prefixlen; |
825 avail -= prefixlen; |
814 ptr += prefixlen; |
826 ptr += prefixlen; |
815 |
827 |
816 state->report_whitespace = 1; |
828 state->report_whitespace = 1; |
817 const char *source = NULL; |
|
818 while (!done) |
829 while (!done) |
819 { |
830 { |
820 bytes_left = state->bytes_left; |
831 const Token token = lexer(state); |
821 source = state->source; |
|
822 const Token token = preprocessor_lexer(state); |
|
823 switch (token) |
832 switch (token) |
824 { |
833 { |
825 case ((Token) '\n'): |
834 case ((Token) '\n'): |
826 state->line--; // make sure error is on the right line. |
835 state->line--; // make sure error is on the right line. |
827 // fall through! |
836 // fall through! |
828 case TOKEN_INCOMPLETE_COMMENT: |
837 case TOKEN_INCOMPLETE_COMMENT: |
829 case TOKEN_EOI: |
838 case TOKEN_EOI: |
830 state->bytes_left = bytes_left; |
839 pushback(state); // move back so we catch this later. |
831 state->source = source; // move back so we catch this later. |
|
832 done = 1; |
840 done = 1; |
833 break; |
841 break; |
834 |
842 |
835 case ' ': |
843 case ' ': |
836 if (!avail) |
844 if (!avail) |
875 Buffer buffer; |
883 Buffer buffer; |
876 init_buffer(&buffer); |
884 init_buffer(&buffer); |
877 |
885 |
878 int done = 0; |
886 int done = 0; |
879 const char *source = NULL; |
887 const char *source = NULL; |
880 unsigned int bytes_left = 0; |
|
881 state->report_whitespace = 1; |
888 state->report_whitespace = 1; |
882 while ((!done) && (!ctx->out_of_memory)) |
889 while ((!done) && (!ctx->out_of_memory)) |
883 { |
890 { |
884 bytes_left = state->bytes_left; |
891 bytes_left = state->bytes_left; |
885 source = state->source; |
892 const Token token = lexer(state); |
886 const Token token = preprocessor_lexer(state); |
|
887 switch (token) |
893 switch (token) |
888 { |
894 { |
889 case TOKEN_INCOMPLETE_COMMENT: |
895 case TOKEN_INCOMPLETE_COMMENT: |
890 case TOKEN_EOI: |
896 case TOKEN_EOI: |
891 state->bytes_left = bytes_left; |
897 pushback(state); // move back so we catch this later. |
892 state->source = source; // move back so we catch this later. |
|
893 // fall through! |
898 // fall through! |
894 case ((Token) '\n'): |
899 case ((Token) '\n'): |
895 done = 1; |
900 done = 1; |
896 break; |
901 break; |
897 |
902 |
1125 // TOKEN_PP_ELIF, |
1130 // TOKEN_PP_ELIF, |
1126 |
1131 |
1127 const Conditional *cond = state->conditional_stack; |
1132 const Conditional *cond = state->conditional_stack; |
1128 const int skipping = ((cond != NULL) && (cond->skipping)); |
1133 const int skipping = ((cond != NULL) && (cond->skipping)); |
1129 |
1134 |
1130 Token token = preprocessor_lexer(state); |
1135 Token token = lexer(state); |
1131 if (token == TOKEN_EOI) |
1136 if (token == TOKEN_EOI) |
1132 { |
1137 { |
1133 assert(state->bytes_left == 0); |
1138 assert(state->bytes_left == 0); |
1134 if (state->conditional_stack != NULL) |
1139 if (state->conditional_stack != NULL) |
1135 { |
1140 { |