OpenASIP 2.2
Loading...
Searching...
No Matches
EditLineReader.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file EditLineReader.cc
26 *
27 * Definition of EditLineReader.cc.
28 *
29 * @author Jussi Nykänen 2004 (nykanen-no.spam-cs.tut.fi)
30 * @author Pekka Jääskeläinen 2005 (pjaaskel-no.spam-cs.tut.fi)
31 * @note reviewed 2 June 2004 by jm, pj, tr, jn
32 * @note rating: yellow
33 */
34
35#include <string>
36#include <cstring>
37#include <cctype>
38#include <cstdio>
39#include <map>
40
41#include "EditLineReader.hh"
42#include "StringTools.hh"
43#include "MapTools.hh"
44#include "Application.hh"
45
46using std::string;
47using std::map;
48
49map<EditLine*, EditLineReader*> EditLineReader::lineReaders_;
50
51/**
52 * Constructor.
53 *
54 * @param program The name of the invocating program.
55 */
57 LineReader(), prompt_(NULL), program_(program), editLine_(NULL),
58 history_(NULL) {
59}
60
61/**
62 * Destructor.
63 */
65
67
68 if (history_ != NULL) {
69 history_end(history_);
70 }
71
72 if (editLine_ != NULL) {
73 el_end(editLine_);
74 }
75
76 if (prompt_ != NULL) {
77 delete[] prompt_;
78 }
79}
80
81/**
82 * Initializes LineReader.
83 *
84 * Sets the prompt printing function and initializes history.
85 *
86 * @param defPrompt The prompt for the program.
87 * @param in Input file stream.
88 * @param out Output file stream.
89 * @param err Error file stream.
90 */
91void
93 std::string defPrompt,
94 FILE* in,
95 FILE* out,
96 FILE* err) {
97
99 // initialize EditLine
100 editLine_ = el_init(program_.c_str(), in, out, err);
101 assert(editLine_!=NULL);
102 // define prompt printing function
103 el_set(editLine_, EL_PROMPT, wrapperToCallPrompt);
104 // bind all keys to the standard GNU emacs-like bindings.
105 //el_set(editLine_, EL_BIND, "-e");
106 el_set(editLine_, EL_EDITOR, "emacs");
107 if (in != stdin) {
108 // when reading from file, editing is set off
109 el_set(editLine_, EL_EDITMODE, 0);
110 }
111 // initialize History
112 HistEvent ev;
113 history_ = history_init();
114 if (history_!=NULL) {
115 // size of the history is set to 100
116 history(history_, &ev, H_SETSIZE, 100);
117 el_set(editLine_, EL_HIST, history, history_);
118 }
119 lineReaders_.insert(ValType(editLine_, this));
120 in_ = in;
122}
123
124/**
125 * Reads line from input stream.
126 *
127 * If prompt is given, it is used as a prompt only for reading this one line.
128 *
129 * @param prompt The prompt.
130 * @return The string that is read.
131 * @exception ObjectNotInitialized If LineReader is not initialized.
132 * @exception EndOfFile When end of file mark (ctrl-d) is received.
133 */
134string
135EditLineReader::readLine(std::string prompt) {
136 if (!initialized()) {
137 string message = "LineReader not initialized";
138 throw ObjectNotInitialized(__FILE__, __LINE__, __func__, message);
139 }
140
141 char* oldPrompt = NULL;
142 if (prompt != "") {
143 oldPrompt = prompt_;
145 }
146
147 int count;
148 const char* c = el_gets(editLine_, &count);
149
150 bool endOfFile = (c == NULL || strlen(c) == 0 || feof(in_));
151 if (endOfFile) {
152 string message = "End of file.";
153 throw EndOfFile(__FILE__, __LINE__, __func__, message);
154 }
155
156 // add command to history
157 updateHistory(c);
158 if (oldPrompt != NULL) {
159 delete[] prompt_;
160 prompt_ = oldPrompt;
161 }
162 return c;
163}
164
165/**
166 * Asks user a question and expects that answer is given as char.
167 *
168 * Prompt is temporarily changed to 'question' during the execution of this
169 * function.
170 *
171 * @param question The asked question.
172 * @param allowedChars The chars that are legal answers.
173 * @param caseSensitive Flag indicating whether answer is read case sensitive
174 * or not.
175 * @param defaultAnswer The default answer.
176 * @return User given answer.
177 * @exception ObjectNotInitialized If LineReader is not initialized.
178 */
179char
181 std::string question, std::string allowedChars, bool caseSensitive,
182 char defaultAnswer) {
183 if (!initialized()) {
184 string method = "EditLineReader::charQuestion()";
185 string message = "LineReader not initialized";
186 throw ObjectNotInitialized(__FILE__, __LINE__, method, message);
187 }
188
189 char* oldPrompt = prompt_;
191
192 if (defaultAnswer == '\0') {
193 const char* answer = nullptr;
194 do {
195 int count;
196 answer = el_gets(editLine_, &count);
197 } while (strlen(answer) != 1 &&
198 !StringTools::
199 containsChar(allowedChars, answer[0], caseSensitive));
200
201 updateHistory(answer);
202 delete[] prompt_;
203 prompt_ = oldPrompt;
204 return answer[0];
205 } else {
206 const char* answer = nullptr;
207 int count;
208 assert(editLine_ != nullptr);
209 answer = el_gets(editLine_, &count);
210 if (answer == nullptr) {
211 updateHistory("");
212 delete[] prompt_;
213 prompt_ = oldPrompt;
214 return defaultAnswer;
215 }
216 if (strlen(answer) != 1 &&
217 !StringTools::
218 containsChar(allowedChars, answer[0], caseSensitive)) {
219
220 updateHistory(&defaultAnswer);
221 delete[] prompt_;
222 prompt_ = oldPrompt;
223 return defaultAnswer;
224 } else {
225 updateHistory(answer);
226 delete[] prompt_;
227 prompt_ = oldPrompt;
228 return answer[0];
229 }
230 }
231}
232
233/**
234 * Static wrapper function that calls function that returns the prompt.
235 *
236 * If correct EditLine* instance is not found in the map, an empty string
237 * (null char*) is returned.
238 *
239 * @param edit EditLine which prompt is needed.
240 * @return The prompt.
241 */
242char*
244
245 MapIt mi = lineReaders_.find(edit);
246 if (mi == lineReaders_.end()) {
247 return NULL;
248 }
249 EditLineReader* reader = (*mi).second;
250 return reader->prompt();
251}
252
253/**
254 * Returns the used prompt.
255 *
256 * @return The prompt.
257 */
258char*
260 return prompt_;
261}
262
263/**
264 * Inserts a new entry to history.
265 *
266 * Only non-empty strings are saved to history.
267 *
268 * @param newEntry A new entry to be added.
269 */
270void
271EditLineReader::updateHistory(const char* newEntry) {
272 string entry(newEntry);
273 entry = StringTools::trim(entry);
274 if (entry != "") {
275 HistEvent ev;
276 history(history_, &ev, H_ENTER, newEntry);
277 putInInputHistory(newEntry);
278 }
279}
#define __func__
#define assert(condition)
find Finds info of the inner loops in the program
char * prompt_
Line reader prompt.
std::map< EditLine *, EditLineReader * >::value_type ValType
value_type for map.
virtual ~EditLineReader()
virtual char charQuestion(std::string question, std::string allowedChars, bool caseSensitive=false, char defaultAnswer='\0')
FILE * in_
Input stream is saved for end-of-file checking.
EditLine * editLine_
EditLine instance.
static std::map< EditLine *, EditLineReader * > lineReaders_
Map containing all (EditLine*, EditLineReader*) pairs to make prompt printing possible....
void updateHistory(const char *c)
EditLineReader(std::string program="")
History * history_
History instance.
virtual std::string readLine(std::string prompt="")
std::map< EditLine *, EditLineReader * >::iterator MapIt
Iterator for map.
virtual void initialize(std::string defPrompt="", FILE *in=stdin, FILE *out=stdout, FILE *err=stderr)
static char * wrapperToCallPrompt(EditLine *edit)
std::string program_
The name of the invocating program.
void putInInputHistory(const std::string &inputLine)
void setInitialized()
bool initialized() const
static std::string trim(const std::string &source)
static char * stringToCharPtr(const std::string &source)