1533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines//===- PreferenceOptions.cpp ----------------------------------------------===//
2533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines//
3533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines//                     The MCLinker Project
4533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines//
5533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines// This file is distributed under the University of Illinois Open Source
6533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines// License. See LICENSE.TXT for details.
7533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines//
8533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines//===----------------------------------------------------------------------===//
9533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/PreferenceOptions.h>
10533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/LinkerConfig.h>
11533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/Support/CommandLine.h>
12533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/Support/raw_ostream.h>
13533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <llvm/Support/Process.h>
14533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
15533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#if defined(HAVE_UNISTD_H)
16533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines# include <unistd.h>
17533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#endif
18533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
19533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#if defined(_MSC_VER) || defined(__MINGW32__)
20533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <io.h>
21533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#ifndef STDIN_FILENO
22533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines# define STDIN_FILENO 0
23533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#endif
24533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#ifndef STDOUT_FILENO
25533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines# define STDOUT_FILENO 1
26533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#endif
27533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#ifndef STDERR_FILENO
28533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines# define STDERR_FILENO 2
29533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#endif
30533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#endif
31533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
32533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesnamespace {
33533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
34533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesllvm::cl::opt<bool> ArgTrace("t",
35533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::desc("Print the names of the input files as ld processes them."));
36533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
37533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesllvm::cl::alias ArgTraceAlias("trace",
38533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::desc("alias for -t"),
39533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::aliasopt(ArgTrace));
40533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
41533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesllvm::cl::opt<int> ArgVerbose("verbose",
42533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::init(-1),
43533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::desc("Display the version number for ld and list the\n"
44533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                 "linker emulations supported."));
45533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
46533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesllvm::cl::opt<bool> ArgVersion("V",
47533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::init(false),
48533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::desc("Display the version number for MCLinker."));
49533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
50533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesllvm::cl::opt<int> ArgMaxErrorNum("error-limit",
51533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::init(-1),
52533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::desc("limits the maximum number of erros."));
53533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
54533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesllvm::cl::opt<int> ArgMaxWarnNum("warning-limit",
55533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::init(-1),
56533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::desc("limits the maximum number of warnings."));
57533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
58533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesllvm::cl::opt<mcld::PreferenceOptions::Color> ArgColor("color",
59533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::value_desc("When"),
60533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::desc("Surround the result strings with the marker"),
61533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::init(mcld::PreferenceOptions::COLOR_Auto),
62533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::values(
63533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    clEnumValN(mcld::PreferenceOptions::COLOR_Never, "never",
64533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines      "do not surround result"),
65533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    clEnumValN(mcld::PreferenceOptions::COLOR_Always, "always",
66533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines      "always surround results, even the output is a plain file"),
67533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    clEnumValN(mcld::PreferenceOptions::COLOR_Auto, "auto",
68533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines      "surround result strings only if the output is a tty"),
69533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    clEnumValEnd));
70533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
71533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesllvm::cl::opt<bool> ArgPrintMap("M",
72533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::desc("Print a link map to the standard output."),
73533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::init(false));
74533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
75533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesllvm::cl::alias ArgPrintMapAlias("print-map",
76533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::desc("alias for -M"),
77533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::aliasopt(ArgPrintMap));
78533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
79533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesbool ArgFatalWarnings;
80533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
81533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesllvm::cl::opt<bool, true, llvm::cl::FalseParser> ArgNoFatalWarnings("no-fatal-warnings",
82533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::location(ArgFatalWarnings),
83533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::desc("do not turn warnings into errors"),
84533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::init(false),
85533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::ValueDisallowed);
86533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
87533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesllvm::cl::opt<bool, true> ArgFatalWarningsFlag("fatal-warnings",
88533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::ZeroOrMore,
89533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::location(ArgFatalWarnings),
90533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::desc("turn all warnings into errors"),
91533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::init(false),
92533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::ValueDisallowed);
93533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
94a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hinesllvm::cl::opt<std::string> ArgUseLD("fuse-ld",
95a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  llvm::cl::desc("Ignored for GCC/collect2 linker compatibility."),
96a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  llvm::cl::init("mcld"));
97533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
98a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hinesllvm::cl::opt<std::string> ArgUseMCLD("use-mcld",
99a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  llvm::cl::desc("Ignored for GCC/collect2 linker compatibility."),
100a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  llvm::cl::init("mcld"));
101533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
102533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines//===----------------------------------------------------------------------===//
103533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines// Non-member functions
104533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines//===----------------------------------------------------------------------===//
105533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesinline bool ShouldColorize()
106533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines{
107533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines   const char* term = getenv("TERM");
108533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines   return term && (0 != strcmp(term, "dumb"));
109533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines}
110533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
111533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines} // anonymous namespace
112533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
113533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesusing namespace mcld;
114533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
115533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines//===----------------------------------------------------------------------===//
116533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines// PreferenceOptions
117533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines//===----------------------------------------------------------------------===//
118533eae20118036f425f27bf0536ef0ccbb090b65Stephen HinesPreferenceOptions::PreferenceOptions()
119533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  : m_Trace(ArgTrace),
120533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    m_Verbose(ArgVerbose),
121533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    m_Version(ArgVersion),
122533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    m_MaxErrorNum(ArgMaxErrorNum),
123533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    m_MaxWarnNum(ArgMaxWarnNum),
124533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    m_Color(ArgColor),
125533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    m_PrintMap(ArgPrintMap),
126533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    m_FatalWarnings(ArgFatalWarnings) {
127533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines}
128533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
129533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesbool PreferenceOptions::parse(LinkerConfig& pConfig)
130533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines{
131533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  // set -t
132533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  pConfig.options().setTrace(m_Trace);
133533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
134533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  // set --verbose
135533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  pConfig.options().setVerbose(m_Verbose);
136533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
137533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  // set --error-limit [number]
138533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  pConfig.options().setMaxErrorNum(m_MaxErrorNum);
139533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
140533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  // set --warning-limit [number]
141533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  pConfig.options().setMaxWarnNum(m_MaxWarnNum);
142533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
143533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  // set --color [mode]
144533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  switch (m_Color) {
145533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    case COLOR_Never:
146533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines      pConfig.options().setColor(false);
147533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    break;
148533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    case COLOR_Always:
149533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines      pConfig.options().setColor(true);
150533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    break;
151533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    case COLOR_Auto:
152533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines      bool color_option = ShouldColorize() &&
153533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                 llvm::sys::Process::FileDescriptorIsDisplayed(STDOUT_FILENO);
154533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines      pConfig.options().setColor(color_option);
155533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    break;
156533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  }
157533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
158533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::outs().setColor(pConfig.options().color());
159533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::errs().setColor(pConfig.options().color());
160533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
161533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  return true;
162533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines}
163533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
164