diff options
author | Peter Breitenlohner <peb@mppmu.mpg.de> | 2009-03-16 15:13:07 +0000 |
---|---|---|
committer | Peter Breitenlohner <peb@mppmu.mpg.de> | 2009-03-16 15:13:07 +0000 |
commit | e967e0cc978d647040ac5616d389e9007d593464 (patch) | |
tree | 1f33ce27a77473b2e90b549d42399b73d4123497 /Build/source/texk/kpathsea/progname.c | |
parent | 49f1fb6887627cdb7cf524aaef9b92108c894381 (diff) |
new reentrant kpathsea API (from Taco)
git-svn-id: svn://tug.org/texlive/trunk@12401 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/kpathsea/progname.c')
-rw-r--r-- | Build/source/texk/kpathsea/progname.c | 167 |
1 files changed, 92 insertions, 75 deletions
diff --git a/Build/source/texk/kpathsea/progname.c b/Build/source/texk/kpathsea/progname.c index 5aee83ca7a0..2a8fdfb692a 100644 --- a/Build/source/texk/kpathsea/progname.c +++ b/Build/source/texk/kpathsea/progname.c @@ -72,24 +72,6 @@ #define S_IXOTH 0001 #endif -#ifndef HAVE_PROGRAM_INVOCATION_NAME -/* Don't redefine the variables if glibc already has. However, we do - not check for HAVE_PROGRAM_INVOCATION_NAME anywhere else in this - file; rather, we always use our own code to compute them, overwriting - anything that glibc may have provided. This avoids - difficult-to-debug system-dependent behavior, and also universally - supports the second (`progname') argument for dotted texmf.cnf values. - - It would have been better to simply use our own variable names (and - computations) in the first place, but it's not worth losing backward - compatibility to rename them now. */ - -string program_invocation_name = NULL; -string program_invocation_short_name = NULL; -#endif - -/* And the variable for the program we pretend to be. */ -string kpse_program_name = NULL; #ifndef WIN32 /* From a standalone program `ll' to expand symlinks written by Kimbo Mundy. @@ -99,8 +81,6 @@ string kpse_program_name = NULL; that's what kimbo liked. */ #ifdef S_ISLNK -static int ll_verbose = 0; -static int ll_loop = 0; #undef BSIZE #define BSIZE 2048 /* sorry */ @@ -109,7 +89,7 @@ static int ll_loop = 0; /* Read link FN into SYM. */ static void -ReadSymLink P2C(char *, fn, char *, sym) +ReadSymLink (char *fn, char *sym) { register int n = readlink (fn, sym, BSIZE); if (n < 0) { @@ -123,7 +103,7 @@ ReadSymLink P2C(char *, fn, char *, sym) /* Strip first component from S, and also return it in a static buffer. */ static char * -StripFirst P1C(register char *, s) +StripFirst (register char *s) { static char buf[BSIZE]; register char *s1; @@ -151,7 +131,7 @@ StripFirst P1C(register char *, s) /* Strip last component from S, and also return it in a static buffer. */ static char * -StripLast P1C(register char *, s) +StripLast (register char *s) { static char buf[BSIZE]; register char *s1; @@ -168,7 +148,7 @@ StripLast P1C(register char *, s) /* Copy first path element from B to A, removing it from B. */ static void -CopyFirst P2C(register char *, a, char *, b) +CopyFirst (register char *a, char *b) { register int length = strlen (a); @@ -187,7 +167,7 @@ CopyFirst P2C(register char *, a, char *, b) #define EXPRE EX(pre) static char * -expand_symlinks P1C(char *, s) +expand_symlinks (kpathsea kpse, char *s) { static char pre[BSIZE]; /* return value */ char post[BSIZE], sym[BSIZE], tmp[BSIZE], before[BSIZE]; @@ -200,7 +180,9 @@ expand_symlinks P1C(char *, s) possibilities ourselves, so let the kernel do it. And make it conditional so that people can see where the infinite loop is being caused (see engtools#1536). */ - if (!ll_loop) { + /* There used to be a test for a variable |ll_loop| here, but + it was initialized to zero and never updated */ + if (0) { FILE *f = fopen (s, "r"); if (!f && errno == ELOOP) { /* Not worried about other errors, we'll get to them in due course. */ @@ -226,7 +208,7 @@ expand_symlinks P1C(char *, s) ReadSymLink (pre, sym); if (!strncmp (sym, "/", 1)) { - if (ll_verbose) + if (kpse->ll_verbose) printf ("[%s]%s%s -> [%s]%s%s\n", pre, EXPOS, post, sym, EXPOS,post); strcpy (pre, ""); @@ -236,7 +218,7 @@ expand_symlinks P1C(char *, s) if (!strlen (pre) && a == '/') strcpy (pre, "/"); - if (ll_verbose) { + if (kpse->ll_verbose) { sprintf (before, "%s%s[%s]%s%s", pre, EXPRE, tmp, EXPOS, post); printf ("%s -> %s%s[%s]%s%s\n", before, pre, EXPRE, sym, EXPOS,post); } @@ -257,7 +239,7 @@ expand_symlinks P1C(char *, s) StripLast (pre); } - if (done && ll_verbose) { + if (done && kpse->ll_verbose) { for (cp = before; *cp;) *cp++ = ' '; if (strlen (sym)) @@ -280,14 +262,14 @@ expand_symlinks P1C(char *, s) return pre; } #else /* not S_ISLNK */ -#define expand_symlinks(s) (s) +#define expand_symlinks(k,s) (s) #endif /* not S_ISLNK */ /* Remove .'s and ..'s in DIR, to avoid problems with relative symlinks as the program name, etc. This does not canonicalize symlinks. */ static string -remove_dots P1C(string, dir) +remove_dots (kpathsea kpse, string dir) { #ifdef AMIGA return dir; @@ -296,8 +278,8 @@ remove_dots P1C(string, dir) unsigned len; string ret = (string) ""; /* We always reassign. */ - for (c = kpse_filename_component (dir); c; - c = kpse_filename_component (NULL)) { + for (c = kpathsea_filename_component (kpse, dir); c; + c = kpathsea_filename_component (kpse, NULL)) { if (STREQ (c, ".")) { /* If leading ., replace with cwd. Else ignore. */ if (*ret == 0) { @@ -356,12 +338,12 @@ remove_dots P1C(string, dir) absolute. */ string -kpse_selfdir P1C(const_string, argv0) +kpathsea_selfdir (kpathsea kpse, const_string argv0) { string ret = NULL; string self = NULL; - if (kpse_absolute_p (argv0, true)) { + if (kpathsea_absolute_p (kpse, argv0, true)) { self = xstrdup (argv0); } else { #ifdef AMIGA @@ -391,8 +373,8 @@ kpse_selfdir P1C(const_string, argv0) /* Have to check PATH. But don't call kpse_path_search since we don't want to search any ls-R's or do anything special with //'s. */ - for (elt = kpse_path_element (getenv ("PATH")); !self && elt; - elt = kpse_path_element (NULL)) { + for (elt = kpathsea_path_element (kpse, getenv ("PATH")); !self && elt; + elt = kpathsea_path_element (kpse, NULL)) { string name; /* UNIX tradition interprets the empty path element as "." */ @@ -420,16 +402,26 @@ kpse_selfdir P1C(const_string, argv0) if (!self) self = concat3 (".", DIR_SEP_STRING, argv0); - ret = xdirname (remove_dots (expand_symlinks (self))); + ret = xdirname (remove_dots (kpse, expand_symlinks (kpse, self))); free (self); return ret; } + +#if defined (KPSE_COMPAT_API) +string +kpse_selfdir (const_string argv0) +{ + return kpathsea_selfdir (kpse_def, argv0); +} +#endif + + #endif /* not WIN32 */ void -kpse_set_program_name P2C(const_string, argv0, const_string, progname) +kpathsea_set_program_name (kpathsea kpse, const_string argv0, const_string progname) { string ext, sdir, sdir_parent, sdir_grandparent; string s = getenv ("KPATHSEA_DEBUG"); @@ -442,14 +434,14 @@ kpse_set_program_name P2C(const_string, argv0, const_string, progname) /* Set debugging stuff first, in case we end up doing debuggable stuff during this initialization. */ if (s) { - kpathsea_debug |= atoi (s); + kpse->debug |= atoi (s); } #if defined(WIN32) /* Set various info about user. Among many things, ensure that HOME is set. If debug_paths is on, turn on some message if $HOME is not found. */ - if (KPSE_DEBUG_P(KPSE_DEBUG_PATHS)) { + if (KPATHSEA_DEBUG_P (KPSE_DEBUG_PATHS)) { set_home_warning(); } init_user_info(); @@ -466,7 +458,7 @@ kpse_set_program_name P2C(const_string, argv0, const_string, progname) flags = _O_CREAT | _O_APPEND | _O_WRONLY; } else { flags = _O_CREAT | _O_TRUNC | _O_WRONLY; - xputenv("KPATHSEA_DEBUG_APPEND", "yes"); + kpathsea_xputenv(kpse, "KPATHSEA_DEBUG_APPEND", "yes"); } } @@ -494,16 +486,16 @@ kpse_set_program_name P2C(const_string, argv0, const_string, progname) /* SearchPath() always gives back an absolute directory */ if (SearchPath(NULL, argv0, ".exe", PATH_MAX, short_path, &fp) == 0) - FATAL1("Can't determine where the executable %s is.\n", argv0); + LIB_FATAL1("Can't determine where the executable %s is.\n", argv0); if (!win32_get_long_filename(short_path, path, sizeof(path))) { - FATAL1("This path points to an invalid file : %s\n", short_path); + LIB_FATAL1("This path points to an invalid file : %s\n", short_path); } /* slashify the dirname */ for (fp = path; fp && *fp; fp++) if (IS_DIR_SEP(*fp)) *fp = DIR_SEP; /* sdir will be the directory of the executable, ie: c:/TeX/bin */ sdir = xdirname(path); - program_invocation_name = xstrdup(xbasename(path)); + kpse->invocation_name = xstrdup(xbasename(path)); } #elif defined(__DJGPP__) @@ -555,85 +547,110 @@ kpse_set_program_name P2C(const_string, argv0, const_string, progname) if (IS_DIR_SEP (*fp)) *fp = DIR_SEP; - program_invocation_name = xstrdup (long_progname); + kpse->invocation_name = xstrdup (long_progname); } else /* If `_truename' failed, God help them, because we won't... */ - program_invocation_name = xstrdup (argv0); + kpse->invocation_name = xstrdup (argv0); } else - program_invocation_name = xstrdup (argv0); + kpse->invocation_name = xstrdup (argv0); #else /* !WIN32 && !__DJGPP__ */ - program_invocation_name = xstrdup (argv0); + kpse->invocation_name = xstrdup (argv0); #endif /* We need to find SELFAUTOLOC *before* removing the ".exe" suffix from the program_name, otherwise the PATH search inside kpse_selfdir will fail, since `prog' doesn't exists as a file, there's `prog.exe' instead. */ #ifndef WIN32 - sdir = kpse_selfdir (program_invocation_name); + sdir = kpathsea_selfdir (kpse, kpse->invocation_name); #endif /* SELFAUTODIR is actually the parent of the invocation directory, and SELFAUTOPARENT the grandparent. This is how teTeX did it. */ - xputenv ("SELFAUTOLOC", sdir); + kpathsea_xputenv (kpse, "SELFAUTOLOC", sdir); sdir_parent = xdirname (sdir); - xputenv ("SELFAUTODIR", sdir_parent); + kpathsea_xputenv (kpse, "SELFAUTODIR", sdir_parent); sdir_grandparent = xdirname (sdir_parent); - xputenv ("SELFAUTOPARENT", sdir_grandparent); + kpathsea_xputenv (kpse, "SELFAUTOPARENT", sdir_grandparent); free (sdir); free (sdir_parent); free (sdir_grandparent); - program_invocation_short_name = (string)xbasename (program_invocation_name); + kpse->invocation_short_name = xstrdup((string)xbasename (kpse->invocation_name)); if (progname) { - kpse_program_name = xstrdup (progname); + kpse->program_name = xstrdup (progname); } else { /* If configured --enable-shared and running from the build directory with the wrapper scripts (e.g., for make check), the binaries will be named foo.exe instead of foo. Or possibly if we're running on a DOSISH system. */ - ext = find_suffix (program_invocation_short_name); + ext = find_suffix (kpse->invocation_short_name); if (ext && FILESTRCASEEQ (ext, "exe")) { - kpse_program_name = remove_suffix (program_invocation_short_name); + kpse->program_name = remove_suffix (kpse->invocation_short_name); } else { - kpse_program_name = xstrdup (program_invocation_short_name); + kpse->program_name = xstrdup (kpse->invocation_short_name); } } - xputenv ("progname", kpse_program_name); + /* Some of the utility routines (like atou() and xfopen()) will use + FATAL and variations thereof (see lib.h) if there is a problem. + + The next trick makes it possible for that message to report some useful + name instead of (NULL), if the backward compatible is compiled in. */ + +#if defined (KPSE_COMPAT_API) + if (kpse!=kpse_def) { + kpse_def->invocation_name = xstrdup(kpse->invocation_name); + kpse_def->invocation_short_name = xstrdup(kpse->invocation_short_name); + } +#endif + + kpathsea_xputenv (kpse, "progname", kpse->program_name); } + /* This function is deprecated, because when we pretend to have a different - name it will look for _that_ name in the PATH if program_invocation_name + name it will look for _that_ name in the PATH if kpse->invocation_name is not defined. */ +#if defined (KPSE_COMPAT_API) void -kpse_set_progname P1C(const_string, argv0) +kpse_set_program_name (const_string argv0, const_string progname) { - kpse_set_program_name (argv0, NULL); + kpathsea_set_program_name (kpse_def, argv0, progname); } + +void +kpse_set_progname (const_string argv0) +{ + kpathsea_set_program_name (kpse_def, argv0, NULL); +} +#endif + #ifdef TEST -void +int main (int argc, char **argv) { - puts (remove_dots ("/w/kpathsea")); - puts (remove_dots ("/w//kpathsea")); - puts (remove_dots ("/w/./kpathsea")); - puts (remove_dots (".")); - puts (remove_dots ("./")); - puts (remove_dots ("./.")); - puts (remove_dots ("../kpathsea")); - puts (remove_dots ("/kpathsea/../foo")); - puts (remove_dots ("/../w/kpathsea")); - puts (remove_dots ("/../w/kpathsea/.")); - puts (remove_dots ("/te/share/texmf/../../../../bin/gnu")); + kpathsea kpse = xcalloc(1, sizeof(kpathsea_instance)); + kpathsea_set_program_name(kpse, argv[0], NULL); + puts (remove_dots (kpse,"/w/kpathsea")); + puts (remove_dots (kpse,"/w//kpathsea")); + puts (remove_dots (kpse,"/w/./kpathsea")); + puts (remove_dots (kpse,".")); + puts (remove_dots (kpse,"./")); + puts (remove_dots (kpse,"./.")); + puts (remove_dots (kpse,"../kpathsea")); + puts (remove_dots (kpse,"/kpathsea/../foo")); + puts (remove_dots (kpse,"/../w/kpathsea")); + puts (remove_dots (kpse,"/../w/kpathsea/.")); + puts (remove_dots (kpse,"/te/share/texmf/../../../../bin/gnu")); } /* Local variables: -standalone-compile-command: "gcc -g -I. -I.. -DTEST progname.c STATIC/libkpathsea.a" +standalone-compile-command: "gcc -g -I. -I.. -DTEST progname.c kpathsea.a" End: */ #endif /* TEST */ |