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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [gdb-5.0/] [readline/] [tilde.c] - Blame information for rev 1778

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

Line No. Rev Author Line
1 106 markom
/* 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, 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
#include <pwd.h>
47
 
48
#include "tilde.h"
49
 
50
#if !defined (HAVE_GETPW_DECLS)
51
extern struct passwd *getpwuid (), *getpwnam ();
52
#endif /* !HAVE_GETPW_DECLS */
53
 
54
#if !defined (savestring)
55
extern char *xmalloc ();
56
#  ifndef strcpy
57
extern char *strcpy ();
58
#  endif
59
#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
60
#endif /* !savestring */
61
 
62
#if !defined (NULL)
63
#  if defined (__STDC__)
64
#    define NULL ((void *) 0)
65
#  else
66
#    define NULL 0x0
67
#  endif /* !__STDC__ */
68
#endif /* !NULL */
69
 
70
#if defined (TEST) || defined (STATIC_MALLOC)
71
static char *xmalloc (), *xrealloc ();
72
#else
73
extern char *xmalloc (), *xrealloc ();
74
#endif /* TEST || STATIC_MALLOC */
75
 
76
/* If being compiled as part of bash, these will be satisfied from
77
   variables.o.  If being compiled as part of readline, they will
78
   be satisfied from shell.o. */
79
extern char *get_home_dir ();
80
extern char *get_env_value ();
81
 
82
/* The default value of tilde_additional_prefixes.  This is set to
83
   whitespace preceding a tilde so that simple programs which do not
84
   perform any word separation get desired behaviour. */
85
static char *default_prefixes[] =
86
  { " ~", "\t~", (char *)NULL };
87
 
88
/* The default value of tilde_additional_suffixes.  This is set to
89
   whitespace or newline so that simple programs which do not
90
   perform any word separation get desired behaviour. */
91
static char *default_suffixes[] =
92
  { " ", "\n", (char *)NULL };
93
 
94
/* If non-null, this contains the address of a function that the application
95
   wants called before trying the standard tilde expansions.  The function
96
   is called with the text sans tilde, and returns a malloc()'ed string
97
   which is the expansion, or a NULL pointer if the expansion fails. */
98
CPFunction *tilde_expansion_preexpansion_hook = (CPFunction *)NULL;
99
 
100
/* If non-null, this contains the address of a function to call if the
101
   standard meaning for expanding a tilde fails.  The function is called
102
   with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
103
   which is the expansion, or a NULL pointer if there is no expansion. */
104
CPFunction *tilde_expansion_failure_hook = (CPFunction *)NULL;
105
 
106
/* When non-null, this is a NULL terminated array of strings which
107
   are duplicates for a tilde prefix.  Bash uses this to expand
108
   `=~' and `:~'. */
109
char **tilde_additional_prefixes = default_prefixes;
110
 
111
/* When non-null, this is a NULL terminated array of strings which match
112
   the end of a username, instead of just "/".  Bash sets this to
113
   `:' and `=~'. */
114
char **tilde_additional_suffixes = default_suffixes;
115
 
116
/* Find the start of a tilde expansion in STRING, and return the index of
117
   the tilde which starts the expansion.  Place the length of the text
118
   which identified this tilde starter in LEN, excluding the tilde itself. */
119
static int
120
tilde_find_prefix (string, len)
121
     char *string;
122
     int *len;
123
{
124
  register int i, j, string_len;
125
  register char **prefixes = tilde_additional_prefixes;
126
 
127
  string_len = strlen (string);
128
  *len = 0;
129
 
130
  if (*string == '\0' || *string == '~')
131
    return (0);
132
 
133
  if (prefixes)
134
    {
135
      for (i = 0; i < string_len; i++)
136
        {
137
          for (j = 0; prefixes[j]; j++)
138
            {
139
              if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0)
140
                {
141
                  *len = strlen (prefixes[j]) - 1;
142
                  return (i + *len);
143
                }
144
            }
145
        }
146
    }
147
  return (string_len);
148
}
149
 
150
/* Find the end of a tilde expansion in STRING, and return the index of
151
   the character which ends the tilde definition.  */
152
static int
153
tilde_find_suffix (string)
154
     char *string;
