OpenTREP Logo  0.07.18
C++ Open Travel Request Parsing Library
Loading...
Searching...
No Matches
readline_autocomp.hpp
Go to the documentation of this file.
1
6#ifndef __OPENTREP_READLINE_AUTOCOMP_HPP
7#define __OPENTREP_READLINE_AUTOCOMP_HPP
8
9// STL
10#include <string>
11#include <iosfwd>
12#include <cstdio>
13#include <sys/types.h>
14#include <sys/file.h>
15#include <sys/stat.h>
16#include <sys/errno.h>
17
18#include <readline/readline.h>
19#include <readline/history.h>
20
21extern char* getwd();
22extern char* xmalloc (size_t);
23
24/* The names of functions that actually do the manipulation. */
25int com_list (char*);
26int com_view (char*);
27int com_rename (char*);
28int com_stat (char*);
29int com_pwd (char*);
30int com_delete (char*);
31int com_help (char*);
32int com_cd (char*);
33int com_quit (char*);
34
35typedef int (*pt2Func) (char*);
36
41typedef struct {
45 char const* name;
46
51
55 char *doc;
56} COMMAND;
57
59 { "cd", (*com_cd)(), "Change to directory DIR" },
60 { "delete", com_delete, "Delete FILE" },
61 { "help", com_help, "Display this text" },
62 { "?", com_help, "Synonym for `help'" },
63 { "list", com_list, "List files in DIR" },
64 { "ls", com_list, "Synonym for `list'" },
65 { "pwd", com_pwd, "Print the current working directory" },
66 { "quit", com_quit, "Quit using opentrep" },
67 { "rename", com_rename, "Rename FILE to NEWNAME" },
68 { "stat", com_stat, "Print out statistics on FILE" },
69 { "view", com_view, "View the contents of FILE" },
70 { (char*) NULL, (pt2Func) NULL, (char*) NULL }
71};
72
73// Forward declarations
74char* stripwhite (char* iString);
75COMMAND* find_command (char* iString);
76
80int done;
81
85char* dupstr (char* iString) {
86 char* r = xmalloc (std::strlen (iString) + 1);
87 strcpy (r, iString);
88 return r;
89}
90
94int execute_line (char* line) {
95 register int i;
96 COMMAND* command;
97 char* word;
98
99 /* Isolate the command word. */
100 i = 0;
101 while (line[i] && whitespace (line[i])) {
102 i++;
103 }
104 word = line + i;
105
106 while (line[i] && !whitespace (line[i])) {
107 i++;
108 }
109
110 if (line[i]) {
111 line[i++] = '\0';
112 }
113
114 command = find_command (word);
115
116 if (!command) {
117 std::cerr << word << ": No such command for opentrep." << std::endl;
118 return -1;
119 }
120
121 /* Get argument to command, if any. */
122 while (whitespace (line[i])) {
123 i++;
124 }
125
126 word = line + i;
127
128 /* Call the function. */
129 return (*(command->func)) (word);
130}
131
136COMMAND* find_command (char* name) {
137 register int i;
138
139 for (i = 0; commands[i].name; i++) {
140 if (strcmp (name, commands[i].name) == 0) {
141 return (&commands[i]);
142 }
143 }
144
145 return (COMMAND*) NULL;
146}
147
152char* stripwhite (char* string) {
153 register char *s, *t;
154
155 for (s = string; whitespace (*s); s++) {
156 }
157
158 if (*s == 0) {
159 return s;
160 }
161
162 t = s + strlen (s) - 1;
163 while (t > s && whitespace (*t)) {
164 t--;
165 }
166 *++t = '\0';
167
168 return s;
169}
170
171/* **************************************************************** */
172/* */
173/* Interface to Readline Completion */
174/* */
175/* **************************************************************** */
176
177char* command_generator (char* text, int state);
178char** fileman_completion (char* text, int start, int end);
179
186 /* Allow conditional parsing of the ~/.inputrc file. */
187 rl_readline_name = "opentrep";
188
189 /* Tell the completer that we want a crack first. */
190 rl_attempted_completion_function = (rl_completion_func_t*) fileman_completion;
191}
192
200char** fileman_completion (char* text, int start, int end) {
201 char **matches;
202
203 matches = (char**) NULL;
204
210 if (start == 0) {
211 matches = completion_matches (text, command_generator);
212 }
213
214 return matches;
215}
216
222char* command_generator (char* text, int state) {
223 static int list_index, len;
224 char* name;
225
231 if (!state) {
232 list_index = 0;
233 len = strlen (text);
234 }
235
236 /* Return the next name which partially matches from the command list. */
237 while (name = commands[list_index].name) {
238 ++list_index;
239
240 if (strncmp (name, text, len) == 0) {
241 return dupstr (name);
242 }
243 }
244
245 /* If no names matched, then return NULL. */
246 return (char*) NULL;
247}
248
249/* **************************************************************** */
250/* */
251/* opentrep Commands */
252/* */
253/* **************************************************************** */
254
259static char syscom[1024];
260
264void com_list (char* arg) {
265 if (!arg) {
266 arg = "";
267 }
268
269 std::ostringstream oStr;
270 oStr << "ls -FClg " << arg;
271 return system (oStr.c_str());
272}
273
274int com_view (char* arg) {
275 if (!valid_argument ("view", arg)) {
276 return 1;
277 }
278
279 std::ostringstream oStr;
280 oStr << "more " << arg;
281 return system (syscom);
282}
283
284int com_rename (char* arg) {
285 too_dangerous ("rename");
286 return 1;
287}
288
289int com_stat (char* arg) {
290 struct stat finfo;
291
292 if (!valid_argument ("stat", arg)) {
293 return 1;
294 }
295
296 if (stat (arg, &finfo) == -1) {
297 perror (arg);
298 return 1;
299 }
300
301 std::cout << "Statistics for `" << arg << "':" << std::endl;
302
303 const std::string lPluralEnd1 = (finfo.st_nlink == 1) ? "" : "s";
304 const std::string lPluralEnd2 = (finfo.st_size == 1) ? "" : "s";
305 std::cout << arg << " has "
306 << finfo.st_nlink << " link" << lPluralEnd1 << ", and is "
307 << finfo.st_size << " byte" << lPluralEnd2 << " in length."
308 << std::endl;
309 std::cout << " Inode Last Change at: " << ctime (&finfo.st_ctime) << std::endl;
310 std::cout << " Last access at: " << ctime (&finfo.st_atime) << std::endl;
311 std::cout << " Last modified at: " << ctime (&finfo.st_mtime) << std::endl;
312 return 0;
313}
314
315int com_delete (char* arg) {
316 too_dangerous ("delete");
317 return 1;
318}
319
324int com_help (char* arg) {
325 register int i;
326 int printed = 0;
327
328 for (i = 0; commands[i].name; i++) {
329 if (!*arg || (strcmp (arg, commands[i].name) == 0)) {
330 printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc);
331 printed++;
332 }
333 }
334
335 if (!printed) {
336 printf ("No commands match `%s'. Possibilties are:\n", arg);
337
338 for (i = 0; commands[i].name; i++) {
339 /* Print in six columns. */
340 if (printed == 6) {
341 printed = 0;
342 printf ("\n");
343 }
344
345 printf ("%s\t", commands[i].name);
346 printed++;
347 }
348
349 if (printed)
350 printf ("\n");
351 }
352 return 0;
353}
354
355/* Change to the directory ARG. */
356int com_cd (char* arg) {
357 if (chdir (arg) == -1) {
358 perror (arg);
359 return 1;
360 }
361
362 com_pwd ("");
363 return 0;
364}
365
366/* Print out the current working directory. */
367int com_pwd (char* ignore) {
368 char dir[1024], *s;
369
370 s = getwd (dir);
371 if (s == 0) {
372 printf ("Error getting pwd: %s\n", dir);
373 return 1;
374 }
375
376 printf ("Current directory is %s\n", dir);
377 return 0;
378}
379
380/* The user wishes to quit using this program. Just set DONE non-zero. */
381int com_quit (char* arg) {
382 done = 1;
383 return 0;
384}
385
386/* Function which tells you that you can't do this. */
387void too_dangerous (char* caller) {
388 fprintf (stderr,
389 "%s: Too dangerous for me to distribute. Write it yourself.\n",
390 caller);
391}
392
393/* Return non-zero if ARG is a valid argument for CALLER, else print
394 * an error message and return zero. */
395int valid_argument (char* caller, char* arg) {
396 if (!arg || !*arg) {
397 fprintf (stderr, "%s: Argument required.\n", caller);
398 return 0;
399 }
400
401 return 1;
402}
403
404#endif // _OPENTREP_READLINE_AUTOCOMP_HPP
int com_quit(char *)
static char syscom[1024]
char * getwd()
int valid_argument(char *caller, char *arg)
int com_pwd(char *)
char * stripwhite(char *iString)
void initialize_readline()
char * xmalloc(size_t)
int com_help(char *)
void too_dangerous(char *caller)
int done
char * command_generator(char *text, int state)
COMMAND commands[]
int execute_line(char *line)
int(* pt2Func)(char *)
int com_list(char *)
int com_view(char *)
int com_rename(char *)
int com_cd(char *)
int com_stat(char *)
COMMAND * find_command(char *iString)
int com_delete(char *)
char * dupstr(char *iString)
char ** fileman_completion(char *text, int start, int end)
char const * name
pt2Func * func