1 //===-- ResourceScriptCppFilter.cpp ----------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===---------------------------------------------------------------------===//
9 // This file implements an interface defined in ResourceScriptCppFilter.h.
11 //===---------------------------------------------------------------------===//
13 #include "ResourceScriptCppFilter.h"
14 #include "llvm/ADT/StringExtras.h"
24 explicit Filter(StringRef Input
) : Data(Input
), DataLength(Input
.size()) {}
29 // Parse the line, returning whether the line should be included in
31 bool parseLine(StringRef Line
);
33 bool streamEof() const;
39 bool Outputting
= true;
42 std::string
Filter::run() {
43 std::vector
<StringRef
> Output
;
45 while (!streamEof() && Pos
!= StringRef::npos
) {
46 size_t LineStart
= Pos
;
47 Pos
= Data
.find_first_of("\r\n", Pos
);
48 Pos
= Data
.find_first_not_of("\r\n", Pos
);
49 StringRef Line
= Data
.take_front(Pos
).drop_front(LineStart
);
52 Output
.push_back(Line
);
55 return llvm::join(Output
, "");
58 bool Filter::parseLine(StringRef Line
) {
61 if (!Line
.consume_front("#")) {
62 // A normal content line, filtered according to the current mode.
66 // Found a preprocessing directive line. From here on, we always return
67 // false since the preprocessing directives should be filtered out.
69 Line
.consume_front("line");
70 if (!Line
.startswith(" "))
71 return false; // Not a line directive (pragma etc).
73 // #line 123 "path/file.h"
74 // # 123 "path/file.h" 1
77 Line
.ltrim(); // There could be multiple spaces after the #line directive
80 if (Line
.consumeInteger(10, N
)) // Returns true to signify an error
85 if (!Line
.consume_front("\""))
86 return false; // Malformed line, no quote found.
88 // Split the string at the last quote (in case the path name had
89 // escaped quotes as well).
90 Line
= Line
.rsplit('"').first
;
92 StringRef Ext
= Line
.rsplit('.').second
;
94 if (Ext
.equals_lower("h") || Ext
.equals_lower("c")) {
103 bool Filter::streamEof() const { return Pos
== DataLength
; }
105 } // anonymous namespace
109 std::string
filterCppOutput(StringRef Input
) { return Filter(Input
).run(); }