/[emacs]/emacs/src/fileio.c
ViewVC logotype

Diff of /emacs/src/fileio.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.419 by pj, Sun Oct 21 13:27:20 2001 UTC revision 1.420 by pj, Mon Oct 22 06:26:10 2001 UTC
# Line 1647  See also the function `substitute-in-fil Line 1647  See also the function `substitute-in-fil
1647    return make_string (target, o - target);    return make_string (target, o - target);
1648  }  }
1649    
 #if 0  
 /* Changed this DEFUN to a DEAFUN, so as not to confuse `make-docfile'.  */  
 DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,  
   "Convert FILENAME to absolute, and canonicalize it.\n\  
 Second arg DEFAULT is directory to start with if FILENAME is relative\n\  
  (does not start with slash); if DEFAULT is nil or missing,\n\  
 the current buffer's value of default-directory is used.\n\  
 Filenames containing `.' or `..' as components are simplified;\n\  
 initial `~/' expands to your home directory.\n\  
 See also the function `substitute-in-file-name'.")  
      (name, defalt)  
      Lisp_Object name, defalt;  
 {  
   unsigned char *nm;  
   
   register unsigned char *newdir, *p, *o;  
   int tlen;  
   unsigned char *target;  
   struct passwd *pw;  
   int lose;  
 #ifdef VMS  
   unsigned char * colon = 0;  
   unsigned char * close = 0;  
   unsigned char * slash = 0;  
   unsigned char * brack = 0;  
   int lbrack = 0, rbrack = 0;  
   int dots = 0;  
 #endif /* VMS */  
   
   CHECK_STRING (name, 0);  
   
 #ifdef VMS  
   /* Filenames on VMS are always upper case.  */  
   name = Fupcase (name);  
 #endif  
   
   nm = XSTRING (name)->data;  
   
   /* If nm is absolute, flush ...// and detect /./ and /../.  
      If no /./ or /../ we can return right away.  */  
   if (  
       nm[0] == '/'  
 #ifdef VMS  
       || index (nm, ':')  
 #endif /* VMS */  
       )  
     {  
       p = nm;  
       lose = 0;  
       while (*p)  
         {  
           if (p[0] == '/' && p[1] == '/'  
 #ifdef APOLLO  
               /* // at start of filename is meaningful on Apollo system.  */  
               && nm != p  
 #endif /* APOLLO */  
               )  
             nm = p + 1;  
           if (p[0] == '/' && p[1] == '~')  
             nm = p + 1, lose = 1;  
           if (p[0] == '/' && p[1] == '.'  
               && (p[2] == '/' || p[2] == 0  
                   || (p[2] == '.' && (p[3] == '/' || p[3] == 0))))  
             lose = 1;  
 #ifdef VMS  
           if (p[0] == '\\')  
             lose = 1;  
           if (p[0] == '/') {  
             /* if dev:[dir]/, move nm to / */  
             if (!slash && p > nm && (brack || colon)) {  
               nm = (brack ? brack + 1 : colon + 1);  
               lbrack = rbrack = 0;  
               brack = 0;  
               colon = 0;  
             }  
             slash = p;  
           }  
           if (p[0] == '-')  
 #ifndef VMS4_4  
             /* VMS pre V4.4,convert '-'s in filenames. */  
             if (lbrack == rbrack)  
               {  
                 if (dots < 2)   /* this is to allow negative version numbers */  
                   p[0] = '_';  
               }  
             else  
 #endif /* VMS4_4 */  
               if (lbrack > rbrack &&  
                   ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') &&  
                    (p[1] == '.' || p[1] == ']' || p[1] == '>')))  
                 lose = 1;  
 #ifndef VMS4_4  
               else  
                 p[0] = '_';  
 #endif /* VMS4_4 */  
           /* count open brackets, reset close bracket pointer */  
           if (p[0] == '[' || p[0] == '<')  
             lbrack++, brack = 0;  
           /* count close brackets, set close bracket pointer */  
           if (p[0] == ']' || p[0] == '>')  
             rbrack++, brack = p;  
           /* detect ][ or >< */  
           if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))  
             lose = 1;  
           if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')  
             nm = p + 1, lose = 1;  
           if (p[0] == ':' && (colon || slash))  
             /* if dev1:[dir]dev2:, move nm to dev2: */  
             if (brack)  
               {  
                 nm = brack + 1;  
                 brack = 0;  
               }  
             /* If /name/dev:, move nm to dev: */  
             else if (slash)  
               nm = slash + 1;  
             /* If node::dev:, move colon following dev */  
             else if (colon && colon[-1] == ':')  
               colon = p;  
             /* If dev1:dev2:, move nm to dev2: */  
             else if (colon && colon[-1] != ':')  
               {  
                 nm = colon + 1;  
                 colon = 0;  
               }  
           if (p[0] == ':' && !colon)  
             {  
               if (p[1] == ':')  
                 p++;  
               colon = p;  
             }  
           if (lbrack == rbrack)  
             if (p[0] == ';')  
               dots = 2;  
             else if (p[0] == '.')  
               dots++;  
 #endif /* VMS */  
           p++;  
         }  
       if (!lose)  
         {  
 #ifdef VMS  
           if (index (nm, '/'))  
             return build_string (sys_translate_unix (nm));  
 #endif /* VMS */  
           if (nm == XSTRING (name)->data)  
             return name;  
           return build_string (nm);  
         }  
     }  
   
   /* Now determine directory to start with and put it in NEWDIR */  
   
   newdir = 0;  
   
   if (nm[0] == '~')             /* prefix ~ */  
     if (nm[1] == '/'  
 #ifdef VMS  
         || nm[1] == ':'  
 #endif /* VMS */  
         || nm[1] == 0)/* ~/filename */  
       {  
         if (!(newdir = (unsigned char *) egetenv ("HOME")))  
           newdir = (unsigned char *) "";  
         nm++;  
 #ifdef VMS  
         nm++;                   /* Don't leave the slash in nm.  */  
 #endif /* VMS */  
       }  
     else  /* ~user/filename */  
       {  
         /* Get past ~ to user */  
         unsigned char *user = nm + 1;  
         /* Find end of name. */  
         unsigned char *ptr = (unsigned char *) index (user, '/');  
         int len = ptr ? ptr - user : strlen (user);  
 #ifdef VMS  
         unsigned char *ptr1 = index (user, ':');  
         if (ptr1 != 0 && ptr1 - user < len)  
           len = ptr1 - user;  
 #endif /* VMS */  
         /* Copy the user name into temp storage. */  
         o = (unsigned char *) alloca (len + 1);  
         bcopy ((char *) user, o, len);  
         o[len] = 0;  
   
         /* Look up the user name. */  
         pw = (struct passwd *) getpwnam (o + 1);  
         if (!pw)  
           error ("\"%s\" isn't a registered user", o + 1);  
   
         newdir = (unsigned char *) pw->pw_dir;  
   
         /* Discard the user name from NM.  */  
         nm += len;  
       }  
   
   if (nm[0] != '/'  
 #ifdef VMS  
       && !index (nm, ':')  
 #endif /* not VMS */  
       && !newdir)  
     {  
       if (NILP (defalt))  
         defalt = current_buffer->directory;  
       CHECK_STRING (defalt, 1);  
       newdir = XSTRING (defalt)->data;  
     }  
   
   /* Now concatenate the directory and name to new space in the stack frame */  
   
   tlen = (newdir ? strlen (newdir) + 1 : 0) + strlen (nm) + 1;  
   target = (unsigned char *) alloca (tlen);  
   *target = 0;  
   
   if (newdir)  
     {  
 #ifndef VMS  
       if (nm[0] == 0 || nm[0] == '/')  
         strcpy (target, newdir);  
       else  
 #endif  
       file_name_as_directory (target, newdir);  
     }  
   
   strcat (target, nm);  
 #ifdef VMS  
   if (index (target, '/'))  
     strcpy (target, sys_translate_unix (target));  
 #endif /* VMS */  
   
   /* Now canonicalize by removing /. and /foo/.. if they appear */  
   
   p = target;  
   o = target;  
   
   while (*p)  
     {  
 #ifdef VMS  
       if (*p != ']' && *p != '>' && *p != '-')  
         {  
           if (*p == '\\')  
             p++;  
           *o++ = *p++;  
         }  
       else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)  
         /* brackets are offset from each other by 2 */  
         {  
           p += 2;  
           if (*p != '.' && *p != '-' && o[-1] != '.')  
             /* convert [foo][bar] to [bar] */  
             while (o[-1] != '[' && o[-1] != '<')  
               o--;  
           else if (*p == '-' && *o != '.')  
             *--p = '.';  
         }  
       else if (p[0] == '-' && o[-1] == '.' &&  
                (p[1] == '.' || p[1] == ']' || p[1] == '>'))  
         /* flush .foo.- ; leave - if stopped by '[' or '<' */  
         {  
           do  
             o--;  
           while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');  
           if (p[1] == '.')      /* foo.-.bar ==> bar.  */  
             p += 2;  
           else if (o[-1] == '.') /* '.foo.-]' ==> ']' */  
             p++, o--;  
           /* else [foo.-] ==> [-] */  
         }  
       else  
         {  
 #ifndef VMS4_4  
           if (*p == '-' &&  
               o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&  
               p[1] != ']' && p[1] != '>' && p[1] != '.')  
             *p = '_';  
 #endif /* VMS4_4 */  
           *o++ = *p++;  
         }  
 #else /* not VMS */  
       if (*p != '/')  
         {  
           *o++ = *p++;  
         }  
       else if (!strncmp (p, "//", 2)  
 #ifdef APOLLO  
                /* // at start of filename is meaningful in Apollo system.  */  
                && o != target  
 #endif /* APOLLO */  
                )  
         {  
           o = target;  
           p++;  
         }  
       else if (p[0] == '/' && p[1] == '.' &&  
                (p[2] == '/' || p[2] == 0))  
         p += 2;  
       else if (!strncmp (p, "/..", 3)  
                /* `/../' is the "superroot" on certain file systems.  */  
                && o != target  
                && (p[3] == '/' || p[3] == 0))  
         {  
           while (o != target && *--o != '/')  
             ;  
 #ifdef APOLLO  
           if (o == target + 1 && o[-1] == '/' && o[0] == '/')  
             ++o;  
           else  
 #endif /* APOLLO */  
           if (o == target && *o == '/')  
             ++o;  
           p += 3;  
         }  
       else  
         {  
           *o++ = *p++;  
         }  
 #endif /* not VMS */  
     }  
   
   return make_string (target, o - target);  
 }  
 #endif  
1650    
1651  DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name,  DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name,
1652         Ssubstitute_in_file_name, 1, 1, 0,         Ssubstitute_in_file_name, 1, 1, 0,

Legend:
Removed from v.1.419  
changed lines
  Added in v.1.420

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26