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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [readline/] [tilde.c] - Blame information for rev 856

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

Line No. Rev Author Line
1 227 jeremybenn
/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */
2
 
3
/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
4
 
5
   This file is part of GNU Readline, a library for reading lines
6
   of text with interactive input and history editing.
7
 
8
   Readline is free software; you can redistribute it and/or modify it
9
   under the terms of the GNU General Public License as published by the
10
   Free Software Foundation; either version 2, or (at your option) any
11
   later version.
12
 
13
   Readline is distributed in the hope that it will be useful, but
14
   WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
   General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with Readline; see the file COPYING.  If not, write to the Free
20
   Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
21
 
22
#if defined (HAVE_CONFIG_H)
23
#  include <config.h>
24
#endif
25
 
26
#if defined (HAVE_UNISTD_H)
27
#  ifdef _MINIX
28
#    include <sys/types.h>
29
#  endif
30
#  include <unistd.h>
31
#endif
32
 
33
#if defined (HAVE_STRING_H)
34
#  include <string.h>
35
#else /* !HAVE_STRING_H */
36
#  include <strings.h>
37
#endif /* !HAVE_STRING_H */  
38
 
39
#if defined (HAVE_STDLIB_H)
40
#  include <stdlib.h>
41
#else
42
#  include "ansi_stdlib.h"
43
#endif /* HAVE_STDLIB_H */
44
 
45
#include <sys/types.h>
46
#if defined (HAVE_PWD_H)
47
#include <pwd.h>
48
#endif
49
 
50
#include "tilde.h"
51
 
52
#if defined (TEST) || defined (STATIC_MALLOC)
53
static void *xmalloc (), *xrealloc ();
54
#else
55
#  include "xmalloc.h"
56
#endif /* TEST || STATIC_MALLOC */
57
 
58
#if !defined (HAVE_GETPW_DECLS)
59
#  if defined (HAVE_GETPWUID)
60
extern struct passwd *getpwuid PARAMS((uid_t));
61
#  endif
62
#  if defined (HAVE_GETPWNAM)
63
extern struct passwd *getpwnam PARAMS((const char *));
64
#  endif
65
#endif /* !HAVE_GETPW_DECLS */
66
 
67
#if !defined (savestring)
68
#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x))
69
#endif /* !savestring */
70
 
71
#if !defined (NULL)
72
#  if defined (__STDC__)
73
#    define NULL ((void *) 0)
74
#  else
75
#    define NULL 0x0
76
#  endif /* !__STDC__ */
77
#endif /* !NULL */
78
 
79
/* If being compiled as part of bash, these will be satisfied from
80
   variables.o.  If being compiled as part of readline, they will
81
   be satisfied from shell.o. */
82
extern char *sh_get_home_dir PARAMS((void));
83
extern char *sh_get_env_value PARAMS((const char *));
84
 
85
/* The default value of tilde_additional_prefixes.  This is set to
86
   whitespace preceding a tilde so that simple programs which do not
87
   perform any word separation get desired behaviour. */
88
static const char *default_prefixes[] =
89
  { " ~", "\t~", (const char *)NULL };
90
 
91
/* The default value of tilde_additional_suffixes.  This is set to
92
   whitespace or newline so that simple programs which do not
93
   perform any word separation get desired behaviour. */
94
static const char *default_suffixes[] =
95
  { " ", "\n", (const char *)NULL };
96
 
97
/* If non-null, this contains the address of a function that the application
98
   wants called before trying the standard tilde expansions.  The function
99
   is called with the text sans tilde, and returns a malloc()'ed string
100
   which is the expansion, or a NULL pointer if the expansion fails. */
101
tilde_hook_func_t *tilde_expansion_preexpansion_hook = (tilde_hook_func_t *)NULL;
102
 
103
/* If non-null, this contains the address of a function to call if the
104
   standard meaning for expanding a tilde fails.  The function is called
105
   with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
106
   which is the expansion, or a NULL pointer if there is no expansion. */
107
tilde_hook_func_t *tilde_expansion_failure_hook = (tilde_hook_func_t *)NULL;
108
 
