BsIncludeHandler.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include "BsSLPrerequisites.h"
  2. #include "Material/BsShaderManager.h"
  3. #include "Material/BsShaderInclude.h"
  4. extern "C" {
  5. #include "BsIncludeHandler.h"
  6. #include "BsMMAlloc.h"
  7. }
  8. using namespace bs;
  9. char* includePush(ParseState* state, const char* filename, int line, int column, int* size)
  10. {
  11. int filenameQuotesLen = (int)strlen(filename);
  12. char* filenameNoQuote = (char*)mmalloc(state->memContext, filenameQuotesLen - 1);
  13. memcpy(filenameNoQuote, filename + 1, filenameQuotesLen - 2);
  14. filenameNoQuote[filenameQuotesLen - 2] = '\0';
  15. HShaderInclude include = ShaderManager::instance().findInclude(filenameNoQuote);
  16. if (include != nullptr)
  17. include.blockUntilLoaded();
  18. int filenameLen = (int)strlen(filenameNoQuote);
  19. if (include.isLoaded())
  20. {
  21. String includeSource = include->getString();
  22. *size = (int)includeSource.size() + 2;
  23. char* output = (char*)mmalloc(state->memContext, *size);
  24. memcpy(output, includeSource.data(), *size - 2);
  25. output[*size - 2] = 0;
  26. output[*size - 1] = 0;
  27. int linkSize = sizeof(IncludeLink) + sizeof(IncludeData) + filenameLen + 1;
  28. char* linkData = (char*)mmalloc(state->memContext, linkSize);
  29. IncludeLink* newLink = (IncludeLink*)linkData;
  30. linkData += sizeof(IncludeLink);
  31. IncludeData* includeData = (IncludeData*)linkData;
  32. linkData += sizeof(IncludeData);
  33. memcpy(linkData, filenameNoQuote, filenameLen);
  34. linkData[filenameLen] = '\0';
  35. includeData->filename = linkData;
  36. includeData->buffer = output;
  37. newLink->data = includeData;
  38. newLink->next = state->includeStack;
  39. state->includeStack = newLink;
  40. mmfree(filenameNoQuote);
  41. return output;
  42. }
  43. const char* errorLabel = "Error opening include file: ";
  44. int labelLen = (int)strlen(errorLabel);
  45. int messageLen = filenameLen + labelLen + 1;
  46. char* message = (char*)mmalloc(state->memContext, messageLen);
  47. memcpy(message, errorLabel, labelLen);
  48. memcpy(message + labelLen, filenameNoQuote, filenameLen);
  49. message[messageLen - 1] = '\0';
  50. state->hasError = 1;
  51. state->errorLine = line;
  52. state->errorColumn = column;
  53. state->errorMessage = message;
  54. state->errorFile = getCurrentFilename(state);
  55. mmfree(filenameNoQuote);
  56. return nullptr;
  57. }
  58. void includePop(ParseState* state)
  59. {
  60. IncludeLink* current = state->includeStack;
  61. if (!current)
  62. return;
  63. state->includeStack = current->next;
  64. current->next = state->includes;
  65. state->includes = current;
  66. mmfree(current->data->buffer);
  67. current->data->buffer = nullptr;
  68. }