gas: sparc: fix collision of registers and pseudo-ops.
[deliverable/binutils-gdb.git] / readline / examples / fileman.c
1 /* fileman.c - file manager example for readline library. */
2
3 /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
4
5 This file is part of the GNU Readline Library (Readline), a library for
6 reading lines of text with interactive input and history editing.
7
8 Readline is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 Readline is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Readline. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 /* fileman.c -- A tiny application which demonstrates how to use the
23 GNU Readline library. This application interactively allows users
24 to manipulate files and their modes. */
25
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29
30 #include <sys/types.h>
31 #ifdef HAVE_SYS_FILE_H
32 # include <sys/file.h>
33 #endif
34 #include <sys/stat.h>
35
36 #ifdef HAVE_UNISTD_H
37 # include <unistd.h>
38 #endif
39
40 #include <fcntl.h>
41 #include <stdio.h>
42 #include <errno.h>
43
44 #if defined (HAVE_STRING_H)
45 # include <string.h>
46 #else /* !HAVE_STRING_H */
47 # include <strings.h>
48 #endif /* !HAVE_STRING_H */
49
50 #ifdef HAVE_STDLIB_H
51 # include <stdlib.h>
52 #endif
53
54 #include <time.h>
55
56 #ifdef READLINE_LIBRARY
57 # include "readline.h"
58 # include "history.h"
59 #else
60 # include <readline/readline.h>
61 # include <readline/history.h>
62 #endif
63
64 extern char *xmalloc PARAMS((size_t));
65
66 /* The names of functions that actually do the manipulation. */
67 int com_list PARAMS((char *));
68 int com_view PARAMS((char *));
69 int com_rename PARAMS((char *));
70 int com_stat PARAMS((char *));
71 int com_pwd PARAMS((char *));
72 int com_delete PARAMS((char *));
73 int com_help PARAMS((char *));
74 int com_cd PARAMS((char *));
75 int com_quit PARAMS((char *));
76
77 /* A structure which contains information on the commands this program
78 can understand. */
79
80 typedef struct {
81 char *name; /* User printable name of the function. */
82 rl_icpfunc_t *func; /* Function to call to do the job. */
83 char *doc; /* Documentation for this function. */
84 } COMMAND;
85
86 COMMAND commands[] = {
87 { "cd", com_cd, "Change to directory DIR" },
88 { "delete", com_delete, "Delete FILE" },
89 { "help", com_help, "Display this text" },
90 { "?", com_help, "Synonym for `help'" },
91 { "list", com_list, "List files in DIR" },
92 { "ls", com_list, "Synonym for `list'" },
93 { "pwd", com_pwd, "Print the current working directory" },
94 { "quit", com_quit, "Quit using Fileman" },
95 { "rename", com_rename, "Rename FILE to NEWNAME" },
96 { "stat", com_stat, "Print out statistics on FILE" },
97 { "view", com_view, "View the contents of FILE" },
98 { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL }
99 };
100
101 /* Forward declarations. */
102 char *stripwhite ();
103 COMMAND *find_command ();
104
105 /* The name of this program, as taken from argv[0]. */
106 char *progname;
107
108 /* When non-zero, this global means the user is done using this program. */
109 int done;
110
111 char *
112 dupstr (s)
113 char *s;
114 {
115 char *r;
116
117 r = xmalloc (strlen (s) + 1);
118 strcpy (r, s);
119 return (r);
120 }
121
122 main (argc, argv)
123 int argc;
124 char **argv;
125 {
126 char *line, *s;
127
128 progname = argv[0];
129
130 initialize_readline (); /* Bind our completer. */
131
132 /* Loop reading and executing lines until the user quits. */
133 for ( ; done == 0; )
134 {
135 line = readline ("FileMan: ");
136
137 if (!line)
138 break;
139
140 /* Remove leading and trailing whitespace from the line.
141 Then, if there is anything left, add it to the history list
142 and execute it. */
143 s = stripwhite (line);
144
145 if (*s)
146 {
147 add_history (s);
148 execute_line (s);
149 }
150
151 free (line);
152 }
153 exit (0);
154 }
155
156 /* Execute a command line. */
157 int
158 execute_line (line)
159 char *line;
160 {
161 register int i;
162 COMMAND *command;
163 char *word;
164
165 /* Isolate the command word. */
166 i = 0;
167 while (line[i] && whitespace (line[i]))
168 i++;
169 word = line + i;
170
171 while (line[i] && !whitespace (line[i]))
172 i++;
173
174 if (line[i])
175 line[i++] = '\0';
176
177 command = find_command (word);
178
179 if (!command)
180 {
181 fprintf (stderr, "%s: No such command for FileMan.\n", word);
182 return (-1);
183 }
184
185 /* Get argument to command, if any. */
186 while (whitespace (line[i]))
187 i++;
188
189 word = line + i;
190
191 /* Call the function. */
192 return ((*(command->func)) (word));
193 }
194
195 /* Look up NAME as the name of a command, and return a pointer to that
196 command. Return a NULL pointer if NAME isn't a command name. */
197 COMMAND *
198 find_command (name)
199 char *name;
200 {
201 register int i;
202
203 for (i = 0; commands[i].name; i++)
204 if (strcmp (name, commands[i].name) == 0)
205 return (&commands[i]);
206
207 return ((COMMAND *)NULL);
208 }
209
210 /* Strip whitespace from the start and end of STRING. Return a pointer
211 into STRING. */
212 char *
213 stripwhite (string)
214 char *string;
215 {
216 register char *s, *t;
217
218 for (s = string; whitespace (*s); s++)
219 ;
220
221 if (*s == 0)
222 return (s);
223
224 t = s + strlen (s) - 1;
225 while (t > s && whitespace (*t))
226 t--;
227 *++t = '\0';
228
229 return s;
230 }
231
232 /* **************************************************************** */
233 /* */
234 /* Interface to Readline Completion */
235 /* */
236 /* **************************************************************** */
237
238 char *command_generator PARAMS((const char *, int));
239 char **fileman_completion PARAMS((const char *, int, int));
240
241 /* Tell the GNU Readline library how to complete. We want to try to complete
242 on command names if this is the first word in the line, or on filenames
243 if not. */
244 initialize_readline ()
245 {
246 /* Allow conditional parsing of the ~/.inputrc file. */
247 rl_readline_name = "FileMan";
248
249 /* Tell the completer that we want a crack first. */
250 rl_attempted_completion_function = fileman_completion;
251 }
252
253 /* Attempt to complete on the contents of TEXT. START and END bound the
254 region of rl_line_buffer that contains the word to complete. TEXT is
255 the word to complete. We can use the entire contents of rl_line_buffer
256 in case we want to do some simple parsing. Return the array of matches,
257 or NULL if there aren't any. */
258 char **
259 fileman_completion (text, start, end)
260 const char *text;
261 int start, end;
262 {
263 char **matches;
264
265 matches = (char **)NULL;
266
267 /* If this word is at the start of the line, then it is a command
268 to complete. Otherwise it is the name of a file in the current
269 directory. */
270 if (start == 0)
271 matches = rl_completion_matches (text, command_generator);
272
273 return (matches);
274 }
275
276 /* Generator function for command completion. STATE lets us know whether
277 to start from scratch; without any state (i.e. STATE == 0), then we
278 start at the top of the list. */
279 char *
280 command_generator (text, state)
281 const char *text;
282 int state;
283 {
284 static int list_index, len;
285 char *name;
286
287 /* If this is a new word to complete, initialize now. This includes
288 saving the length of TEXT for efficiency, and initializing the index
289 variable to 0. */
290 if (!state)
291 {
292 list_index = 0;
293 len = strlen (text);
294 }
295
296 /* Return the next name which partially matches from the command list. */
297 while (name = commands[list_index].name)
298 {
299 list_index++;
300
301 if (strncmp (name, text, len) == 0)
302 return (dupstr(name));
303 }
304
305 /* If no names matched, then return NULL. */
306 return ((char *)NULL);
307 }
308
309 /* **************************************************************** */
310 /* */
311 /* FileMan Commands */
312 /* */
313 /* **************************************************************** */
314
315 /* String to pass to system (). This is for the LIST, VIEW and RENAME
316 commands. */
317 static char syscom[1024];
318
319 /* List the file(s) named in arg. */
320 com_list (arg)
321 char *arg;
322 {
323 if (!arg)
324 arg = "";
325
326 sprintf (syscom, "ls -FClg %s", arg);
327 return (system (syscom));
328 }
329
330 com_view (arg)
331 char *arg;
332 {
333 if (!valid_argument ("view", arg))
334 return 1;
335
336 #if defined (__MSDOS__)
337 /* more.com doesn't grok slashes in pathnames */
338 sprintf (syscom, "less %s", arg);
339 #else
340 sprintf (syscom, "more %s", arg);
341 #endif
342 return (system (syscom));
343 }
344
345 com_rename (arg)
346 char *arg;
347 {
348 too_dangerous ("rename");
349 return (1);
350 }
351
352 com_stat (arg)
353 char *arg;
354 {
355 struct stat finfo;
356
357 if (!valid_argument ("stat", arg))
358 return (1);
359
360 if (stat (arg, &finfo) == -1)
361 {
362 perror (arg);
363 return (1);
364 }
365
366 printf ("Statistics for `%s':\n", arg);
367
368 printf ("%s has %d link%s, and is %d byte%s in length.\n",
369 arg,
370 finfo.st_nlink,
371 (finfo.st_nlink == 1) ? "" : "s",
372 finfo.st_size,
373 (finfo.st_size == 1) ? "" : "s");
374 printf ("Inode Last Change at: %s", ctime (&finfo.st_ctime));
375 printf (" Last access at: %s", ctime (&finfo.st_atime));
376 printf (" Last modified at: %s", ctime (&finfo.st_mtime));
377 return (0);
378 }
379
380 com_delete (arg)
381 char *arg;
382 {
383 too_dangerous ("delete");
384 return (1);
385 }
386
387 /* Print out help for ARG, or for all of the commands if ARG is
388 not present. */
389 com_help (arg)
390 char *arg;
391 {
392 register int i;
393 int printed = 0;
394
395 for (i = 0; commands[i].name; i++)
396 {
397 if (!*arg || (strcmp (arg, commands[i].name) == 0))
398 {
399 printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc);
400 printed++;
401 }
402 }
403
404 if (!printed)
405 {
406 printf ("No commands match `%s'. Possibilties are:\n", arg);
407
408 for (i = 0; commands[i].name; i++)
409 {
410 /* Print in six columns. */
411 if (printed == 6)
412 {
413 printed = 0;
414 printf ("\n");
415 }
416
417 printf ("%s\t", commands[i].name);
418 printed++;
419 }
420
421 if (printed)
422 printf ("\n");
423 }
424 return (0);
425 }
426
427 /* Change to the directory ARG. */
428 com_cd (arg)
429 char *arg;
430 {
431 if (chdir (arg) == -1)
432 {
433 perror (arg);
434 return 1;
435 }
436
437 com_pwd ("");
438 return (0);
439 }
440
441 /* Print out the current working directory. */
442 com_pwd (ignore)
443 char *ignore;
444 {
445 char dir[1024], *s;
446
447 s = getcwd (dir, sizeof(dir) - 1);
448 if (s == 0)
449 {
450 printf ("Error getting pwd: %s\n", dir);
451 return 1;
452 }
453
454 printf ("Current directory is %s\n", dir);
455 return 0;
456 }
457
458 /* The user wishes to quit using this program. Just set DONE non-zero. */
459 com_quit (arg)
460 char *arg;
461 {
462 done = 1;
463 return (0);
464 }
465
466 /* Function which tells you that you can't do this. */
467 too_dangerous (caller)
468 char *caller;
469 {
470 fprintf (stderr,
471 "%s: Too dangerous for me to distribute. Write it yourself.\n",
472 caller);
473 }
474
475 /* Return non-zero if ARG is a valid argument for CALLER, else print
476 an error message and return zero. */
477 int
478 valid_argument (caller, arg)
479 char *caller, *arg;
480 {
481 if (!arg || !*arg)
482 {
483 fprintf (stderr, "%s: Argument required.\n", caller);
484 return (0);
485 }
486
487 return (1);
488 }
This page took 0.04003 seconds and 4 git commands to generate.