Mercurial > hg > xemacs-beta
diff src/mule-mcpath.c @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | |
children | 8de8e3f6228a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mule-mcpath.c Mon Aug 13 11:20:41 2007 +0200 @@ -0,0 +1,306 @@ +/* Support for Non-ASCII Path Name + Copyright (C) 1985, 1986, 1992, 1993, 1995 Free Software Foundation, Inc. + Copyright (C) 1995 Sun Microsystems, Inc. + +This file is part of XEmacs. + +XEmacs is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +XEmacs is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with XEmacs; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Synched up with: Mule 2.3. Not in FSF. */ + +/* mcpath.h should be included in config.h */ +#include <config.h> +#include "lisp.h" + +#include "sysfile.h" +#include "buffer.h" +#include "mule.h" + +Lisp_Object Qpathname_coding_system = 0; + +static void +mcpath_encode_code (struct Lisp_Coding_System *cp) +{ + Lisp_Object coding_system; + + coding_system = Fsymbol_value (Qpathname_coding_system); + + mule_encode_code (coding_system, cp); + CODE_CNTL (cp) |= CC_END; +} + +static int +mule_encode_path_1 (unsigned char *src, unsigned int srcsize, + unsigned char *dst, unsigned int dstsize) +{ + struct Lisp_Coding_System code; + + mcpath_encode_code (&code); + if (CODE_TYPE (&code) > MULE_AUTOCONV) + { + unsigned char *buf; + + /* get_conversion_buffer () is not */ + /* re-entrant. */ + buf = (unsigned char *) alloca (MULE_ENCODE_BUF_SIZE (srcsize, &code)); + if (buf) + { + int len; + Lisp_Object dummy = Qnil; + + len = mule_encode (&code, src, buf, srcsize, &dummy); + if (!CODE_CHAR (&code) && len <= dstsize) + { + memcpy (dst, buf, len); + return len; + } + } + } + return -1; /* use original */ +} + +static unsigned char * +mule_decode_path_1 (unsigned char *src, unsigned char *dst, + unsigned int dstsize) +{ + struct Lisp_Coding_System code; + + mcpath_encode_code (&code); + if (CODE_TYPE (&code) > MULE_AUTOCONV) + { + int len; + unsigned char *buf; + + len = strlen (src) + 1; /* + 1 for '\0' */ + + /* get_conversion_buffer () is not */ + /* re-entrant. */ + buf = (unsigned char *) alloca (MULE_DECODE_BUF_SIZE (len, &code)); + if (buf) + { + CODE_CNTL (&code) |= CC_END; + len = mule_decode (&code, src, buf, len); + if (!CODE_CHAR (&code) && len <= dstsize) + { + memcpy (dst, buf, len); /* len should include '\0' */ + return dst; + } + } + } + return src; +} + +static unsigned char * +mule_decode_path (unsigned char *path, unsigned char ext_path[MC_MAXPATHLEN]) +{ + return + (Qpathname_coding_system + ? mule_decode_path_1 (path, ext_path, MC_MAXPATHLEN) + : path); /* in case of before initialization */ +} + +static unsigned char * +mule_encode_path (unsigned char *path, unsigned char *encode_buffer, + unsigned int size) +{ + int len; + + len = mule_encode_path_1 (path, strlen (path), encode_buffer, size); + if (len > 0) + path = encode_buffer; +#ifdef MSDOS + /* convert the MSDOS style path delimiter to the UNIX style. Note + that now the code is *internal*, so we can simply compare each + character with '\\'. And this operation will alter the contents + of Lisp Object, PATH. */ + { + unsigned char *p = path; + + while (*p) + { + if (*p == '\\') + *p = '/'; + p++; + } + } +#endif /* MSDOS */ + return path; +} + +#if 0 /* example of how they do it (similar junk deleted) ... */ + +int +mc_creat (unsigned char *path, int mode) +{ + unsigned char buffer[MC_MAXPATHLEN]; + return creat (mule_decode_path (path, buffer), mode); +} + +int +mc_readlink (unsigned char *path, unsigned char *buf, int size) +{ + unsigned char buffer[MC_MAXPATHLEN], buffer2[MAXPATHLEN]; + int nread; + + nread = readlink (mule_decode_path (path, buffer), buffer2, MAXPATHLEN); + if (nread > 0) + { + int len; + unsigned char *p; + + len = mule_encode_path_1 (buffer2, nread, buffer, sizeof (buffer)); + if (0 <= len && len <= size) + { + memcpy (buf, buffer, len); + return len; + } + } + return -1; +} + +int +mc_chdir (unsigned char *path) +{ + unsigned char buffer[MC_MAXPATHLEN]; + + path = mule_decode_path (path, buffer); + +#ifdef MSDOS + if ((path[0] != 0) && (path[1] == ':')) + { + int drive = (tolower (path[0]) - 'a'); + if (getdisk () != drive) + setdisk (drive); + } + + /* If path != "/" and path != "a:/" and path ends with slash, remove + it. */ + { + int len = strlen (path); + + if (strcmp (path + 1, ":/") && (len > 1) && (path[len - 1] == '/')) + { + if (path != buffer) /* It is not good to modify original path. */ + { + memcpy (buffer, path, len - 1); /* no need to copy last /. */ + path = buffer; + } + path[len - 1] = 0; + } + } +#endif /* MSDOS */ + + return chdir (path); +} + +#ifdef MSDOS +#ifndef HAVE_GETWD +unsigned char * +mc_getcwd (unsigned char *null, size_t size) +{ + unsigned char buffer[MAXPATHLEN]; + unsigned char *path; + + path = (unsigned char *) getcwd ((char *)buffer, MAXPATHLEN); + if (path) + { + /* here, should be (path == buffer). */ + path = (unsigned char *) xmalloc (MC_MAXPATHLEN); /* MSDOS */ + if (path) + { + int len; + int buffer_length = strlen (buffer) + 1; + + len = mule_encode_path_1 (buffer, buffer_length, path, MC_MAXPATHLEN); + if (len < 0) + { + /* conversion failed. use value that is returned from system. */ + memcpy (path, buffer, buffer_length); + } + } + } + return path; +} +#else /* HAVE_GETWD */ +unsigned char * +mc_getwd (unsigned char path[]) +{ + unsigned char *p; + + p = getwd (path); + if (p) + { + unsigned char buffer[MC_MAXPATHLEN]; + int len; + + len = mule_encode_path_1 (path, strlen (path) + 1, buffer, sizeof buffer); + if (len > 0) + { + memcpy (path, buffer, len); + } + } + return p; +} +#endif /* HAVE_GETWD */ +#endif /* MSDOS */ + +/* In callproc.c, execvp() is called like this: + * execvp (new_argv[0], new_argv); + * following implement depends this. + */ +#ifndef NO_MC_EXECVP +void +mc_execvp (unsigned char *path, unsigned char *argv[]) +{ + unsigned char buffer[MC_MAXPATHLEN]; + argv[0] = path = mule_decode_path (path, buffer); + execvp (path, argv); +} +#endif /* !NO_MC_EXECVP */ + +static DIRENTRY mcpath_directory_entry; +DIRENTRY * +mc_readdir (DIR *d) +{ + SYSTEM_DIRENTRY *sp; + DIRENTRY *dp = &mcpath_directory_entry; + + sp = readdir (d); + if (!sp) return 0; + +#ifndef MSDOS + dp->d_ino = sp->d_ino; +#endif /* MSDOS */ + { /* copy d_name with conversion. */ + int len; + + len = mule_encode_path_1 (sp->d_name, NAMLEN (sp), + dp->d_name, sizeof (dp->d_name) - 1); + if (len < 0) + { + len = NAMLEN (sp); +#ifdef MCPATH_ASSERT + assert (len < sizeof (dp->d_name)); +#endif + memcpy (dp->d_name, sp->d_name, len); + } + dp->d_name[len] = 0; + } + return dp; +} + +#endif /* 0 */ +