Annotation of GNUtools/debug/gdb/glob/tilde.c, revision 1.1

1.1     ! root        1: /* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */
        !             2: 
        !             3: /* Copyright (C) 1988,1989, 1991 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
        !             9:    it under the terms of the GNU General Public License as published by
        !            10:    the Free Software Foundation; either version 2 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 this program; if not, write to the Free Software
        !            20:    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            21: 
        !            22: #include "sysdep.h"
        !            23: 
        !            24: #ifndef __MSDOS__
        !            25: #include <pwd.h>
        !            26: #endif
        !            27: 
        !            28: #ifdef __GNUC__
        !            29: #undef alloca
        !            30: #define alloca(x) __builtin_alloca(x)
        !            31: #endif
        !            32: 
        !            33: #ifndef savestring
        !            34: #ifdef xmalloc
        !            35: #define savestring(x) (char *)strcpy ((char *)malloc (1 + strlen (x)), (x))
        !            36: #else
        !            37: #define savestring(x) (char *)strcpy (xmalloc (1 + strlen (x)), (x))
        !            38: #endif /* xmalloc */
        !            39: #endif
        !            40: 
        !            41: typedef int Function ();
        !            42: #if !defined (NULL)
        !            43: #  define NULL 0x0
        !            44: #endif
        !            45: 
        !            46: #ifndef xmalloc
        !            47: #if defined (TEST)
        !            48: static char *xmalloc (), *xrealloc ();
        !            49: #else
        !            50: extern char *xmalloc (), *xrealloc ();
        !            51: #endif /* TEST */
        !            52: #endif /* !xmalloc */
        !            53: 
        !            54: /* The default value of tilde_additional_prefixes.  This is set to
        !            55:    whitespace preceding a tilde so that simple programs which do not
        !            56:    perform any word separation get desired behaviour. */
        !            57: static char *default_prefixes[] =
        !            58:   { " ~", "\t~", (char *)NULL };
        !            59: 
        !            60: /* The default value of tilde_additional_suffixes.  This is set to
        !            61:    whitespace or newline so that simple programs which do not
        !            62:    perform any word separation get desired behaviour. */
        !            63: static char *default_suffixes[] =
        !            64:   { " ", "\n", (char *)NULL };
        !            65: 
        !            66: /* If non-null, this contains the address of a function to call if the
        !            67:    standard meaning for expanding a tilde fails.  The function is called
        !            68:    with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
        !            69:    which is the expansion, or a NULL pointer if there is no expansion. */
        !            70: Function *tilde_expansion_failure_hook = (Function *)NULL;
        !            71: 
        !            72: /* When non-null, this is a NULL terminated array of strings which
        !            73:    are duplicates for a tilde prefix.  Bash uses this to expand
        !            74:    `=~' and `:~'. */
        !            75: char **tilde_additional_prefixes = default_prefixes;
        !            76: 
        !            77: /* When non-null, this is a NULL terminated array of strings which match
        !            78:    the end of a username, instead of just "/".  Bash sets this to
        !            79:    `:' and `=~'. */
        !            80: char **tilde_additional_suffixes = default_suffixes;
        !            81: 
        !            82: /* Find the start of a tilde expansion in STRING, and return the index of
        !            83:    the tilde which starts the expansion.  Place the length of the text
        !            84:    which identified this tilde starter in LEN, excluding the tilde itself. */
        !            85: static int
        !            86: tilde_find_prefix (string, len)
        !            87:      char *string;
        !            88:      int *len;
        !            89: {
        !            90:   register int i, j, string_len;
        !            91:   register char **prefixes = tilde_additional_prefixes;
        !            92: 
        !            93:   string_len = strlen (string);
        !            94:   *len = 0;
        !            95: 
        !            96:   if (!*string || *string == '~')
        !            97:     return (0);
        !            98: 
        !            99:   if (prefixes)
        !           100:     {
        !           101:       for (i = 0; i < string_len; i++)
        !           102:        {
        !           103:          for (j = 0; prefixes[j]; j++)
        !           104:            {
        !           105:              if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0)
        !           106:                {
        !           107:                  *len = strlen (prefixes[j]) - 1;
        !           108:                  return (i + *len);
        !           109:                }
        !           110:            }
        !           111:        }
        !           112:     }
        !           113:   return (string_len);
        !           114: }
        !           115: 
        !           116: /* Find the end of a tilde expansion in STRING, and return the index of
        !           117:    the character which ends the tilde definition.  */
        !           118: static int
        !           119: tilde_find_suffix (string)
        !           120:      char *string;
        !           121: {
        !           122:   register int i, j, string_len;
        !           123:   register char **suffixes = tilde_additional_suffixes;
        !           124: 
        !           125:   string_len = strlen (string);
        !           126: 
        !           127:   for (i = 0; i < string_len; i++)
        !           128:     {
        !           129:       if (string[i] == '/' || !string[i])
        !           130:        break;
        !           131: 
        !           132:       for (j = 0; suffixes && suffixes[j]; j++)
        !           133:        {
        !           134:          if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0)
        !           135:            return (i);
        !           136:        }
        !           137:     }
        !           138:   return (i);
        !           139: }
        !           140: 
        !           141: /* Return a new string which is the result of tilde expanding FILENAME. */
        !           142: char *
        !           143: tilde_expand (filename)
        !           144:      char *filename;
        !           145: {
        !           146:   char *result, *tilde_expand_word ();
        !           147:   int result_size, result_index;
        !           148: 
        !           149:   result_size = result_index = 0;
        !           150:   result = (char *)NULL;
        !           151: 
        !           152:   /* Scan through FILENAME expanding tildes as we come to them. */
        !           153:   while (1)
        !           154:     {
        !           155:       register int start, end;
        !           156:       char *tilde_word, *expansion;
        !           157:       int len;
        !           158: 
        !           159:       /* Make START point to the tilde which starts the expansion. */
        !           160:       start = tilde_find_prefix (filename, &len);
        !           161: 
        !           162:       /* Copy the skipped text into the result. */
        !           163:       /* This test is always true the first time, since result_index
        !           164:         is 0, result_size is 0, and start is >= 0.  So we malloc here.  */
        !           165:       if ((result_index + start + 1) > result_size) {
        !           166:        result_size += (start + 20);
        !           167:        if (result == NULL)
        !           168:          result = (char *)xmalloc  (        1 + result_size);
        !           169:        else
        !           170:          result = (char *)xrealloc (result, 1 + result_size);
        !           171:       }
        !           172: 
        !           173:       strncpy (result + result_index, filename, start);
        !           174:       result_index += start;
        !           175: 
        !           176:       /* Advance FILENAME upto the starting tilde. */
        !           177:       filename += start;
        !           178: 
        !           179:       /* Make END be the index of one after the last character of the
        !           180:         username. */
        !           181:       end = tilde_find_suffix (filename);
        !           182: 
        !           183:       /* If both START and END are zero, we are all done. */
        !           184:       if (!start && !end)
        !           185:        break;
        !           186: 
        !           187:       /* Expand the entire tilde word, and copy it into RESULT. */
        !           188:       tilde_word = (char *)xmalloc (1 + end);
        !           189:       strncpy (tilde_word, filename, end);
        !           190:       tilde_word[end] = '\0';
        !           191:       filename += end;
        !           192: 
        !           193:       expansion = tilde_expand_word (tilde_word);
        !           194:       free (tilde_word);
        !           195: 
        !           196:       len = strlen (expansion);
        !           197:       if ((result_index + len + 1) > result_size)
        !           198:        result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
        !           199: 
        !           200:       strcpy (result + result_index, expansion);
        !           201:       result_index += len;
        !           202:       free (expansion);
        !           203:     }
        !           204: 
        !           205:   result[result_index] = '\0';
        !           206: 
        !           207:   return (result);
        !           208: }
        !           209: 
        !           210: /* Do the work of tilde expansion on FILENAME.  FILENAME starts with a
        !           211:    tilde.  If there is no expansion, call tilde_expansion_failure_hook. */
        !           212: char *
        !           213: tilde_expand_word (filename)
        !           214:      char *filename;
        !           215: {
        !           216:   char *dirname = filename ? savestring (filename) : (char *)NULL;
        !           217: 
        !           218:   if (dirname && *dirname == '~')
        !           219:     {
        !           220:       char *temp_name;
        !           221:       if (!dirname[1] || dirname[1] == '/')
        !           222:        {
        !           223:          /* Prepend $HOME to the rest of the string. */
        !           224:          char *temp_home = (char *)getenv ("HOME");
        !           225: 
        !           226:          temp_name = (char *)alloca (1 + strlen (&dirname[1])
        !           227:                                      + (temp_home? strlen (temp_home) : 0));
        !           228:          temp_name[0] = '\0';
        !           229:          if (temp_home)
        !           230:            strcpy (temp_name, temp_home);
        !           231:          strcat (temp_name, &dirname[1]);
        !           232:          free (dirname);
        !           233:          dirname = savestring (temp_name);
        !           234:        }
        !           235:       else
        !           236:        {
        !           237: #ifndef __MSDOS__
        !           238:          struct passwd *getpwnam (), *user_entry;
        !           239: #endif
        !           240:          char *username = (char *)alloca (257);
        !           241:          int i, c;
        !           242: 
        !           243:          for (i = 1; c = dirname[i]; i++)
        !           244:            {
        !           245:              if (c == '/')
        !           246:                break;
        !           247:              else
        !           248:                username[i - 1] = c;
        !           249:            }
        !           250:          username[i - 1] = '\0';
        !           251: 
        !           252: #ifndef __MSDOS__
        !           253:          if (!(user_entry = getpwnam (username)))
        !           254:            {
        !           255:              /* If the calling program has a special syntax for
        !           256:                 expanding tildes, and we couldn't find a standard
        !           257:                 expansion, then let them try. */
        !           258: #endif
        !           259:              if (tilde_expansion_failure_hook)
        !           260:                {
        !           261:                  char *expansion;
        !           262: 
        !           263:                  expansion =
        !           264:                    (char *)(*tilde_expansion_failure_hook) (username);
        !           265: 
        !           266:                  if (expansion)
        !           267:                    {
        !           268:                      temp_name = (char *)alloca (1 + strlen (expansion)
        !           269:                                                  + strlen (&dirname[i]));
        !           270:                      strcpy (temp_name, expansion);
        !           271:                      strcat (temp_name, &dirname[i]);
        !           272:                      free (expansion);
        !           273:                      goto return_name;
        !           274:                    }
        !           275:                }
        !           276:              /* We shouldn't report errors. */
        !           277: #ifndef __MSDOS__
        !           278:            }
        !           279:          else
        !           280:            {
        !           281:              temp_name = (char *)alloca (1 + strlen (user_entry->pw_dir)
        !           282:                                          + strlen (&dirname[i]));
        !           283:              strcpy (temp_name, user_entry->pw_dir);
        !           284:              strcat (temp_name, &dirname[i]);
        !           285: #endif
        !           286:            return_name:
        !           287:              free (dirname);
        !           288:              dirname = savestring (temp_name);
        !           289: #ifndef __MSDOS__
        !           290:            }
        !           291:            endpwent ();
        !           292: #endif
        !           293:        }
        !           294:     }
        !           295:   return (dirname);
        !           296: }
        !           297: 
        !           298: #if defined (TEST)
        !           299: #undef NULL
        !           300: #include <stdio.h>
        !           301: 
        !           302: main (argc, argv)
        !           303:      int argc;
        !           304:      char **argv;
        !           305: {
        !           306:   char *result, line[512];
        !           307:   int done = 0;
        !           308: 
        !           309:   while (!done)
        !           310:     {
        !           311:       printf ("~expand: ");
        !           312:       fflush (stdout);
        !           313: 
        !           314:       if (!gets (line))
        !           315:        strcpy (line, "done");
        !           316: 
        !           317:       if ((strcmp (line, "done") == 0) ||
        !           318:          (strcmp (line, "quit") == 0) ||
        !           319:          (strcmp (line, "exit") == 0))
        !           320:        {
        !           321:          done = 1;
        !           322:          break;
        !           323:        }
        !           324: 
        !           325:       result = tilde_expand (line);
        !           326:       printf ("  --> %s\n", result);
        !           327:       free (result);
        !           328:     }
        !           329:   exit (0);
        !           330: }
        !           331: 
        !           332: static void memory_error_and_abort ();
        !           333: 
        !           334: static char *
        !           335: xmalloc (bytes)
        !           336:      int bytes;
        !           337: {
        !           338:   char *temp = (char *)malloc (bytes);
        !           339: 
        !           340:   if (!temp)
        !           341:     memory_error_and_abort ();
        !           342:   return (temp);
        !           343: }
        !           344: 
        !           345: static char *
        !           346: xrealloc (pointer, bytes)
        !           347:      char *pointer;
        !           348:      int bytes;
        !           349: {
        !           350:   char *temp;
        !           351: 
        !           352:   if (!pointer)
        !           353:     temp = (char *)malloc (bytes);
        !           354:   else
        !           355:     temp = (char *)realloc (pointer, bytes);
        !           356: 
        !           357:   if (!temp)
        !           358:     memory_error_and_abort ();
        !           359: 
        !           360:   return (temp);
        !           361: }
        !           362: 
        !           363: static void
        !           364: memory_error_and_abort ()
        !           365: {
        !           366:   fprintf (stderr, "readline: Out of virtual memory!\n");
        !           367:   abort ();
        !           368: }
        !           369: 
        !           370: /*
        !           371:  * Local variables:
        !           372:  * compile-command: "gcc -g -DTEST -o tilde tilde.c"
        !           373:  * end:
        !           374:  */
        !           375: #endif /* TEST */
        !           376: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.