865 /* Handle the file includes! */ |
867 /* Handle the file includes! */ |
866 /*********************************/ |
868 /*********************************/ |
867 <include_beg>{file_include_pragma_beg} BEGIN(include_filename); |
869 <include_beg>{file_include_pragma_beg} BEGIN(include_filename); |
868 |
870 |
869 <include_filename>{file_include_pragma_filename} { |
871 <include_filename>{file_include_pragma_filename} { |
870 /* got the include file name */ |
872 /* set the internal state variables of lexical analyser to process a new include file */ |
871 int i; |
873 include_file(yytext); |
872 |
|
873 if (include_stack_ptr >= MAX_INCLUDE_DEPTH) { |
|
874 fprintf(stderr, "Includes nested too deeply\n"); |
|
875 exit( 1 ); |
|
876 } |
|
877 include_stack[include_stack_ptr].buffer_state = YY_CURRENT_BUFFER; |
|
878 include_stack[include_stack_ptr].env = current_tracking; |
|
879 include_stack[include_stack_ptr].filename = current_filename; |
|
880 |
|
881 for (i = 0, yyin = NULL; (INCLUDE_DIRECTORIES[i] != NULL) && (yyin == NULL); i++) { |
|
882 char *full_name = strdup3(INCLUDE_DIRECTORIES[i], "/", yytext); |
|
883 if (full_name == NULL) { |
|
884 fprintf(stderr, "Out of memory!\n"); |
|
885 exit( 1 ); |
|
886 } |
|
887 yyin = fopen(full_name, "r"); |
|
888 free(full_name); |
|
889 } |
|
890 |
|
891 if (!yyin) { |
|
892 fprintf(stderr, "Error opening included file %s\n", yytext); |
|
893 exit( 1 ); |
|
894 } |
|
895 |
|
896 current_filename = strdup(yytext); |
|
897 current_tracking = GetNewTracking(yyin); |
|
898 include_stack_ptr++; |
|
899 |
|
900 /* switch input buffer to new file... */ |
|
901 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); |
|
902 /* switch to whatever state was active before the include file */ |
874 /* switch to whatever state was active before the include file */ |
903 yy_pop_state(); |
875 yy_pop_state(); |
904 /* now process the new file... */ |
876 /* now process the new file... */ |
905 } |
877 } |
906 |
878 |
945 yy_push_state(include_end); |
917 yy_push_state(include_end); |
946 } |
918 } |
947 } |
919 } |
948 |
920 |
949 <include_end>{file_include_pragma_end} yy_pop_state(); |
921 <include_end>{file_include_pragma_end} yy_pop_state(); |
|
922 /* handle the artificial file includes created by include_string(), which do not end with a '}' */ |
|
923 <include_end>. unput_text(0); yy_pop_state(); |
950 |
924 |
951 |
925 |
952 /*********************************/ |
926 /*********************************/ |
953 /* Handle all the state changes! */ |
927 /* Handle all the state changes! */ |
954 /*********************************/ |
928 /*********************************/ |
1688 for (i = include_stack_ptr - 1; i >= 0; i--) |
1662 for (i = include_stack_ptr - 1; i >= 0; i--) |
1689 fprintf (stderr, "included from file %s:%d\n", include_stack[i].filename, include_stack[i].env->lineNumber); |
1663 fprintf (stderr, "included from file %s:%d\n", include_stack[i].filename, include_stack[i].env->lineNumber); |
1690 } |
1664 } |
1691 |
1665 |
1692 |
1666 |
|
1667 |
|
1668 /* set the internal state variables of lexical analyser to process a new include file */ |
|
1669 void handle_include_file_(FILE *filehandle, const char *filename) { |
|
1670 if (include_stack_ptr >= MAX_INCLUDE_DEPTH) { |
|
1671 fprintf(stderr, "Includes nested too deeply\n"); |
|
1672 exit( 1 ); |
|
1673 } |
|
1674 |
|
1675 yyin = filehandle; |
|
1676 |
|
1677 include_stack[include_stack_ptr].buffer_state = YY_CURRENT_BUFFER; |
|
1678 include_stack[include_stack_ptr].env = current_tracking; |
|
1679 include_stack[include_stack_ptr].filename = current_filename; |
|
1680 |
|
1681 current_filename = strdup(filename); |
|
1682 current_tracking = GetNewTracking(yyin); |
|
1683 include_stack_ptr++; |
|
1684 |
|
1685 /* switch input buffer to new file... */ |
|
1686 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); |
|
1687 } |
|
1688 |
|
1689 |
|
1690 |
|
1691 /* insert the code (in <source_code>) into the source code we are parsing. |
|
1692 * This is done by creating an artificial file with that new source code, and then 'including' the file |
|
1693 */ |
|
1694 void include_string(const char *source_code) { |
|
1695 FILE *tmp_file = tmpfile(); |
|
1696 |
|
1697 if(tmp_file == NULL) { |
|
1698 perror("Error creating temp file."); |
|
1699 exit(EXIT_FAILURE); |
|
1700 } |
|
1701 |
|
1702 fwrite((void *)source_code, 1, strlen(source_code), tmp_file); |
|
1703 rewind(tmp_file); |
|
1704 |
|
1705 /* now parse the tmp file, by asking flex to handle it as if it had been included with the (*#include ... *) pragma... */ |
|
1706 handle_include_file_(tmp_file, ""); |
|
1707 //fclose(tmp_file); /* do NOT close file. It must only be closed when we finish reading from it! */ |
|
1708 } |
|
1709 |
|
1710 |
|
1711 |
|
1712 /* Open an include file, and set the internal state variables of lexical analyser to process a new include file */ |
|
1713 void include_file(const char *filename) { |
|
1714 FILE *filehandle = NULL; |
|
1715 |
|
1716 for (int i = 0; (INCLUDE_DIRECTORIES[i] != NULL) && (filehandle == NULL); i++) { |
|
1717 char *full_name; |
|
1718 full_name = strdup3(INCLUDE_DIRECTORIES[i], "/", filename); |
|
1719 if (full_name == NULL) { |
|
1720 fprintf(stderr, "Out of memory!\n"); |
|
1721 exit( 1 ); |
|
1722 } |
|
1723 filehandle = fopen(full_name, "r"); |
|
1724 free(full_name); |
|
1725 } |
|
1726 |
|
1727 if (NULL == filehandle) { |
|
1728 fprintf(stderr, "Error opening included file %s\n", filename); |
|
1729 exit( 1 ); |
|
1730 } |
|
1731 |
|
1732 /* now process the new file... */ |
|
1733 handle_include_file_(filehandle, filename); |
|
1734 } |
|
1735 |
|
1736 |
|
1737 |
|
1738 |
|
1739 |
1693 /* return all the text in the current token back to the input stream, except the first n chars. */ |
1740 /* return all the text in the current token back to the input stream, except the first n chars. */ |
1694 void unput_text(unsigned int n) { |
1741 void unput_text(unsigned int n) { |
1695 /* it seems that flex has a bug in that it will not correctly count the line numbers |
1742 /* it seems that flex has a bug in that it will not correctly count the line numbers |
1696 * if we return newlines back to the input stream. These newlines will be re-counted |
1743 * if we return newlines back to the input stream. These newlines will be re-counted |
1697 * a second time when they are processed again by flex. |
1744 * a second time when they are processed again by flex. |