OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [readline/] [examples/] [fileman.c] - Blame information for rev 578

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.