blob: 9400b352dca9021f1622b2b76c556d4790fbb7eb (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
// -*- c++ -*-
// Distributed under the BSD 2-Clause License.
// See accompanying file LICENSE for details.
#include "deps.h"
#include "util.h"
#include <fstream>
namespace {
/* Format example:
build/src/libctor_a-libctor_cc.o: src/libctor.cc \
src/getoptpp/getoptpp.hpp src/ctor.h src/configure.h src/rebuild.h \
src/A\ B\ C.h src/task.h src/build.h src/unittest.h
*/
std::vector<std::string> readDepsMake(const std::string& dep_file)
{
auto str = readFile(dep_file);
std::vector<std::string> output;
std::string tmp;
enum class State
{
pre_colon,
post_colon,
in_escape,
} state{State::pre_colon};
auto old_state{state};
for(const auto& c : str)
{
if(c == '\r')
{
// just always ignore windows extra newline char
continue;
}
switch(state)
{
case State::pre_colon:
if(c == ':') // ignore everything until the colon
{
state = State::post_colon;
continue;
}
continue;
case State::post_colon:
if(c == '\n')
{
// done
if(!tmp.empty())
{
output.emplace_back(tmp);
}
return output;
}
if(c == '\\')
{
old_state = state;
state = State::in_escape;
continue;
}
if(c == '\t' || c == ' ') // new token
{
if(!tmp.empty())
{
output.emplace_back(tmp);
}
tmp.clear();
continue;
}
break;
case State::in_escape:
if(c == '\n')
{
// linewrap
state = old_state;
continue;
}
state = old_state;
break;
}
tmp += c;
}
if(!tmp.empty())
{
output.emplace_back(tmp);
}
return output;
}
}
std::vector<std::string> readDeps(const std::string& dep_file,
ctor::toolchain toolchain)
{
if(!std::filesystem::exists(dep_file))
{
return {};
}
switch(toolchain)
{
case ctor::toolchain::any:
case ctor::toolchain::none:
return {};
// makefile .d file based:
case ctor::toolchain::gcc:
case ctor::toolchain::clang:
return readDepsMake(dep_file);
}
return {};
}
|