1 //===- CommandLine.cpp ----------------------------------------------------===//
2 //
3 //                     The MCLinker Project
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #include <mcld/Support/CommandLine.h>
10 
11 #include <llvm/ADT/StringRef.h>
12 #include <llvm/ADT/Twine.h>
13 #include <llvm/ADT/StringSwitch.h>
14 #include <llvm/Support/ErrorHandling.h>
15 
16 using namespace llvm;
17 using namespace llvm::cl;
18 
19 using namespace mcld;
20 
21 static const size_t MaxOptWidth = 8;  // arbitrary spacing for printOptionDiff
22 
23 //===----------------------------------------------------------------------===//
24 // SearchDirParser
25 //===----------------------------------------------------------------------===//
26 // parse - Return true on error.
parse(Option & pOption,StringRef pArgName,StringRef pArg,std::string & pValue)27 bool SearchDirParser::parse(Option &pOption,
28                             StringRef pArgName,
29                             StringRef pArg,
30                             std::string &pValue)
31 {
32   char separator = *(pArgName.data() + 1);
33   if ('=' == separator)
34     pValue = '=';
35   pValue += pArg.str();
36   return false;
37 }
38 
printOptionDiff(const Option & pOption,StringRef pValue,OptVal pDefault,size_t pGlobalWidth) const39 void SearchDirParser::printOptionDiff(const Option &pOption,
40                                       StringRef pValue,
41                                       OptVal pDefault,
42                                       size_t pGlobalWidth) const
43 {
44   printOptionName(pOption, pGlobalWidth);
45   outs() << "= " << pValue;
46   size_t NumSpaces = MaxOptWidth > pValue.size()?MaxOptWidth - pValue.size():0;
47   outs().indent(NumSpaces) << " (default: ";
48   if (pDefault.hasValue())
49     outs() << pDefault.getValue();
50   else
51     outs() << "*no default*";
52   outs() << ")\n";
53 }
54 
anchor()55 void SearchDirParser::anchor()
56 {
57   // do nothing
58 }
59 
60 //===----------------------------------------------------------------------===//
61 // parser<mcld::sys::fs::Path>
62 //===----------------------------------------------------------------------===//
parse(llvm::cl::Option & O,llvm::StringRef ArgName,llvm::StringRef Arg,mcld::sys::fs::Path & Val)63 bool parser<mcld::sys::fs::Path>::parse(llvm::cl::Option &O,
64                        llvm::StringRef ArgName,
65                        llvm::StringRef Arg,
66                        mcld::sys::fs::Path &Val)
67 {
68   Val.assign<llvm::StringRef::const_iterator>(Arg.begin(), Arg.end());
69   return false;
70 }
71 
printOptionDiff(const llvm::cl::Option & O,const mcld::sys::fs::Path & V,parser<mcld::sys::fs::Path>::OptVal Default,size_t GlobalWidth) const72 void parser<mcld::sys::fs::Path>::printOptionDiff(const llvm::cl::Option &O,
73                                                   const mcld::sys::fs::Path &V,
74                                                   parser<mcld::sys::fs::Path>::OptVal Default,
75                                                   size_t GlobalWidth) const
76 {
77   printOptionName(O, GlobalWidth);
78   outs() << "= " << V;
79   size_t VSize = V.native().size();
80   size_t NumSpaces = MaxOptWidth > VSize ? MaxOptWidth - VSize : 0;
81   outs().indent(NumSpaces) << " (default: ";
82   if (Default.hasValue())
83     outs() << Default.getValue().c_str();
84   else
85     outs() << "*no default*";
86   outs() << ")\n";
87 }
88 
anchor()89 void parser<mcld::sys::fs::Path>::anchor()
90 {
91   // do nothing
92 }
93 
94 //===----------------------------------------------------------------------===//
95 // parser<mcld::ZOption>
96 //===----------------------------------------------------------------------===//
parse(llvm::cl::Option & O,llvm::StringRef ArgName,llvm::StringRef Arg,mcld::ZOption & Val)97 bool parser<mcld::ZOption>::parse(llvm::cl::Option &O,
98                                   llvm::StringRef ArgName,
99                                   llvm::StringRef Arg,
100                                   mcld::ZOption &Val)
101 {
102   if (0 == Arg.compare("combreloc"))
103     Val.setKind(ZOption::CombReloc);
104   else if (0 == Arg.compare("nocombreloc"))
105     Val.setKind(ZOption::NoCombReloc);
106   else if (0 == Arg.compare("defs"))
107     Val.setKind(ZOption::Defs);
108   else if (0 == Arg.compare("execstack"))
109     Val.setKind(ZOption::ExecStack);
110   else if (0 == Arg.compare("noexecstack"))
111     Val.setKind(ZOption::NoExecStack);
112   else if (0 == Arg.compare("initfirst"))
113     Val.setKind(ZOption::InitFirst);
114   else if (0 == Arg.compare("interpose"))
115     Val.setKind(ZOption::InterPose);
116   else if (0 == Arg.compare("loadfltr"))
117     Val.setKind(ZOption::LoadFltr);
118   else if (0 == Arg.compare("muldefs"))
119     Val.setKind(ZOption::MulDefs);
120   else if (0 == Arg.compare("nocopyreloc"))
121     Val.setKind(ZOption::NoCopyReloc);
122   else if (0 == Arg.compare("nodefaultlib"))
123     Val.setKind(ZOption::NoDefaultLib);
124   else if (0 == Arg.compare("nodelete"))
125     Val.setKind(ZOption::NoDelete);
126   else if (0 == Arg.compare("nodlopen"))
127     Val.setKind(ZOption::NoDLOpen);
128   else if (0 == Arg.compare("nodump"))
129     Val.setKind(ZOption::NoDump);
130   else if (0 == Arg.compare("relro"))
131     Val.setKind(ZOption::Relro);
132   else if (0 == Arg.compare("norelro"))
133     Val.setKind(ZOption::NoRelro);
134   else if (0 == Arg.compare("lazy"))
135     Val.setKind(ZOption::Lazy);
136   else if (0 == Arg.compare("now"))
137     Val.setKind(ZOption::Now);
138   else if (0 == Arg.compare("origin"))
139     Val.setKind(ZOption::Origin);
140   else if (Arg.startswith("common-page-size=")) {
141     Val.setKind(ZOption::CommPageSize);
142     long long unsigned size = 0;
143     Arg.drop_front(17).getAsInteger(0, size);
144     Val.setPageSize(static_cast<uint64_t>(size));
145   }
146   else if (Arg.startswith("max-page-size=")) {
147     Val.setKind(ZOption::MaxPageSize);
148     long long unsigned size = 0;
149     Arg.drop_front(14).getAsInteger(0, size);
150     Val.setPageSize(static_cast<uint64_t>(size));
151   }
152 
153   if (ZOption::Unknown == Val.kind())
154     llvm::report_fatal_error(llvm::Twine("unknown -z option: `") +
155                              Arg +
156                              llvm::Twine("'\n"));
157   return false;
158 }
159 
printOptionDiff(const llvm::cl::Option & O,const mcld::ZOption & V,parser<mcld::ZOption>::OptVal Default,size_t GlobalWidth) const160 void parser<mcld::ZOption>::printOptionDiff(const llvm::cl::Option &O,
161                                             const mcld::ZOption &V,
162                                             parser<mcld::ZOption>::OptVal Default,
163                                             size_t GlobalWidth) const
164 {
165   // TODO
166 }
167 
anchor()168 void parser<mcld::ZOption>::anchor()
169 {
170   // do nothing
171 }
172 
173