109
/* When non-null, this is a NULL terminated array of strings which
110
   are duplicates for a tilde prefix.  Bash uses this to expand
111
   `=~' and `:~'. */
112
char **tilde_additional_prefixes = (char **)default_prefixes;
113
 
114
/* When non-null, this is a NULL terminated array of strings which match
115
   the end of a username, instead of just "/".  Bash sets this to
116
   `:' and `=~'. */
117
char **tilde_additional_suffixes = (char **)default_suffixes;
118
 
119
static int tilde_find_prefix PARAMS((const char *, int *));
120
static int tilde_find_suffix PARAMS((const char *));
121
static char *isolate_tilde_prefix PARAMS((const char *, int *));
122
static char *glue_prefix_and_suffix PARAMS((char *, const char *, int));
123
 
124
/* Find the start of a tilde expansion in STRING, and return the index of
125
   the tilde which starts the expansion.  Place the length of the text
126
   which identified this tilde starter in LEN, excluding the tilde itself. */
127
static int
128
tilde_find_prefix (string, len)
129
     const char *string;
130
     int *len;
131
{
132
  register int i, j, string_len;
133
  register char **prefixes;
134
 
135
  prefixes = tilde_additional_prefixes;
136
 
137
  string_len = strlen (string);
138
  *len = 0;
139
 
140
  if (*string == '\0' || *string == '~')
141
    return (0);
142
 
143
  if (prefixes)
144
    {
145
      for (i = 0; i < string_len; i++)
146
        {
147
          for (j = 0; prefixes[j]; j++)
148
            {
149
              if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0)
150
                {
151
                  *len = strlen (prefixes[j]) - 1;
152
                  return (i + *len);
153
                }
154
            }
155
        }
156
    }
157
  return (string_len);
158
}
159
 
160
/* Find the end of a tilde expansion in STRING, and return the index of
161
   the character which ends the tilde definition.  */
162
static int
163
tilde_find_suffix (string)
164
     const char *string;
165
{
166
  register int i, j, string_len;
167
  register char **suffixes;
168
 
169
  suffixes = tilde_additional_suffixes;
170
  string_len = strlen (string);
171
 
172
  for (i = 0; i < string_len; i++)
173
    {
174
#if defined (__MSDOS__)
175
      if (string[i] == '/' || string[i] == '\\' /* || !string[i] */)
176
#else
177
      if (string[i] == '/' /* || !string[i] */)
178
#endif
179
        break;
180
 
181
      for (j = 0; suffixes && suffixes[j]; j++)
182
        {
183
          if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0)
184
            return (i);
185
        }
186
    }
187
  return (i);
188
}
189
 
190
/* Return a new string which is the result of tilde expanding STRING. */
191
char *
192
tilde_expand (string)
193
     const char *string;
194
{
195
  char *result;
196
  int result_size, result_index;
197
 
198
  result_index = result_size = 0;
199
  if (result = strchr (string, '~'))
200
    result = (char *)xmalloc (result_size = (strlen (string) + 16));
201
  else
202
    result = (char *)xmalloc (result_size = (strlen (string) + 1));
203
 
204
  /* Scan through STRING expanding tildes as we come to them. */
205
  while (1)
206
    {
207
      register int start, end;
208
      char *tilde_word, *expansion;
209
      int len;
210
 
211
      /* Make START point to the tilde which starts the expansion. */
212
      start = tilde_find_prefix (string, &len);
213
 
214
      /* Copy the skipped text into the result. */
215
      if ((result_index + start + 1) > result_size)
216
        result = (char *)xrealloc (result, 1 + (result_size += (start + 20)));
217
 
218
      strncpy (result + result_index, string, start);
219
      result_index += start;
220
 
221
      /* Advance STRING to the starting tilde. */
222
      string += start;
223
 
224
      /* Make END be the index of one after the last character of the
225
         username. */
226
      end = tilde_find_suffix (string);
227
 
228
      /* If both START and END are zero, we are all done. */
229
      if (!start && !end)
230
        break;
231
 
232
      /* Expand the entire tilde word, and copy it into RESULT. */
233
      tilde_word = (char *)xmalloc (1 + end);
234
      strncpy (tilde_word, string, end);
235
      tilde_word[end] = '\0';
236
      string += end;
237
 
238
      expansion = tilde_expand_word (tilde_word);
239
      free (tilde_word);
240
 
241
      len = strlen (expansion);
242
#ifdef __CYGWIN__
243
      /* Fix for Cygwin to prevent ~user/xxx from expanding to //xxx when
244
         $HOME for `user' is /.  On cygwin, // denotes a network drive. */
245
      if (len > 1 || *expansion != '/' || *string != '/')
246
#endif
247
        {
248
          if ((result_index + len + 1) > result_size)
249
            result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
250
 
251
          strcpy (result + result_index, expansion);
252
          result_index += len;
253
        }
254
      free (expansion);
255
    }
256
 
257
  result[result_index] = '\0';
258
 
259
  return (result);
260
}
261
 
