Skip to content

Commit a51e141

Browse files
committed
Add initial -output support, see #48
1 parent dda5c9f commit a51e141

File tree

2 files changed

+64
-24
lines changed

2 files changed

+64
-24
lines changed

source/common.h

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -270,18 +270,20 @@ class cmdline_processor
270270
};
271271
std::vector<arg> args;
272272

273-
using callback = void (*)();
273+
using callback0 = void (*)();
274+
using callback1 = void (*)(std::string const&);
274275
struct flag
275276
{
276277
int group = 0;
277278
std::string name;
278279
int unique_prefix = 0;
279280
std::string description;
280-
callback handler;
281+
callback0 handler0;
282+
callback1 handler1;
281283
std::string synonym;
282284

283-
flag(int g, std::string_view n, std::string_view d, callback h, std::string_view s)
284-
: group{g}, name{n}, description{d}, handler{h}, synonym{s}
285+
flag(int g, std::string_view n, std::string_view d, callback0 h0, callback1 h1, std::string_view s)
286+
: group{g}, name{n}, description{d}, handler0{h0}, handler1{h1}, synonym{s}
285287
{ }
286288
};
287289
std::vector<flag> flags;
@@ -315,42 +317,59 @@ class cmdline_processor
315317
}
316318

317319
// Look for matches
318-
for (auto& arg : args)
320+
for (auto arg = args.begin(); arg != args.end(); ++arg)
319321
{
320322
// The arg should never be empty, but we're going to do a [0]
321323
// subscript next so we should either check or assert
322-
if (arg.text.empty()) {
324+
if (arg->text.empty()) {
323325
continue;
324326
}
325327

326328
// Provide a way to ignore the rest of the command line
327329
// for the purpose of looking for switches
328-
if (arg.text == "--") {
329-
arg.pos = processed;
330+
if (arg->text == "--") {
331+
arg->pos = processed;
330332
break;
331333
}
332334

333335
for (auto& flag : flags) {
334-
auto length_to_match = std::max(flag.unique_prefix, as<int>(arg.text.length())-1);
336+
auto length_to_match = std::max(flag.unique_prefix, as<int>(arg->text.length())-1);
335337
// Allow a switch to start with either - or /
336-
if (arg.text.starts_with("-" + flag.name.substr(0, length_to_match)) ||
337-
arg.text.starts_with("/" + flag.name.substr(0, length_to_match)) ||
338-
arg.text == "-" + flag.synonym ||
339-
arg.text == "/" + flag.synonym
338+
if (arg->text.starts_with("-" + flag.name.substr(0, length_to_match)) ||
339+
arg->text.starts_with("/" + flag.name.substr(0, length_to_match)) ||
340+
arg->text == "-" + flag.synonym ||
341+
arg->text == "/" + flag.synonym
340342
)
341343
{
342-
flag.handler();
343-
arg.pos = processed;
344+
assert(flag.handler0 || flag.handler1);
345+
346+
// If this is a standalone switch, just process it
347+
if (flag.handler0) {
348+
flag.handler0();
349+
}
350+
351+
// Else this is a switch that takes the next arg as its value, so pass that
352+
else {
353+
if (arg+1 == args.end()) {
354+
print("Missing argument to option " + arg->text + " (try -help)\n");
355+
help_requested = true;
356+
}
357+
arg->pos = processed;
358+
++arg; // move to next argument, which is the argument to this switch
359+
flag.handler1(arg->text);
360+
}
361+
362+
arg->pos = processed;
344363
break;
345364
}
346365
}
347366

348367
// For now comment this out to try leaving unmatched switches alone, so that
349368
// Unix absolute filenames work... and in case an absolute filename collides
350369
// with a legit switch name, also added "--" above... let's see how this works
351-
//if (arg.pos != processed && (arg.text.starts_with("-") || arg.text.starts_with("/"))) {
352-
// arg.pos = processed;
353-
// print("Unknown option: " + arg.text + " (try -help)\n");
370+
//if (arg->pos != processed && (arg->text.starts_with("-") || arg->text.starts_with("/"))) {
371+
// arg->pos = processed;
372+
// print("Unknown option: " + arg->text + " (try -help)\n");
354373
// help_requested = true;
355374
//}
356375
}
@@ -391,14 +410,14 @@ class cmdline_processor
391410
}
392411
}
393412

394-
auto add_flag(int group, std::string_view name, std::string_view description, callback handler, std::string_view synonym) {
395-
flags.emplace_back( group, name, description, handler, synonym );
413+
auto add_flag(int group, std::string_view name, std::string_view description, callback0 handler0, callback1 handler1, std::string_view synonym) {
414+
flags.emplace_back( group, name, description, handler0, handler1, synonym );
396415
if (max_flag_length < std::ssize(name)) {
397416
max_flag_length = std::ssize(name);
398417
}
399418
}
400419
struct register_flag {
401-
register_flag(int group, std::string_view name, std::string_view description, callback handler, std::string_view synonym = {});
420+
register_flag(int group, std::string_view name, std::string_view description, callback0 handler0, callback1 handler1 = nullptr, std::string_view synonym = {});
402421
};
403422

404423
auto set_args(int argc, char* argv[]) -> void {
@@ -431,15 +450,16 @@ class cmdline_processor
431450

432451
} cmdline;
433452

434-
cmdline_processor::register_flag::register_flag(int group, std::string_view name, std::string_view description, callback handler, std::string_view synonym) {
435-
cmdline.add_flag( group, name, description, handler, synonym );
453+
cmdline_processor::register_flag::register_flag(int group, std::string_view name, std::string_view description, callback0 handler0, callback1 handler1, std::string_view synonym) {
454+
cmdline.add_flag( group, name, description, handler0, handler1, synonym );
436455
}
437456

438457
static cmdline_processor::register_flag cmd_help (
439458
0,
440459
"help",
441460
"Print help",
442461
[]{ cmdline.print_help(); },
462+
nullptr,
443463
"?"
444464
);
445465

source/cppfront.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,15 @@ static cmdline_processor::register_flag cmd_enable_source_info(
100100
[]{ flag_use_source_location = true; }
101101
);
102102

103+
static auto flag_cpp1_filename = std::string{};
104+
static cmdline_processor::register_flag cmd_cpp1_filename(
105+
2,
106+
"output",
107+
"Output filename (default is *.cpp)",
108+
nullptr,
109+
[](std::string const& name) { flag_cpp1_filename = name; }
110+
);
111+
103112

104113
struct text_with_pos{
105114
std::string text;
@@ -707,10 +716,21 @@ class cppfront
707716
}
708717

709718
// Now we'll open the .cpp file
719+
auto cpp1_filename = sourcefile.substr(0, std::ssize(sourcefile) - 1);
720+
if (!flag_cpp1_filename.empty()) {
721+
cpp1_filename = flag_cpp1_filename; // use override if present
722+
}
710723
printer.open(
711-
sourcefile.substr(0, std::ssize(sourcefile) - 1),
724+
cpp1_filename,
712725
tokens.get_comments()
713726
);
727+
if (!printer.is_open()) {
728+
errors.emplace_back(
729+
source_position{},
730+
"could not open output file " + cpp1_filename
731+
);
732+
return;
733+
}
714734

715735
// Only emit extra lines if we actually have Cpp2, because
716736
// we want pure-Cpp1 files to pass through with zero changes

0 commit comments

Comments
 (0)