155
{
156
  register int i, j, string_len;
157
  register char **suffixes;
158
 
159
  suffixes = tilde_additional_suffixes;
160
  string_len = strlen (string);
161
 
162
  for (i = 0; i < string_len; i++)
163
    {
164
      if (string[i] == '/' /* || !string[i] */)
165
        break;
166
 
167
      for (j = 0; suffixes && suffixes[j]; j++)
168
        {
169
          if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0)
170
            return (i);
171
        }
172
    }
173
  return (i);
174
}
175
 
176
/* Return a new string which is the result of tilde expanding STRING. */
177
char *
178
tilde_expand (string)
179
     char *string;
180
{
181
  char *result;
182
  int result_size, result_index;
183
 
184
  result_index = result_size = 0;
185
  if (result = strchr (string, '~'))
186
    result = xmalloc (result_size = (strlen (string) + 16));
187
  else
188
    result = xmalloc (result_size = (strlen (string) + 1));
189
 
190
  /* Scan through STRING expanding tildes as we come to them. */
191
  while (1)
192
    {
193
      register int start, end;
194
      char *tilde_word, *expansion;
195
      int len;
196
 
197
      /* Make START point to the tilde which starts the expansion. */
198
      start = tilde_find_prefix (string, &len);
199
 
200
      /* Copy the skipped text into the result. */
201
      if ((result_index + start + 1) > result_size)
202
        result = xrealloc (result, 1 + (result_size += (start + 20)));
203
 
204
      strncpy (result + result_index, string, start);
205
      result_index += start;
206
 
207
      /* Advance STRING to the starting tilde. */
208
      string += start;
209
 
210
      /* Make END be the index of one after the last character of the
211
         username. */
212
      end = tilde_find_suffix (string);
213
 
214
      /* If both START and END are zero, we are all done. */
215
      if (!start && !end)
216
        break;
217
 
218
      /* Expand the entire tilde word, and copy it into RESULT. */
219
      tilde_word = xmalloc (1 + end);
220
      strncpy (tilde_word, string, end);
221
      tilde_word[end] = '\0';
222
      string += end;
223
 
224
      expansion = tilde_expand_word (tilde_word);
225
      free (tilde_word);
226
 
227
      len = strlen (expansion);
228
      if ((result_index + len + 1) > result_size)
229
        result = xrealloc (result, 1 + (result_size += (len + 20)));
230
 
231
      strcpy (result + result_index, expansion);
232
      result_index += len;
233
      free (expansion);
234
    }
235
 
236
  result[result_index] = '\0';
237
 
238
  return (result);
239
}
240
 
241
/* Take FNAME and return the tilde prefix we want expanded.  If LENP is
242
   non-null, the index of the end of the prefix into FNAME is returned in
243
   the location it points to. */
244
static char *
245
isolate_tilde_prefix (fname, lenp)
246
     char *fname;
247
     int *lenp;
248
{
249
  char *ret;
250
  int i;
251
 
252
  ret = xmalloc (strlen (fname));
253
  for (i = 1; fname[i] && fname[i] != '/'; i++)
254
    ret[i - 1] = fname[i];
255
  ret[i - 1] = '\0';
256
  if (lenp)
257
    *lenp = i;
258
  return ret;
259
}
260
 
261
/* Return a string that is PREFIX concatenated with SUFFIX starting at
262
   SUFFIND. */
263
static char *
264
glue_prefix_and_suffix (prefix, suffix, suffind)
265
     char *prefix, *suffix;
266
     int suffind;
267
{
268
  char *ret;
269
  int plen, slen;
270
 
271
  plen = (prefix && *prefix) ? strlen (prefix) : 0;
272
  slen = strlen (suffix + suffind);
273
  ret = xmalloc (plen + slen + 1);
274
  if (prefix && *prefix)
275
    strcpy (ret, prefix);
276
  strcpy (ret + plen, suffix + suffind);
277
  return ret;
278
}
279
 
280
/* Do the work of tilde expansion on FILENAME.  FILENAME starts with a
281
   tilde.  If there is no expansion, call tilde_expansion_failure_hook.
282
   This always returns a newly-allocated string, never static storage. */
283
char *
284
tilde_expand_word (filename)
285
     char *filename;