262
/* Take FNAME and return the tilde prefix we want expanded.  If LENP is
263
   non-null, the index of the end of the prefix into FNAME is returned in
264
   the location it points to. */
265
static char *
266
isolate_tilde_prefix (fname, lenp)
267
     const char *fname;
268
     int *lenp;
269
{
270
  char *ret;
271
  int i;
272
 
273
  ret = (char *)xmalloc (strlen (fname));
274
#if defined (__MSDOS__)
275
  for (i = 1; fname[i] && fname[i] != '/' && fname[i] != '\\'; i++)
276
#else
277
  for (i = 1; fname[i] && fname[i] != '/'; i++)
278
#endif
279
    ret[i - 1] = fname[i];
280
  ret[i - 1] = '\0';
281
  if (lenp)
282
    *lenp = i;
283
  return ret;
284
}
285
 
286
#if 0
287
/* Public function to scan a string (FNAME) beginning with a tilde and find
288
   the portion of the string that should be passed to the tilde expansion
289
   function.  Right now, it just calls tilde_find_suffix and allocates new
290
   memory, but it can be expanded to do different things later. */
291
char *
292
tilde_find_word (fname, flags, lenp)
293
     const char *fname;
294
     int flags, *lenp;
295
{
296
  int x;
297
  char *r;
298
 
299
  x = tilde_find_suffix (fname);
300
  if (x == 0)
301
    {
302
      r = savestring (fname);
303
      if (lenp)
304
        *lenp = 0;
305
    }
306
  else
307
    {
308
      r = (char *)xmalloc (1 + x);
309
      strncpy (r, fname, x);
310
      r[x] = '\0';
311
      if (lenp)
312
        *lenp = x;
313
    }
314
 
315
  return r;
316
}
317
#endif
318
 
319
/* Return a string that is PREFIX concatenated with SUFFIX starting at
320
   SUFFIND. */
321
static char *
322
glue_prefix_and_suffix (prefix, suffix, suffind)
323
     char *prefix;
324
     const char *suffix;
325
     int suffind;
326
{
327
  char *ret;
328
  int plen, slen;
329
 
330
  plen = (prefix && *prefix) ? strlen (prefix) : 0;
331
  slen = strlen (suffix + suffind);
332
  ret = (char *)xmalloc (plen + slen + 1);
333
  if (plen)
334
    strcpy (ret, prefix);
335
  strcpy (ret + plen, suffix + suffind);
336
  return ret;
337
}
338
 
339
/* Do the work of tilde expansion on FILENAME.  FILENAME starts with a
340
   tilde.  If there is no expansion, call tilde_expansion_failure_hook.
341
   This always returns a newly-allocated string, never static storage. */
342
char *
343
tilde_expand_word (filename)
344
     const char *filename;
