Large scale changes to implement new command line argument facility


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp
index deaf3a2..f243baa 100644
--- a/tools/llvm-dis/llvm-dis.cpp
+++ b/tools/llvm-dis/llvm-dis.cpp
@@ -25,69 +25,67 @@
 #include "llvm/Method.h"
 #include "llvm/CFG.h"
 
+// OutputMode - The different orderings to print basic blocks in...
+enum OutputMode {
+  Default = 0,           // Method Order (list order)
+  dfo,                   // Depth First ordering
+  rdfo,                  // Reverse Depth First ordering
+  po,                    // Post Order
+  rpo,                   // Reverse Post Order
+};
+
+cl::String InputFilename ("", "Load <arg> file, print as assembly", 0, "-");
+cl::String OutputFilename("o", "Override output filename", 0, "");
+cl::Flag   Force         ("f", "Overwrite output files", 0, false);
+cl::EnumFlags<enum OutputMode> WriteMode(cl::NoFlags,
+  clEnumVal(Default, "Write bb's in bytecode order"),
+  clEnumVal(dfo    , "Write bb's in depth first order"),
+  clEnumVal(rdfo   , "Write bb's in reverse DFO"),
+  clEnumVal(po     , "Write bb's in postorder"),
+  clEnumVal(rpo    , "Write bb's in reverse postorder"), 0);
+
 int main(int argc, char **argv) {
-  // WriteMode - The different orderings to print basic blocks in...
-  enum {
-    Default = 0,                  // Method Order (list order)
-    DepthFirst,                   // Depth First ordering
-    ReverseDepthFirst,            // Reverse Depth First ordering
-    PostOrder,                    // Post Order
-    ReversePostOrder              // Reverse Post Order
-  } WriteMode = Default;
-
-  ToolCommandLine Opts(argc, argv, false);
-
-  // We only support the options that the system parser does... if it left any
-  // then we don't know what to do.
-  //
-  if (argc > 1) {
-    for (int i = 1; i < argc; i++) {
-      if (string(argv[i]) == string("--help")) {
-	cerr << argv[0] << " usage:\n"
-	     << "\tx.bc        - Parse <x.bc> file and output to x.ll\n"
-	     << "\tno .bc file - Parse stdin and write to stdout.\n"
-	     << "\t-dfo        - Write basic blocks in depth first order.\n"
-	     << "\t-rdfo       - Write basic blocks in reverse DFO.\n"
-	     << "\t-po         - Write basic blocks in postorder.\n"
-	     << "\t-rpo        - Write basic blocks in reverse postorder.\n"
-	     << "\t--help      - Print this usage information\n\n";
-	return 1;
-      } else if (string(argv[i]) == string("-dfo")) {
-	WriteMode = DepthFirst;
-      } else if (string(argv[i]) == string("-rdfo")) {
-	WriteMode = ReverseDepthFirst;
-      } else if (string(argv[i]) == string("-po")) {
-	WriteMode = PostOrder;
-      } else if (string(argv[i]) == string("-rpo")) {
-	WriteMode = ReversePostOrder;
-      } else {
-	cerr << argv[0] << ": argument not recognized: '" << argv[i] << "'!\n";
-      }
-    }
-  }
-  
+  cl::ParseCommandLineOptions(argc, argv, " llvm .bc -> .ll disassembler\n");
   ostream *Out = &cout;  // Default to printing to stdout...
 
-  Module *C = ParseBytecodeFile(Opts.getInputFilename());
+  Module *C = ParseBytecodeFile(InputFilename.getValue());
   if (C == 0) {
     cerr << "bytecode didn't read correctly.\n";
     return 1;
   }
   
-  if (Opts.getOutputFilename() != "-") {
-    Out = new ofstream(Opts.getOutputFilename().c_str(), 
-                       (Opts.getForce() ? 0 : ios::noreplace)|ios::out);
-    if (!Out->good()) {
-      cerr << "Error opening " << Opts.getOutputFilename() 
-           << ": sending to stdout instead!\n";
+  if (OutputFilename.getValue() != "") {   // Specified an output filename?
+    Out = new ofstream(OutputFilename.getValue().c_str(), 
+		       (Force.getValue() ? 0 : ios::noreplace)|ios::out);
+  } else {
+    if (InputFilename.getValue() == "-") {
+      OutputFilename.setValue("-");
       Out = &cout;
+    } else {
+      string IFN = InputFilename.getValue();
+      int Len = IFN.length();
+      if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
+	// Source ends in .bc
+	OutputFilename.setValue(string(IFN.begin(), IFN.end()-3));
+      } else {
+	OutputFilename.setValue(IFN);   // Append a .ll to it
       }
+      OutputFilename.setValue(OutputFilename.getValue() + ".ll");
+      Out = new ofstream(OutputFilename.getValue().c_str(), 
+			 (Force.getValue() ? 0 : ios::noreplace)|ios::out);
+    }
   }
-    
+
+  if (!Out->good()) {
+    cerr << "Error opening " << OutputFilename.getValue() 
+	 << ": sending to stdout instead!\n";
+    Out = &cout;
+  }
+
   // All that dis does is write the assembly out to a file... which is exactly
   // what the writer library is supposed to do...
   //
-  if (WriteMode == Default) {
+  if (WriteMode.getValue() == Default) {
     (*Out) << C;           // Print out in list order
   } else {
     // TODO: This does not print anything other than the basic blocks in the
@@ -98,20 +96,20 @@
       Method *M = *I;
       (*Out) << "-------------- Method: " << M->getName() << " -------------\n";
 
-      switch (WriteMode) {
-      case DepthFirst:                   // Depth First ordering
+      switch (WriteMode.getValue()) {
+      case dfo:                   // Depth First ordering
 	copy(cfg::df_begin(M), cfg::df_end(M),
 	     ostream_iterator<BasicBlock*>(*Out, "\n"));
 	break;
-      case ReverseDepthFirst:            // Reverse Depth First ordering
+      case rdfo:            // Reverse Depth First ordering
 	copy(cfg::df_begin(M, true), cfg::df_end(M),
 	     ostream_iterator<BasicBlock*>(*Out, "\n"));
 	break;
-      case PostOrder:                    // Post Order
+      case po:                    // Post Order
 	copy(cfg::po_begin(M), cfg::po_end(M),
 	     ostream_iterator<BasicBlock*>(*Out, "\n"));
 	break;
-      case ReversePostOrder: {           // Reverse Post Order
+      case rpo: {           // Reverse Post Order
 	cfg::ReversePostOrderTraversal RPOT(M);
 	copy(RPOT.begin(), RPOT.end(),
 	     ostream_iterator<BasicBlock*>(*Out, "\n"));