Skip to content

Commit c0dd050

Browse files
vanceism7hsutter
andauthored
Feat: Add ability to compile from stdin (#1327)
* Implement ability to compile directly from stdin * Add doc comment to process_cpp2 function * Move choice between file or stdin to source.load() * Add a little comment above source loading decision * Don't file-open `stdin` * Fixed logic, and added default to stdout if stdin is used Also: - re-ran self-build and regression tests - suppressed non-error output when stdout is used, so piping is easier --------- Co-authored-by: Herb Sutter <[email protected]>
1 parent 6b3934b commit c0dd050

File tree

4 files changed

+32
-11
lines changed

4 files changed

+32
-11
lines changed

source/common.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,9 @@ class cmdline_processor
799799
[](auto& a, auto& b){ return a.group < b.group || (a.group == b.group && a.name < b.name); }
800800
);
801801

802-
print("\nUsage: cppfront [options] file ...\n\nOptions:\n");
802+
print("\nUsage: cppfront [options] file ...\n");
803+
print("\n file source file(s) (can be 'stdin')\n");
804+
print("\nOptions: \n");
803805
int last_group = -1;
804806
for (auto& flag : flags) {
805807
// Skip hidden flags

source/cppfront.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,12 @@ auto main(
7979

8080
auto& out = flag_cpp1_filename != "stdout" ? std::cout : std::cerr;
8181

82-
if (!flag_quiet) {
82+
if (
83+
!flag_quiet
84+
&& arg.text != "stdin"
85+
&& flag_cpp1_filename != "stdout"
86+
)
87+
{
8388
out << arg.text << "...";
8489
}
8590

@@ -92,7 +97,10 @@ auto main(
9297
// If there were no errors, say so and generate Cpp1
9398
if (c.had_no_errors())
9499
{
95-
if (!flag_quiet)
100+
if (
101+
!flag_quiet
102+
&& flag_cpp1_filename != "stdout"
103+
)
96104
{
97105
if (!c.has_cpp1()) {
98106
out << " ok (all Cpp2, passes safety checks)\n";

source/io.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -882,11 +882,17 @@ class source
882882
)
883883
-> bool
884884
{
885-
std::ifstream in{ filename };
886-
if (!in.is_open()) {
887-
return false;
885+
// If filename is stdin, we read from stdin, otherwise we try to read the file
886+
//
887+
auto is_stdin = filename == "stdin";
888+
std::ifstream fss;
889+
if (!is_stdin)
890+
{
891+
fss.open(filename);
892+
if( !fss.is_open()) { return false; }
888893
}
889-
894+
std::istream& in = is_stdin ? std::cin : fss;
895+
890896
auto in_comment = false;
891897
auto in_string_literal = false;
892898
auto in_raw_string_literal = false;

source/to_cpp1.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,7 @@ class cppfront
11791179
if (
11801180
!sourcefile.ends_with(".cpp2")
11811181
&& !sourcefile.ends_with(".h2")
1182+
&& sourcefile != "stdin"
11821183
)
11831184
{
11841185
errors.emplace_back(
@@ -1257,14 +1258,18 @@ class cppfront
12571258
}
12581259

12591260
// Now we'll open the Cpp1 file
1260-
auto cpp1_filename = sourcefile.substr(0, std::ssize(sourcefile) - 1);
1261+
// Default to stdout if input is stdin
1262+
auto cpp1_filename = std::string{"stdout"};
1263+
if (sourcefile != "stdin") {
1264+
assert(sourcefile.ends_with("2"));
1265+
cpp1_filename = sourcefile.substr(0, std::ssize(sourcefile) - 1);
1266+
}
12611267

1262-
// Use explicit filename override if present,
1263-
// otherwise strip leading path
1268+
// Use explicit filename override if present, otherwise strip leading path
12641269
if (!flag_cpp1_filename.empty()) {
12651270
cpp1_filename = flag_cpp1_filename;
12661271
}
1267-
else {
1272+
else if (cpp1_filename != "stdout") {
12681273
cpp1_filename = std::filesystem::path(cpp1_filename).filename().string();
12691274
}
12701275

0 commit comments

Comments
 (0)