Coverage Report

Created: 2025-07-04 07:23

/src/shaderc/libshaderc_util/src/io_shaderc.cc
Line
Count
Source (jump to first uncovered line)
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 "libshaderc_util/io_shaderc.h"
16
17
#include "libshaderc_util/universal_unistd.h"
18
19
#if _WIN32
20
// Need _fileno from stdio.h
21
// Need _O_BINARY and _O_TEXT from fcntl.h
22
#include <fcntl.h>
23
#include <stdio.h>
24
#endif
25
26
#include <errno.h>
27
28
#include <cstdio>
29
#include <cstring>
30
#include <fstream>
31
#include <iostream>
32
33
namespace {
34
35
// Outputs a descriptive message for errno_value to cerr.
36
// This may be truncated to 1023 bytes on certain platforms.
37
0
void OutputFileErrorMessage(int errno_value) {
38
#ifdef _MSC_VER
39
  // If the error message is more than 1023 bytes it will be truncated.
40
  char buffer[1024];
41
  strerror_s(buffer, errno_value);
42
  std::cerr << ": " << buffer << std::endl;
43
#else
44
0
  std::cerr << ": " << strerror(errno_value) << std::endl;
45
0
#endif
46
0
}
47
48
}  // anonymous namespace
49
50
namespace shaderc_util {
51
52
0
bool IsAbsolutePath(const std::string& path) {
53
0
  if (path.empty()) return false;
54
  // Unix-like OS: /path/to/file
55
0
  if (path.front() == '/') return true;
56
  // Windows: \\server\user\file
57
0
  if (path.size() > 1 && path[0] == '\\' && path[1] == '\\') {
58
0
    return true;
59
0
  }
60
  // Windows: X:\path\to\file
61
0
  if (path.size() > 2 && ::isalpha(path[0]) && path[1] == ':' &&
62
0
      path[2] == '\\') {
63
0
    return true;
64
0
  }
65
0
  return false;
66
0
}
67
68
0
std::string GetBaseFileName(const std::string& file_path) {
69
0
  size_t loc_slash = file_path.find_last_of("/\\");
70
0
  std::string base_name =
71
0
      file_path.substr((loc_slash == std::string::npos ? -1 : loc_slash) + 1);
72
0
  if (base_name == ".." || base_name == ".") {
73
0
    base_name = "";
74
0
  }
75
0
  return base_name;
76
0
}
77
78
bool ReadFile(const std::string& input_file_name,
79
45.4k
              std::vector<char>* input_data) {
80
45.4k
  std::istream* stream = &std::cin;
81
45.4k
  std::ifstream input_file;
82
45.4k
  if (input_file_name != "-") {
83
45.4k
    input_file.open(input_file_name, std::ios_base::binary);
84
45.4k
    stream = &input_file;
85
45.4k
    if (input_file.fail()) {
86
0
      std::cerr << "glslc: error: cannot open input file: '" << input_file_name
87
0
                << "'";
88
0
      if (access(input_file_name.c_str(), R_OK) != 0) {
89
0
        OutputFileErrorMessage(errno);
90
0
        return false;
91
0
      }
92
0
      std::cerr << std::endl;
93
0
      return false;
94
0
    }
95
45.4k
  }
96
45.4k
  *input_data = std::vector<char>((std::istreambuf_iterator<char>(*stream)),
97
45.4k
                                  std::istreambuf_iterator<char>());
98
45.4k
  return true;
99
45.4k
}
100
101
std::ostream* GetOutputStream(const string_piece& output_filename,
102
9.58k
                              std::ofstream* file_stream, std::ostream* err) {
103
9.58k
  std::ostream* stream = &std::cout;
104
9.58k
  if (output_filename != "-") {
105
0
    file_stream->open(output_filename.str(), std::ios_base::binary);
106
0
    stream = file_stream;
107
0
    if (file_stream->fail()) {
108
0
      *err << "glslc: error: cannot open output file: '" << output_filename
109
0
           << "'";
110
0
      if (access(output_filename.str().c_str(), W_OK) != 0) {
111
0
        OutputFileErrorMessage(errno);
112
0
        return nullptr;
113
0
      }
114
0
      std::cerr << std::endl;
115
0
      return nullptr;
116
0
    }
117
0
  }
118
9.58k
  return stream;
119
9.58k
}
120
121
0
bool WriteFile(std::ostream* stream, const string_piece& output_data) {
122
0
  if (output_data.size() > 0) {
123
0
    stream->write(output_data.data(), output_data.size());
124
0
    if (!stream->good()) {
125
0
      return false;
126
0
    }
127
0
  }
128
0
  stream->flush();
129
0
  return true;
130
0
}
131
132
0
void FlushAndSetBinaryModeOnStdout() {
133
0
  std::fflush(stdout);
134
#if _WIN32
135
  _setmode(_fileno(stdout), _O_BINARY);
136
#endif
137
0
}
138
139
0
void FlushAndSetTextModeOnStdout() {
140
0
  std::fflush(stdout);
141
#if _WIN32
142
  _setmode(_fileno(stdout), _O_TEXT);
143
#endif
144
0
}
145
146
}  // namespace shaderc_util