286
{
287
  char *dirname, *expansion, *username;
288
  int user_len;
289
  struct passwd *user_entry;
290
 
291
  if (filename == 0)
292
    return ((char *)NULL);
293
 
294
  if (*filename != '~')
295
    return (savestring (filename));
296
 
297
  /* A leading `~/' or a bare `~' is *always* translated to the value of
298
     $HOME or the home directory of the current user, regardless of any
299
     preexpansion hook. */
300
  if (filename[1] == '\0' || filename[1] == '/')
301
    {
302
      /* Prefix $HOME to the rest of the string. */
303
      expansion = get_env_value ("HOME");
304
 
305
      /* If there is no HOME variable, look up the directory in
306
         the password database. */
307
      if (expansion == 0)
308
        expansion = get_home_dir ();
309
 
310
      return (glue_prefix_and_suffix (expansion, filename, 1));
311
    }
312
 
313
  username = isolate_tilde_prefix (filename, &user_len);
314
 
315
  if (tilde_expansion_preexpansion_hook)
316
    {
317
      expansion = (*tilde_expansion_preexpansion_hook) (username);
318
      if (expansion)
319
        {
320
          dirname = glue_prefix_and_suffix (expansion, filename, user_len);
321
          free (username);
322
          free (expansion);
323
          return (dirname);
324
        }
325
    }
326
 
327
  /* No preexpansion hook, or the preexpansion hook failed.  Look in the
328
     password database. */
329
  dirname = (char *)NULL;
330
  user_entry = getpwnam (username);
331
  if (user_entry == 0)
332
    {
333
      /* If the calling program has a special syntax for expanding tildes,
334
         and we couldn't find a standard expansion, then let them try. */
335
      if (tilde_expansion_failure_hook)
336
        {
337
          expansion = (*tilde_expansion_failure_hook) (username);
338
          if (expansion)
339
            {
340
              dirname = glue_prefix_and_suffix (expansion, filename, user_len);
341
              free (expansion);
342
            }
343
        }
344
      free (username);
345
      /* If we don't have a failure hook, or if the failure hook did not
346
         expand the tilde, return a copy of what we were passed. */
347
      if (dirname == 0)
348
        dirname = savestring (filename);
349
    }
350
  else
351
    {
352
      free (username);
353
      dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len);
354
    }
355
 
356
  endpwent ();
357
  return (dirname);
358
}
359
 
360
 
361
#if defined (TEST)
362
#undef NULL
363
#include <stdio.h>
364
 
365
main (argc, argv)
366
     int argc;
367
     char **argv;
368
{
369
  char *result, line[512];
370
  int done = 0;
371
 
372
  while (!done)
373
    {
374
      printf ("~expand: ");
375
      fflush (stdout);
376
 
377
      if (!gets (line))
378
        strcpy (line, "done");
379
 
380
      if ((strcmp (line, "done") == 0) ||
381
          (strcmp (line, "quit") == 0) ||
382
          (strcmp (line, "exit") == 0))
383
        {
384
          done = 1;
385
          break;
386
        }
387
 
388
      result = tilde_expand (line);
389
      printf ("  --> %s\n", result);
390
      free (result);
391
    }
392
  exit (0);
393
}
394
 
395
static void memory_error_and_abort ();
396
 
397
static char *
398
xmalloc (bytes)
399
     int bytes;
400
{
401
  char *temp = (char *)malloc (bytes);
402
 
403
  if (!temp)
404
    memory_error_and_abort ();
405
  return (temp);
406
}
407
 
408
static char *
409
xrealloc (pointer, bytes)
410
     char *pointer;
411
     int bytes;
412
{
413
  char *temp;
414
 
415
  if (!pointer)
416
    temp = (char *)malloc (bytes);
417
  else
418
    temp = (char *)realloc (pointer, bytes);
419
 
420
  if (!temp)
421
    memory_error_and_abort ();
422
 
423
  return (temp);
424
}
425
 
426
static void
427
memory_error_and_abort ()
428
{
429
  fprintf (stderr, "readline: out of virtual memory\n");
430
  abort ();
431
}
432
 
433
/*
434
 * Local variables:
435
 * compile-command: "gcc -g -DTEST -o tilde tilde.c"
436
 * end:
437
 */
438
#endif /* TEST */

powered by: WebSVN 2.1.0

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