345
{
346
  char *dirname, *expansion, *username;
347
  int user_len;
348
  struct passwd *user_entry;
349
 
350
  if (filename == 0)
351
    return ((char *)NULL);
352
 
353
  if (*filename != '~')
354
    return (savestring (filename));
355
 
356
  /* A leading `~/' or a bare `~' is *always* translated to the value of
357
     $HOME or the home directory of the current user, regardless of any
358
     preexpansion hook. */
359
  if (filename[1] == '\0' || filename[1] == '/')
360
    {
361
      /* Prefix $HOME to the rest of the string. */
362
      expansion = sh_get_env_value ("HOME");
363
 
364
      /* If there is no HOME variable, look up the directory in
365
         the password database. */
366
      if (expansion == 0)
367
        expansion = sh_get_home_dir ();
368
 
369
      return (glue_prefix_and_suffix (expansion, filename, 1));
370
    }
371
 
372
  username = isolate_tilde_prefix (filename, &user_len);
373
 
374
  if (tilde_expansion_preexpansion_hook)
375
    {
376
      expansion = (*tilde_expansion_preexpansion_hook) (username);
377
      if (expansion)
378
        {
379
          dirname = glue_prefix_and_suffix (expansion, filename, user_len);
380
          free (username);
381
          free (expansion);
382
          return (dirname);
383
        }
384
    }
385
 
386
  /* No preexpansion hook, or the preexpansion hook failed.  Look in the
387
     password database. */
388
  dirname = (char *)NULL;
389
#if defined (HAVE_GETPWNAM)
390
  user_entry = getpwnam (username);
391
#else
392
  user_entry = 0;
393
#endif
394
  if (user_entry == 0)
395
    {
396
      /* If the calling program has a special syntax for expanding tildes,
397
         and we couldn't find a standard expansion, then let them try. */
398
      if (tilde_expansion_failure_hook)
399
        {
400
          expansion = (*tilde_expansion_failure_hook) (username);
401
          if (expansion)
402
            {
403
              dirname = glue_prefix_and_suffix (expansion, filename, user_len);
404
              free (expansion);
405
            }
406
        }
407
      free (username);
408
      /* If we don't have a failure hook, or if the failure hook did not
409
         expand the tilde, return a copy of what we were passed. */
410
      if (dirname == 0)
411
        dirname = savestring (filename);
412
    }
413
#if defined (HAVE_GETPWENT)
414
  else
415
    {
416
      free (username);
417
      dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len);
418
    }
419
  endpwent ();
420
#endif
421
  return (dirname);
422
}
423
 
424
 
425
#if defined (TEST)
426
#undef NULL
427
#include <stdio.h>
428
 
429
main (argc, argv)
430
     int argc;
431
     char **argv;
432
{
433
  char *result, line[512];
434
  int done = 0;
435
 
436
  while (!done)
437
    {
438
      printf ("~expand: ");
439
      fflush (stdout);
440
 
441
      if (!gets (line))
442
        strcpy (line, "done");
443
 
444
      if ((strcmp (line, "done") == 0) ||
445
          (strcmp (line, "quit") == 0) ||
446
          (strcmp (line, "exit") == 0))
447
        {
448
          done = 1;
449
          break;
450
        }
451
 
452
      result = tilde_expand (line);
453
      printf ("  --> %s\n", result);
454
      free (result);
455
    }
456
  exit (0);
457
}
458
 
459
static void memory_error_and_abort ();
460
 
461
static void *
462
xmalloc (bytes)
463
     size_t bytes;
464
{
465
  void *temp = (char *)malloc (bytes);
466
 
467
  if (!temp)
468
    memory_error_and_abort ();
469
  return (temp);
470
}
471
 
472
static void *
473
xrealloc (pointer, bytes)
474
     void *pointer;
475
     int bytes;
476
{
477
  void *temp;
478
 
479
  if (!pointer)
480
    temp = malloc (bytes);
481
  else
482
    temp = realloc (pointer, bytes);
483
 
484
  if (!temp)
485
    memory_error_and_abort ();
486
 
487
  return (temp);
488
}
489
 
490
static void
491
memory_error_and_abort ()
492
{
493
  fprintf (stderr, "readline: out of virtual memory\n");
494
  abort ();
495
}
496
 
497
/*
498
 * Local variables:
499
 * compile-command: "gcc -g -DTEST -o tilde tilde.c"
500
 * end:
501
 */
502
#endif /* TEST */

powered by: WebSVN 2.1.0

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