1 // Copyright 2015 The Shaderc Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "file_includer.h"
16 
17 #include <mutex>
18 #include <utility>
19 
20 #include "libshaderc_util/io.h"
21 
22 namespace glslc {
23 
MakeErrorIncludeResult(const char * message)24 shaderc_include_result* MakeErrorIncludeResult(const char* message) {
25   return new shaderc_include_result{"", 0, message, strlen(message)};
26 }
27 
28 FileIncluder::~FileIncluder() = default;
29 
GetInclude(const char * requested_source,shaderc_include_type include_type,const char * requesting_source,size_t)30 shaderc_include_result* FileIncluder::GetInclude(
31     const char* requested_source, shaderc_include_type include_type,
32     const char* requesting_source, size_t) {
33 
34   const std::string full_path =
35       (include_type == shaderc_include_type_relative)
36           ? file_finder_.FindRelativeReadableFilepath(requesting_source,
37                                                       requested_source)
38           : file_finder_.FindReadableFilepath(requested_source);
39 
40   if (full_path.empty())
41     return MakeErrorIncludeResult("Cannot find or open include file.");
42 
43   // In principle, several threads could be resolving includes at the same
44   // time.  Protect the included_files.
45 
46   // Read the file and save its full path and contents into stable addresses.
47   FileInfo* new_file_info = new FileInfo{full_path, {}};
48   if (!shaderc_util::ReadFile(full_path, &(new_file_info->contents))) {
49     return MakeErrorIncludeResult("Cannot read file");
50   }
51 
52   included_files_.insert(full_path);
53 
54   return new shaderc_include_result{
55       new_file_info->full_path.data(), new_file_info->full_path.length(),
56       new_file_info->contents.data(), new_file_info->contents.size(),
57       new_file_info};
58 }
59 
ReleaseInclude(shaderc_include_result * include_result)60 void FileIncluder::ReleaseInclude(shaderc_include_result* include_result) {
61   FileInfo* info = static_cast<FileInfo*>(include_result->user_data);
62   delete info;
63   delete include_result;
64 }
65 
66 }  // namespace glslc
67