| 38 | } |
| 39 | |
| 40 | std::string readShaderFile(const char* fileName) |
| 41 | { |
| 42 | FILE* file = fopen(fileName, "r"); |
| 43 | |
| 44 | if (!file) |
| 45 | { |
| 46 | printf("I/O error. Cannot open shader file '%s'\n", fileName); |
| 47 | return std::string(); |
| 48 | } |
| 49 | |
| 50 | fseek(file, 0L, SEEK_END); |
| 51 | const auto bytesinfile = ftell(file); |
| 52 | fseek(file, 0L, SEEK_SET); |
| 53 | |
| 54 | char* buffer = (char*)alloca(bytesinfile + 1); |
| 55 | const size_t bytesread = fread(buffer, 1, bytesinfile, file); |
| 56 | fclose(file); |
| 57 | |
| 58 | buffer[bytesread] = 0; |
| 59 | |
| 60 | static constexpr unsigned char BOM[] = { 0xEF, 0xBB, 0xBF }; |
| 61 | |
| 62 | if (bytesread > 3) |
| 63 | { |
| 64 | if (!memcmp(buffer, BOM, 3)) |
| 65 | memset(buffer, ' ', 3); |
| 66 | } |
| 67 | |
| 68 | std::string code(buffer); |
| 69 | |
| 70 | while (code.find("#include ") != code.npos) |
| 71 | { |
| 72 | const auto pos = code.find("#include "); |
| 73 | const auto p1 = code.find('<', pos); |
| 74 | const auto p2 = code.find('>', pos); |
| 75 | if (p1 == code.npos || p2 == code.npos || p2 <= p1) |
| 76 | { |
| 77 | printf("Error while loading shader program: %s\n", code.c_str()); |
| 78 | return std::string(); |
| 79 | } |
| 80 | const std::string name = code.substr(p1 + 1, p2 - p1 - 1); |
| 81 | const std::string include = readShaderFile(name.c_str()); |
| 82 | code.replace(pos, p2-pos+1, include.c_str()); |
| 83 | } |
| 84 | |
| 85 | return code; |
| 86 | } |
no outgoing calls
no test coverage detected