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
16using namespace llvm;
17using namespace llvm::cl;
18
19using namespace mcld;
20
21static const size_t MaxOptWidth = 8;  // arbitrary spacing for printOptionDiff
22
23//===----------------------------------------------------------------------===//
24// SearchDirParser
25//===----------------------------------------------------------------------===//
26// parse - Return true on error.
27bool 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
39void 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
55void SearchDirParser::anchor()
56{
57  // do nothing
58}
59
60//===----------------------------------------------------------------------===//
61// parser<mcld::sys::fs::Path>
62//===----------------------------------------------------------------------===//
63bool 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
72void 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
89void parser<mcld::sys::fs::Path>::anchor()
90{
91  // do nothing
92}
93
94//===----------------------------------------------------------------------===//
95// parser<mcld::ZOption>
96//===----------------------------------------------------------------------===//
97bool 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
160void 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
168void parser<mcld::ZOption>::anchor()
169{
170  // do nothing
171}
172
173