12 #include "llvm/Config/config.h"
33 LineEditor::CompleterConcept::~CompleterConcept() {}
34 LineEditor::ListCompleterConcept::~ListCompleterConcept() {}
36 std::string LineEditor::ListCompleterConcept::getCommonPrefix(
37 const std::vector<Completion> &Comps) {
40 std::string CommonPrefix = Comps[0].TypedText;
41 for (std::vector<Completion>::const_iterator
I = Comps.begin() + 1,
44 size_t Len =
std::min(CommonPrefix.size(),
I->TypedText.size());
46 for (; CommonLen != Len; ++CommonLen) {
47 if (CommonPrefix[CommonLen] !=
I->TypedText[CommonLen])
50 CommonPrefix.resize(CommonLen);
56 LineEditor::ListCompleterConcept::complete(
StringRef Buffer,
size_t Pos)
const {
57 CompletionAction Action;
58 std::vector<Completion> Comps = getCompletions(Buffer, Pos);
60 Action.Kind = CompletionAction::AK_ShowCompletions;
64 std::string CommonPrefix = getCommonPrefix(Comps);
71 if (CommonPrefix.empty()) {
72 Action.Kind = CompletionAction::AK_ShowCompletions;
73 for (std::vector<Completion>::iterator
I = Comps.begin(),
E = Comps.end();
75 Action.Completions.push_back(
I->DisplayText);
77 Action.Kind = CompletionAction::AK_Insert;
78 Action.Text = CommonPrefix;
92 return Completer->complete(Buffer, Pos);
113 const char *ElGetPromptFn(EditLine *EL) {
115 if (el_get(EL, EL_CLIENTDATA, &Data) == 0)
124 unsigned char ElCompletionFn(EditLine *EL,
int ch) {
126 if (el_get(EL, EL_CLIENTDATA, &Data) == 0) {
129 FILE *Out = Data->
Out;
137 std::string Prevs(Data->
PrevCount,
'\02');
138 ::el_push(EL, const_cast<char *>(Prevs.c_str()));
145 const LineInfo *LI = ::el_line(EL);
147 StringRef(LI->buffer, LI->lastchar - LI->buffer),
148 LI->cursor - LI->buffer);
149 switch (Action.
Kind) {
151 ::el_insertstr(EL, Action.
Text.c_str());
156 return CC_REFRESH_BEEP;
165 ::el_push(EL, const_cast<char *>(
"\05\t"));
174 for (std::vector<std::string>::iterator
I = Action.
Completions.begin(),
184 <<
StringRef(LI->buffer, LI->lastchar - LI->buffer);
188 Data->
PrevCount = LI->lastchar - LI->cursor;
200 FILE *Out, FILE *Err)
201 : Prompt((ProgName +
"> ").str()), HistoryPath(HistoryPath),
203 if (HistoryPath.
empty())
209 Data->
Hist = ::history_init();
212 Data->
EL = ::el_init(ProgName.
str().c_str(),
In, Out, Err);
215 ::el_set(Data->
EL, EL_PROMPT, ElGetPromptFn);
216 ::el_set(Data->
EL, EL_EDITOR,
"emacs");
217 ::el_set(Data->
EL, EL_HIST, history, Data->
Hist);
218 ::el_set(Data->
EL, EL_ADDFN,
"tab_complete",
"Tab completion function",
220 ::el_set(Data->
EL, EL_BIND,
"\t",
"tab_complete", NULL);
221 ::el_set(Data->
EL, EL_BIND,
"^r",
"em-inc-search-prev",
223 ::el_set(Data->
EL, EL_BIND,
"^w",
"ed-delete-prev-word",
225 ::el_set(Data->
EL, EL_BIND,
"\033[3~",
"ed-delete-next-char",
227 ::el_set(Data->
EL, EL_CLIENTDATA, Data.get());
230 ::history(Data->
Hist, &HE, H_SETSIZE, 800);
231 ::history(Data->
Hist, &HE, H_SETUNIQUE, 1);
238 ::history_end(Data->
Hist);
240 ::fwrite(
"\n", 1, 1, Data->
Out);
244 if (!HistoryPath.empty()) {
246 ::history(Data->
Hist, &HE, H_SAVE, HistoryPath.c_str());
251 if (!HistoryPath.empty()) {
253 ::history(Data->
Hist, &HE, H_LOAD, HistoryPath.c_str());
260 const char *Line = ::el_gets(Data->
EL, &LineLen);
263 if (!Line || LineLen == 0)
267 while (LineLen > 0 &&
268 (Line[LineLen - 1] ==
'\n' || Line[LineLen - 1] ==
'\r'))
273 ::history(Data->
Hist, &HE, H_ENTER, Line);
275 return std::string(Line, LineLen);
278 #else // HAVE_LIBEDIT
288 FILE *Out, FILE *Err)
289 : Prompt((ProgName +
"> ").str()), Data(new InternalData) {
295 ::fwrite(
"\n", 1, 1, Data->
Out);
302 ::fprintf(Data->
Out,
"%s", Prompt.c_str());
307 char *Res = ::fgets(Buf,
sizeof(Buf), Data->In);
315 }
while (Line.empty() ||
316 (Line[Line.size() - 1] !=
'\n' && Line[Line.size() - 1] !=
'\r'));
318 while (!Line.empty() &&
319 (Line[Line.size() - 1] ==
'\n' || Line[Line.size() - 1] ==
'\r'))
320 Line.resize(Line.size() - 1);
325 #endif // HAVE_LIBEDIT
std::string ContinuationOutput
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
llvm::Optional< std::string > readLine() const
Reads a line.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
Insert Text at the cursor position.
LineEditor(StringRef ProgName, StringRef HistoryPath="", FILE *In=stdin, FILE *Out=stdout, FILE *Err=stderr)
Create a LineEditor object.
static std::string getDefaultHistoryPath(StringRef ProgName)
The action to perform upon a completion request.
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
CompletionAction getCompletionAction(StringRef Buffer, size_t Pos) const
Use the current completer to produce a CompletionAction for the given completion request.
Show Completions, or beep if the list is empty.
std::vector< std::string > Completions
The list of completions to show.
StringRef str() const
Explicit conversion to StringRef.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
std::string Text
The text to insert.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
bool home_directory(SmallVectorImpl< char > &result)
Get the user's home directory.
StringRef - Represent a constant reference to a string, i.e.
const std::string & getPrompt() const