Our own little c preprocessor that replaces #includes with the file * contents, to work around issue of OpenCL drivers not supporting * include paths with spaces in them. */
| 857 | * include paths with spaces in them. |
| 858 | */ |
| 859 | static string path_source_replace_includes_recursive(const string &_source, |
| 860 | const string &source_filepath, |
| 861 | SourceReplaceState *state) |
| 862 | { |
| 863 | const string *psource = &_source; |
| 864 | string source_new; |
| 865 | |
| 866 | auto pragma_once = _source.find("#pragma once"); |
| 867 | if (pragma_once != string::npos) { |
| 868 | if (state->pragma_onced.find(source_filepath) != state->pragma_onced.end()) { |
| 869 | return ""; |
| 870 | } |
| 871 | state->pragma_onced.insert(source_filepath); |
| 872 | |
| 873 | // "#pragma once" |
| 874 | // "//prgma once" |
| 875 | source_new = _source; |
| 876 | memcpy(source_new.data() + pragma_once, "//pr", 4); |
| 877 | psource = &source_new; |
| 878 | } |
| 879 | |
| 880 | /* Try to re-use processed file without spending time on replacing all |
| 881 | * include directives again. |
| 882 | */ |
| 883 | const SourceReplaceState::ProcessedMapping::iterator replaced_file = state->processed_files.find( |
| 884 | source_filepath); |
| 885 | if (replaced_file != state->processed_files.end()) { |
| 886 | return replaced_file->second; |
| 887 | } |
| 888 | |
| 889 | const string &source = *psource; |
| 890 | |
| 891 | /* Perform full file processing. */ |
| 892 | string result; |
| 893 | const size_t source_length = source.length(); |
| 894 | size_t index = 0; |
| 895 | /* Information about where we are in the source. */ |
| 896 | size_t line_number = 0; |
| 897 | size_t column_number = 1; |
| 898 | /* Currently gathered non-preprocessor token. |
| 899 | * Store as start/length rather than token itself to avoid overhead of |
| 900 | * memory re-allocations on each character concatenation. |
| 901 | */ |
| 902 | size_t token_start = 0; |
| 903 | size_t token_length = 0; |
| 904 | /* Denotes whether we're inside of preprocessor line, together with |
| 905 | * preprocessor line itself. |
| 906 | * |
| 907 | * TODO(sergey): Investigate whether using token start/end position |
| 908 | * gives measurable speedup. |
| 909 | */ |
| 910 | bool inside_preprocessor = false; |
| 911 | string preprocessor_line; |
| 912 | /* Actual loop over the whole source. */ |
| 913 | while (index < source_length) { |
| 914 | const char ch = source[index]; |
| 915 | |
| 916 | if (ch == '\n') { |