about summary refs log tree commit diff stats
path: root/subx/028translate.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-09-30 22:49:24 -0700
committerKartik Agaram <vc@akkartik.com>2018-09-30 23:12:54 -0700
commit1dcd9350ce975fb05ed99a5ffc864b0d65c8bab3 (patch)
tree14ae2237d5b164ef7db4604567cd29b3b32cfa73 /subx/028translate.cc
parent2e693f723de721fff35f74ef1194132d48222615 (diff)
downloadmu-1dcd9350ce975fb05ed99a5ffc864b0d65c8bab3.tar.gz
4624
Start requiring a '-o' flag to designate the output binary when translating.

Things currently get funky if you pass in multiple inputs, but that's ok.
This is the first step to supporting multiple input files for a single
output binary.
Diffstat (limited to 'subx/028translate.cc')
-rw-r--r--subx/028translate.cc49
1 files changed, 38 insertions, 11 deletions
diff --git a/subx/028translate.cc b/subx/028translate.cc
index 174a863a..303d6219 100644
--- a/subx/028translate.cc
+++ b/subx/028translate.cc
@@ -19,30 +19,57 @@
 :(before "End Main")
 if (is_equal(argv[1], "translate")) {
   START_TRACING_UNTIL_END_OF_SCOPE;
-  assert(argc > 3);
   reset();
   program p;
-  ifstream fin(argv[2]);
-  if (!fin) {
-    cerr << "could not open " << argv[2] << '\n';
-    return 1;
+  string output_filename;
+  for (int i = /*skip 'subx translate'*/2;  i < argc;  ++i) {
+    if (is_equal(argv[i], "-o")) {
+      ++i;
+      if (i >= argc) {
+        print_translate_usage();
+        cerr << "'-o' must be followed by a filename to write results to\n";
+        exit(1);
+      }
+      output_filename = argv[i];
+    }
+    else {
+      ifstream fin(argv[i]);
+      if (!fin) {
+        cerr << "could not open " << argv[i] << '\n';
+        return 1;
+      }
+      parse(fin, p);
+      if (trace_contains_errors()) return 1;
+    }
+  }
+  if (p.segments.empty()) {
+    print_translate_usage();
+    cerr << "nothing to do; must provide at least one file to read\n";
+    exit(1);
+  }
+  if (output_filename.empty()) {
+    print_translate_usage();
+    cerr << "must provide a filename to write to using '-o'\n";
+    exit(1);
   }
-  parse(fin, p);
-  if (trace_contains_errors()) return 1;
   transform(p);
   if (trace_contains_errors()) return 1;
-  save_elf(p, argv[3]);
+  save_elf(p, output_filename);
   if (trace_contains_errors()) {
-    unlink(argv[3]);
+    unlink(output_filename.c_str());
     return 1;
   }
   return 0;
 }
 
 :(code)
+void print_translate_usage() {
+  cerr << "Usage: subx translate <input.subx> -o <output_ELF>\n";
+}
+
 // write out a program to a bare-bones ELF file
-void save_elf(const program& p, const char* filename) {
-  ofstream out(filename, ios::binary);
+void save_elf(const program& p, const string& filename) {
+  ofstream out(filename.c_str(), ios::binary);
   write_elf_header(out, p);
   for (size_t i = 0;  i < p.segments.size();  ++i)
     write_segment(p.segments.at(i), out);