summaryrefslogtreecommitdiff
path: root/include/llvm/Tools/CommandLine.h
blob: 76b4e97989cdcc5cd706d4b27e832df6fed19a0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//===-- llvm/Tools/CommandLine.h - Command line parser for tools -*- C++ -*--=//
//
// This class implements a command line argument processor that is useful when
// creating a tool.
//
// This class is defined entirely inline so that you don't have to link to any
// libraries to use this.
//
// TODO: make this extensible by passing in arguments to be read.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TOOLS_COMMANDLINE_H
#define LLVM_TOOLS_COMMANDLINE_H

#include <string>

class ToolCommandLine {
public:
  inline ToolCommandLine(int &argc, char **argv, bool OutputBytecode = true);
  inline ToolCommandLine(const string &infn, const string &outfn = "-");
  inline ToolCommandLine(const ToolCommandLine &O);
  inline ToolCommandLine &operator=(const ToolCommandLine &O);

  inline bool getForce() const { return Force; }
  inline const string getInputFilename() const { return InputFilename; }
  inline const string getOutputFilename() const { return OutputFilename; }

private:
  void calculateOutputFilename(bool OutputBytecode) {
    OutputFilename = InputFilename;
    unsigned Len = OutputFilename.length();

    if (Len <= 3) { 
      OutputFilename += (OutputBytecode ? ".bc" : ".ll"); 
      return; 
    }

    if (OutputBytecode) {
      if (OutputFilename[Len-3] == '.' &&
	  OutputFilename[Len-2] == 'l' &&
	  OutputFilename[Len-1] == 'l') {   // .ll -> .bc	  
	OutputFilename[Len-2] = 'b'; 
	OutputFilename[Len-1] = 'c';
      } else {
	OutputFilename += ".bc";
      }
    } else {
      if (OutputFilename[Len-3] == '.' &&
	  OutputFilename[Len-2] == 'b' &&
	  OutputFilename[Len-1] == 'c') {   // .ll -> .bc	  
	OutputFilename[Len-2] = 'l'; 
	OutputFilename[Len-1] = 'l';
      } else {
	OutputFilename += ".ll";
      }
    }
  }

private:
  string InputFilename;           // Filename to read from.  If "-", use stdin.
  string OutputFilename;          // Filename to write to.   If "-", use stdout.
  bool   Force;                   // Force output (-f argument)
};

inline ToolCommandLine::ToolCommandLine(int &argc, char **argv, bool OutBC) 
  : InputFilename("-"), OutputFilename("-"), Force(false) {
  bool FoundInputFN  = false;
  bool FoundOutputFN = false;
  bool FoundForce    = false;

  for (int i = 1; i < argc; i++) {
    int RemoveArg = 0;
    
    if (argv[i][0] == '-') {
      if (!FoundInputFN && argv[i][1] == 0) { // Is the current argument '-'
	InputFilename = argv[i];
	FoundInputFN = true;
	RemoveArg = 1;
      } else if (!FoundOutputFN && (argv[i][1] == 'o' && argv[i][2] == 0)) {
	// Is the argument -o?
	if (i+1 < argc) {        // Next arg is output fn
	  OutputFilename = argv[i+1];
	  FoundOutputFN = true;
	  RemoveArg = 2;
	}
      } else if (!FoundForce && (argv[i][1] == 'f' && argv[i][2] == 0)) {
	Force = true;
	FoundForce = true;
	RemoveArg = 1;
      }
    } else if (!FoundInputFN) {     // Is the current argument '[^-].*'?
      InputFilename = argv[i];
      FoundInputFN = true;
      RemoveArg = 1;
    }
					    
    if (RemoveArg) {
      argc -= RemoveArg;                           // Shift args over...
      memmove(argv+i, argv+i+RemoveArg, (argc-i)*sizeof(char*));
      i--;                                         // Reprocess this argument...
    }
  }

  if (!FoundOutputFN && InputFilename != "-")
    calculateOutputFilename(OutBC);
}

inline ToolCommandLine::ToolCommandLine(const string &inf, 
                                        const string &outf) 
  : InputFilename(inf), OutputFilename(outf), Force(false) {
}

inline ToolCommandLine::ToolCommandLine(const ToolCommandLine &Opts) 
  : InputFilename(Opts.InputFilename), OutputFilename(Opts.OutputFilename),
    Force(Opts.Force) {
}

inline ToolCommandLine &ToolCommandLine::operator=(const ToolCommandLine &Opts){
  InputFilename  = Opts.InputFilename;
  OutputFilename = Opts.OutputFilename;
  Force          = Opts.Force;
  return *this;
}

#endif