From 30f6c4d00de40b38da64016114658a1f02063fe4 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 4 Feb 2018 23:23:31 +0000 Subject: casefolding fallback search for Unix git-svn-id: svn://tug.org/texlive/trunk@46545 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/kpathsea/ChangeLog | 50 +++ Build/source/texk/kpathsea/NEWS | 6 + Build/source/texk/kpathsea/c-auto.in | 2 +- Build/source/texk/kpathsea/configure | 24 +- Build/source/texk/kpathsea/doc/kpathsea.info | 516 +++++++++++++++++------- Build/source/texk/kpathsea/doc/kpathsea.texi | 316 ++++++++++++--- Build/source/texk/kpathsea/kpsewhich.c | 26 +- Build/source/texk/kpathsea/pathsearch.c | 486 +++++++++++++++++----- Build/source/texk/kpathsea/tests/kpsewhich.test | 16 +- Build/source/texk/kpathsea/texmf.cnf | 7 + Build/source/texk/kpathsea/version.ac | 4 +- 11 files changed, 1103 insertions(+), 350 deletions(-) (limited to 'Build') diff --git a/Build/source/texk/kpathsea/ChangeLog b/Build/source/texk/kpathsea/ChangeLog index 1feb2ffbb0c..fafb1ee3ba6 100644 --- a/Build/source/texk/kpathsea/ChangeLog +++ b/Build/source/texk/kpathsea/ChangeLog @@ -1,3 +1,53 @@ +2018-02-04 Karl Berry + + * texmf.cnf (texmf_casefold_search): new configuration value + for Unix, default 1. Latest thread about this longstanding issue: + http://tug.org/pipermail/tex-live/2017-September/040619.html + + * version.ac: move to 6.3.0 since I guess this is a new + (compatible [enough]) interface. + * NEWS: mention it. + * doc/kpathsea.texi: document it. + (Casefolding search), + (Casefolding rationale), + (Casefolding examples): new nodes. + (Path searching options): new option [-no]-casefold-search + for kpsewhich. + + * pathsearch.c (KPSE_CASEFOLDING_SEARCH): new compile-time macro + to support case-insensitive searches on case-sensitive operating + systems, that is, not Windows. Most other changes here are + conditional on it. + + (print_space_list): helper fn for debugging output. + (readable_file_fn_type): new typedef for casefold_readable_file + and kpathsea_readable_file. + (casefold_readable_file): new fn to check for a file ignoring case. + (dir_list_search), + (dir_list_search_list): take an additional function pointer argument + and call it, instead of only kpathsea_readable_file. Return + the matched name instead of the original name. (This would have + caused failure before with the ENAMETOOLONG kludge; guess that + never actually happens.) + (absolute_search), + (path_search): also do casefolded search if enabled and requested. + Also free passed name in callers. + (kpathsea_path_search_list_generic): call absolute_search + instead of kpathsea_readable_file; merge returned lists; + also do casefolded search if enabled and requested. + + (print_tab_list) [TEST]: another helper fn to print test results. + (test_path_search_list_generic) [TEST]: new test fn for some + minimal casefolding tests. + (main): call it, and rearrange tests. + (standalone-compile-command): current to current (TeX Live) reality. + + * kpsewhich.c (long_options): new options [-no]-casefold-search + to override the default for casefolded searches. + (read_command_line): handle them with xputenv on texmf_casefold_search. + + * tests/kpsewhich.test: do a few casefolding tests. + 2018-02-01 Karl Berry * lib.h (KPSE_CNF_P): new macro. diff --git a/Build/source/texk/kpathsea/NEWS b/Build/source/texk/kpathsea/NEWS index 45b572c00bf..04b493e0f6e 100644 --- a/Build/source/texk/kpathsea/NEWS +++ b/Build/source/texk/kpathsea/NEWS @@ -1,5 +1,11 @@ +$Id$ This file records noteworthy changes. (Public domain.) +6.3.0 (for TeX Live 2018) +* New configuration value texmf_casefold_search to fall back to + case-insensitive search in non-system directories if there is no exact + match; only relevant on Unix. + 6.2.3 (for TeX Live 2017, 19 May 2017) * .OTF treated like .otf. * texmf.cnf: mpost removed from default shell_escape_commands. diff --git a/Build/source/texk/kpathsea/c-auto.in b/Build/source/texk/kpathsea/c-auto.in index aaf1a686a44..0d7f71e8ed3 100644 --- a/Build/source/texk/kpathsea/c-auto.in +++ b/Build/source/texk/kpathsea/c-auto.in @@ -23,7 +23,7 @@ #define KPATHSEA_C_AUTO_H /* kpathsea: the version string. */ -#define KPSEVERSION "kpathsea version 6.2.4/dev" +#define KPSEVERSION "kpathsea version 6.3.0/dev" /* Define to 1 if the `closedir' function returns void instead of `int'. */ #undef CLOSEDIR_VOID diff --git a/Build/source/texk/kpathsea/configure b/Build/source/texk/kpathsea/configure index cfc1f019d49..6a95b8df36f 100755 --- a/Build/source/texk/kpathsea/configure +++ b/Build/source/texk/kpathsea/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for Kpathsea 6.2.4/dev. +# Generated by GNU Autoconf 2.69 for Kpathsea 6.3.0/dev. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Kpathsea' PACKAGE_TARNAME='kpathsea' -PACKAGE_VERSION='6.2.4/dev' -PACKAGE_STRING='Kpathsea 6.2.4/dev' +PACKAGE_VERSION='6.3.0/dev' +PACKAGE_STRING='Kpathsea 6.3.0/dev' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1339,7 +1339,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Kpathsea 6.2.4/dev to adapt to many kinds of systems. +\`configure' configures Kpathsea 6.3.0/dev to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1409,7 +1409,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Kpathsea 6.2.4/dev:";; + short | recursive ) echo "Configuration of Kpathsea 6.3.0/dev:";; esac cat <<\_ACEOF @@ -1537,7 +1537,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Kpathsea configure 6.2.4/dev +Kpathsea configure 6.3.0/dev generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2376,7 +2376,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Kpathsea $as_me 6.2.4/dev, which was +It was created by Kpathsea $as_me 6.3.0/dev, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2757,10 +2757,10 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. -KPSEVERSION=6.2.4/dev +KPSEVERSION=6.3.0/dev -KPSE_LT_VERSINFO=8:4:2 +KPSE_LT_VERSINFO=9:0:3 @@ -8071,7 +8071,7 @@ fi # Define the identity of the package. PACKAGE='kpathsea' - VERSION='6.2.4/dev' + VERSION='6.3.0/dev' cat >>confdefs.h <<_ACEOF @@ -14695,7 +14695,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Kpathsea $as_me 6.2.4/dev, which was +This file was extended by Kpathsea $as_me 6.3.0/dev, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14761,7 +14761,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -Kpathsea config.status 6.2.4/dev +Kpathsea config.status 6.3.0/dev configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/Build/source/texk/kpathsea/doc/kpathsea.info b/Build/source/texk/kpathsea/doc/kpathsea.info index 98c5bd794e1..339edf9af2a 100644 --- a/Build/source/texk/kpathsea/doc/kpathsea.info +++ b/Build/source/texk/kpathsea/doc/kpathsea.info @@ -3,7 +3,7 @@ kpathsea.texi. This file documents the Kpathsea library for path searching. - Copyright (C) 1996-2017 Karl Berry & Olaf Weber. + Copyright (C) 1996-2018 Karl Berry & Olaf Weber. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are @@ -37,7 +37,7 @@ Kpathsea library **************** This manual documents the Kpathsea library for path searching. It -corresponds to version 6.2.4, released in June 2017. +corresponds to version 6.3.0, released in February 2018. * Menu: @@ -61,8 +61,8 @@ File: kpathsea.info, Node: Introduction, Next: unixtex.ftp, Prev: Top, Up: T 1 Introduction ************** -This manual corresponds to version 6.2.4 of the Kpathsea library, -released in June 2017. +This manual corresponds to version 6.3.0 of the Kpathsea library, +released in February 2018. The library's fundamental purpose is to return a filename from a list of directories specified by the user, similar to what shells do when @@ -80,27 +80,29 @@ this library: Other software that we do not maintain also uses it. Kpathsea is now maintained as part of the TeX Live distribution -(). For information on configuration, building, -installing, and more, *note (tlbuild)::. +(), which includes several more Kpathsea-using +programs. For information on configuration, building, installing, and +more, *note (tlbuild)::. The library is still actively maintained. If you have comments or suggestions, please send along (*note Reporting bugs::). The Kpathsea library is distributed under the GNU Library General -Public License (LGPL). In short, this means if you write a program using -the library, you must (offer to) distribute the source to the library, -along with any changes you have made, and allow anyone to modify the -library source and distribute their modifications. It does not mean you -have to distribute the source to your program, although we hope you -will. See accompanying files for the text of the GNU licenses, or -. +Public License (LGPL), version 2.1 or (at your option) any later +version. In short, this means if you write a program using the library, +you must (offer to) distribute the source to the library, along with any +changes you have made, and allow anyone to modify the library source and +distribute their modifications. It does not mean you have to distribute +the source to your program using the library, although we hope you will. +See accompanying files for the text of the GNU licenses, or +. If you know enough about TeX to be reading this manual, then you (or your institution) should consider joining the TeX Users Group (if you're already a member, thanks!). TUG produces the periodical 'TUGboat', sponsors an annual meeting and publishes the proceedings, and arranges courses on TeX for all levels of users throughout the world. See - for information. + for information. * Menu: @@ -185,14 +187,13 @@ continues. Karl had been looking for some time for someone to take up part of the burden, and I volunteered. [Karl writes again.] Indeed, time goes on. As of 2006 or so, Olaf's -available time for Kpathsea became rather reduced, and I started taking -overall care of it again, although I did not do any significant new -development. In 2009, Taco Hoekwater made a major rearrangement to make -the library suitable for use within the MetaPost library (*note -Programming overview::). Also, for some years now, Peter Breitenlohner -has made many improvements to the infrastructure and kept up-to-date -with respect to the overall TeX Live build, where Kpathsea is now -maintained. +available time for Kpathsea was reduced, and I started taking overall +care of it again, although I did not do any significant new development. +In 2009, Taco Hoekwater implemented a major rearrangement to make the +library suitable for use within the MetaPost library (*note Programming +overview::). Also, for some years now, Peter Breitenlohner has made +many improvements to the infrastructure and kept it up-to-date with +respect to the overall TeX Live build, where Kpathsea is now maintained.  File: kpathsea.info, Node: unixtex.ftp, Next: Security, Prev: Introduction, Up: Top @@ -378,6 +379,7 @@ provides. For information about searching for particular file types * Searching overview:: Basic scheme for searching. * Path sources:: Where search paths can be defined. * Path expansion:: Special constructs in search paths. +* Casefolding search:: Fallback to case-insensitive search. * Filename database:: Using an externally-built list to search. * Invoking kpsewhich:: Standalone path lookup. @@ -419,10 +421,16 @@ the disk for them. Therefore, if you fail to update 'ls-R' when you install a new VF file, it will not be found. Each path element is checked in turn: first the database, then the -disk. If a match is found, the search stops and the result is returned. -This avoids possibly-expensive processing of path specifications that -are never needed on a particular run. (Unless the search explicitly -requested all matches.) +disk. If a match is found, the search stops and the result is returned +(unless the search explicitly requested all matches). This avoids +possibly-expensive processing of path specifications that are never +needed on a particular run. + + On Unix-like systems, if no match is found by any of the above, and +the path element allows checking the filesystem (per the above), a final +check is made for a case-insensitive match. Thus, looking for a name +like './FooBar.TeX' will match a file './foobar.tex', and vice versa. +This is not done on Windows. *Note Casefolding search::. Although the simplest and most common path element is a directory name, Kpathsea supports additional features in search paths: layered @@ -435,7 +443,8 @@ order as the sections. Exception to all of the above: If the filename being searched for is absolute or explicitly relative, i.e., starts with '/' or './' or '../', -Kpathsea simply checks if that file exists. +Kpathsea simply checks if that file exists, with a fallback to a +casefolding match if needed and enabled, as described above. Ordinarily, if Kpathsea tries to access a file or directory that cannot be read, it gives a warning. This is so you will be alerted to @@ -455,8 +464,8 @@ File: kpathsea.info, Node: Path sources, Next: Path expansion, Prev: Searchin 5.2 Path sources ================ -A search path can come from many sources. In the order in which -Kpathsea uses them: +A search path or other configuration value can come from many sources. +In the order in which Kpathsea looks for them: 1. A user-set environment variable, e.g., 'TEXINPUTS'. Environment variables with an underscore and the program name appended @@ -570,7 +579,7 @@ anyway, since the 'sh' process couldn't affect its parent's environment. The implementation of all this is in 'kpathsea/cnf.c'.  -File: kpathsea.info, Node: Path expansion, Next: Filename database, Prev: Path sources, Up: Path searching +File: kpathsea.info, Node: Path expansion, Next: Casefolding search, Prev: Path sources, Up: Path searching 5.3 Path expansion ================== @@ -579,7 +588,9 @@ Kpathsea recognizes certain special characters and constructions in search paths, similar to that in shells. As a general example: '~$USER/{foo,bar}//baz' expands to all subdirectories under directories 'foo' and 'bar' in $USER's home directory that contain a directory or -file 'baz'. These expansions are explained in the sections below. +file 'baz'. + + These expansions are explained in the sections below. * Menu: @@ -796,9 +807,156 @@ And if you can find a way to _solve_ the problem, please let me know. 'kpathsea/elt-dirs.c'.  -File: kpathsea.info, Node: Filename database, Next: Invoking kpsewhich, Prev: Path expansion, Up: Path searching +File: kpathsea.info, Node: Casefolding search, Next: Filename database, Prev: Path expansion, Up: Path searching + +5.4 Casefolding search +====================== + +In Kpathsea version 6.3.0 (released with TeX Live 2018), a new fallback +search was implemented on Unix-like systems, including Macs: for each +path element in turn, if no match is found by the normal search, and the +path element allows for checking the filesystem, a second check is made +for a case-insensitive match. + + This is enabled at compile-time on Unix systems, and enabled at +runtime by setting the configuration variable 'texmf_casefold_search', +to a true value, e.g., '1'; this is done by default in TeX Live. + +* Menu: + +* Rationale: Casefolding rationale. +* Examples: Casefolding examples. + + +File: kpathsea.info, Node: Casefolding rationale, Next: Casefolding examples, Up: Casefolding search + +5.4.1 Casefolding rationale +--------------------------- + +The purpose of the fallback casefolding search is to ease moving complex +documents between case-insensitive (file)systems and case-sensitive +ones. In particular, Apple decided to make the default filesystem on +Macs be case-insensitive some years ago, and this has exacerbated a +problem of people creating documents that use, say, an image under the +name 'foo.jpg', while the actual file is named 'foo.JPG' or 'Foo.jpg'. +It works on the Mac but if the document is transferred and run on a +standard case-sensitive Unix (file)system, the file can't be found, due +only to differences in case. + + This same problematic scenario has always existed on Windows, but for +whatever reason, it has become much more common since Apple also went to +a case-insensitive filesystem. Hence the move to change the Kpathsea +behavior now. + + The fallback case-insensitive search is omitted at compile-time on +Windows, where (for practical purposes) all file names are +case-insensitive at the kernel level, and so the normal search will +already have definitively matched or not. Therefore, search results in +unusual cases can be different on Windows and Unix--but this has always +been true. + + +File: kpathsea.info, Node: Casefolding examples, Prev: Casefolding rationale, Up: Casefolding search + +5.4.2 Casefolding examples +-------------------------- + +The casefolding implementation prefers exact matches to casefolded +matches within a given path element, so as to retain most compatibility. +Backward compatibility is not perfect, however, as a casefolded match +may be found in an earlier path element than an exact match was +previously found (see example #4 below). Still, preferring the match in +the earlier element seemed potentially less confusing than otherwise, +and is in fact consistent with past behavior on Windows. Since case +mismatches are rare to begin with, and name collisions with respect only +to case thus even more rare, the hope is that it will not cause +difficulties in practice. + + If it's desirable in a given situation to have the exact same search +behavior as previously, that can be accomplished by setting the +configuration variable 'texmf_casefold_search' to '0' (*note Path +sources::). + + Some examples to illustrate the new behavior follow. + + Example #1: suppose the file './foobar.tex' exists. Now, searching +for './FooBar.TeX' (or any other case variation) will succeed, returning +'./foobar.tex'--the name as stored on disk. In previous releases, or if +'texmf_casefold_search' is false, the search would fail. + + Example #2: suppose we are using a case-sensitive (file)system, and +the search path is '.:/somedir', and the files './foobar.tex' and +'/somedir/FooBar.TeX' both exist. Both now and previously, searching +for 'foobar.tex' returns './foobar.tex'. However, searching for +'FooBar.TeX' now returns './foobar.tex' instead of +'/somedir/FooBar.TeX'; this is the incompatibility mentioned above. +Also (as expected), searching for 'FOOBAR.TEX' (or whatever variation) +will now return './foobar.tex', whereas before it would fail. Searching +for all ('kpsewhich --all') 'foobar.tex' will return both matches. + + Example #3: same as example #2, but on a case-insensitive +(file)system: both now and previously, searching for 'FooBar.TeX' +returns './foobar.tex', since the system considers that a match. The +Kpathsea casefolding never comes into play. + + Example #4: if we have (on a case-sensitive system) both +'./foobar.tex' and './FOOBAR.TEX', searching with the exact case returns +that exact match, now and previously. Searching for 'FooBar.tex' will +now return one or the other (chosen arbitrarily), rather than failing. +Perhaps unexpectedly, searching for all 'foobar.tex' or 'FooBar.tex' +will also return only one or the other, not both (see more below). + + Example #5: the font file 'STIX-Regular.otf' is included in TeX Live +in the system directory 'texmf-dist/fonts/opentype/public/stix'. +Because Kpathsea never searches the disk in the big system directory, +the casefolding is not done, and a search for 'stix-regular.otf' will +fail (on case-sensitive systems), as it always has. + + The caveat about not searching the disk amounts to saying that +casefolding does not happen in the trees specified with '!!' (*note +ls-R::), that is, where only database ('ls-R') searching is done. In +TeX Live, that is the 'texmf-local' and 'texmf-dist' trees (also +'$TEXMFSYSCONFIG' and '$TEXMFSYSVAR', but those are rarely noticed). +The rationale for this is that in practice, case mangling happens with +user-created files, not with packages distributed as part of the TeX +system. + + One more caveat: the purpose of 'kpsewhich' is to exercise the path +searching in Kpathsea as it is actually done. Therefore, as shown +above, 'kpsewhich --all' will not return all matches regardless of case +within a given path element. If you want to find all matches in all +directories, 'find' is the best tool, although the setup takes a couple +steps: + + kpsewhich -show-path=tex >/tmp/texpath # search path specification + kpsewhich -expand-path="`cat /tmp/texpath`" >/tmp/texdirs # all dirs + tr ':' '\n' /tmp/texdirlist # colons to newlines + find `cat /tmp/texdirlist` -iname somefile.tex -print . + + The casefolding search is implemented in the source file +'kpathsea/pathsearch.c'. Two implementation points: + + * Kpathsea never tries to check if a given directory resides on a + case-insensitive filesystem, because there is no efficient and + portable way to do so. All it does is try to see if a potential + file name is a readable normal file (with, usually, the 'access' + system call). + + * Kpathsea does not do any case-insensitive matching of the + directories along the path. It's not going to find + '/Some/Random/file.tex' when looking for '/some/random/file.tex'. + The casefolding only happens with the elements of the leaf + directory. + + +File: kpathsea.info, Node: Filename database, Next: Invoking kpsewhich, Prev: Casefolding search, Up: Path searching -5.4 Filename database ('ls-R') +5.5 Filename database ('ls-R') ============================== Kpathsea goes to some lengths to minimize disk accesses for searches @@ -826,7 +984,7 @@ filename conventions in source files.  File: kpathsea.info, Node: ls-R, Next: Filename aliases, Up: Filename database -5.4.1 'ls-R' +5.5.1 'ls-R' ------------ As mentioned above, you must name the main filename database 'ls-R'. @@ -886,7 +1044,7 @@ paths.  File: kpathsea.info, Node: Filename aliases, Next: Database format, Prev: ls-R, Up: Filename database -5.4.2 Filename aliases +5.5.2 Filename aliases ---------------------- In some circumstances, you may wish to find a file under several names. @@ -914,7 +1072,7 @@ aliases.  File: kpathsea.info, Node: Database format, Prev: Filename aliases, Up: Filename database -5.4.3 Database format +5.5.3 Database format --------------------- The "database" read by Kpathsea is a line-oriented file of plain text. @@ -957,7 +1115,7 @@ the '-R' option, as follows.  File: kpathsea.info, Node: Invoking kpsewhich, Prev: Filename database, Up: Path searching -5.5 'kpsewhich': Standalone path searching +5.6 'kpsewhich': Standalone path searching ========================================== The Kpsewhich program exercises the path searching functionality @@ -984,7 +1142,7 @@ accepted.  File: kpathsea.info, Node: Path searching options, Next: Specially-recognized files, Up: Invoking kpsewhich -5.5.1 Path searching options +5.6.1 Path searching options ---------------------------- Kpsewhich looks up each non-option argument on the command line as a @@ -997,6 +1155,13 @@ filename, and returns the first file found. more than one match, just one will be reported (chosen effectively at random). +'--casefold-search' +'--no-casefold-search' + Explicitly enable or disable the fallback to a case-insensitive + search on Unix platforms (*note Casefolding search::); no effect on + Windows. The default is the same as the system setup, which is (by + default) enabled. + '--dpi=NUM' Set the resolution to NUM; this only affects 'gf' and 'pk' lookups. '-D' is a synonym, for compatibility with Dvips. Default is 600. @@ -1197,7 +1362,7 @@ filename, and returns the first file found.  File: kpathsea.info, Node: Specially-recognized files, Next: Auxiliary tasks, Prev: Path searching options, Up: Invoking kpsewhich -5.5.2 Specially-recognized files for 'kpsewhich' +5.6.2 Specially-recognized files for 'kpsewhich' ------------------------------------------------ 'kpsewhich' recognizes a few special filenames on the command line and @@ -1247,7 +1412,7 @@ about the above configuration files (among others).  File: kpathsea.info, Node: Auxiliary tasks, Next: Standard options, Prev: Specially-recognized files, Up: Invoking kpsewhich -5.5.3 Auxiliary tasks +5.6.3 Auxiliary tasks --------------------- Kpsewhich provides some features in addition to path lookup as such: @@ -1309,7 +1474,7 @@ Kpsewhich provides some features in addition to path lookup as such:  File: kpathsea.info, Node: Standard options, Prev: Auxiliary tasks, Up: Invoking kpsewhich -5.5.4 Standard options +5.6.4 Standard options ---------------------- Kpsewhich accepts the standard GNU options: @@ -1327,21 +1492,21 @@ File: kpathsea.info, Node: TeX support, Next: Programming, Prev: Path searchi ************* Although the basic features in Kpathsea can be used for any type of path -searching, it came about (like all libraries) with a specific -application in mind: I wrote Kpathsea specifically for TeX system -programs. I had been struggling with the programs I was using (Dvips, -Xdvi, and TeX itself) having slightly different notions of how to -specify paths; and debugging was painful, since no code was shared. +searching, it came about, as usual, with a specific application in mind: +I wrote Kpathsea specifically for TeX system programs. I had been +struggling with the programs I was using (Dvips, Xdvi, and TeX itself) +having slightly different notions of how to specify paths; and debugging +was painful, since no code was shared. Therefore, Kpathsea provides some TeX-specific formats and features. -Indeed, many of the supposedly generic path searching features were +Indeed, many of the purportedly generic path searching features were provided because they seemed useful in that conTeXt (font lookup, particularly). Kpathsea provides a standard way to search for files of any of the supported file types; glyph fonts are a bit different than all the rest. -Searches are based solely on filenames, not file contents--if a GF file -is named 'cmr10.600pk', it will be found as a PK file. +Searches are based solely on names of files, not their contents--if a GF +file is (mis)named 'cmr10.600pk', it will be found as a PK file. * Menu: @@ -2072,7 +2237,8 @@ File: kpathsea.info, Node: Programming, Next: Reporting bugs, Prev: TeX suppo ************* This chapter is for programmers who wish to use Kpathsea. *Note -Introduction::, for the conditions under which you may do so. +Introduction::, for the conditions under which you may do so (in short, +it is released under LGPLv2.1 or later). * Menu: @@ -2088,22 +2254,24 @@ File: kpathsea.info, Node: Programming overview, Next: Calling sequence, Up: ======================== Aside from this manual, your best source of information is the source to -the programs that use Kpathsea (*note Introduction::). Of those, Dviljk -is probably the simplest, and hence a good place to start. Xdvik adds -VF support and the complication of X resources. Dvipsk adds the -complication of its own config files. Web2c is source code I also -maintain, so it uses Kpathsea rather straightforwardly, but is of course -complicated by the Web to C translation. Finally, Kpsewhich is a small -utility program whose sole purpose is to exercise the main -path-searching functionality. +the programs that use Kpathsea (*note Introduction::). First, Kpsewhich +is a small utility program whose sole purpose is to exercise the main +path-searching functionality. Of the drivers, Dviljk is probably the +simplest full application program. Xdvik adds VF support and the +complication of X resources. Dvipsk adds the complication of its own +config files. Web2c is source code I also maintain, so it uses Kpathsea +rather straightforwardly, but is of course complicated by the Web to C +translation. When looking at these program sources, you should know that previous -versions of the library had a different programming interface, to -support re-entrancy. In that interface the library function names were -prefixed with 'kpse_' instead of 'kpathsea_', and they did not need an -instance variable as first argument. This change was made in 2009. -Some of the programs mentioned above may still be using the previous -interface. +versions of the library had a different programming interface; the +current interface supports re-entrancy. Historically, the library +function names were prefixed with 'kpse_' instead of 'kpathsea_', and +they did not need an instance variable as first argument. This change +was made in 2009. The old functions will never disappear, and can +reliably continue to be used when they suffice, as they do for the +programs above. The main application using the re-entrant API is the +MetaPost library used by MetaPost and LuaTeX. Beyond these examples, the '.h' files in the Kpathsea source describe the interfaces and functionality (and of course the '.c' files define @@ -2770,38 +2938,42 @@ Index * $ expansion: Variable expansion. (line 6) * --all: Path searching options. (line 12) +* --casefold-search: Path searching options. + (line 18) * --color=tty: ls-R. (line 21) * --debug=NUM: Auxiliary tasks. (line 9) * --dpi=NUM: Path searching options. - (line 17) + (line 24) * --engine=NAME: Path searching options. - (line 21) + (line 28) * --expand-braces=STRING: Auxiliary tasks. (line 12) * --expand-path=STRING: Auxiliary tasks. (line 16) * --expand-var=STRING: Auxiliary tasks. (line 34) * --format=NAME: Path searching options. - (line 37) + (line 44) * --help: Standard options. (line 8) * --help-formats: Auxiliary tasks. (line 39) * --interactive: Path searching options. - (line 119) + (line 126) * --mktex=FILETYPE: Path searching options. - (line 124) + (line 131) * --mode=STRING: Path searching options. - (line 130) + (line 137) * --must-exist: Path searching options. - (line 135) + (line 142) +* --no-casefold-search: Path searching options. + (line 18) * --no-mktex=FILETYPE: Path searching options. - (line 124) + (line 131) * --path=STRING: Path searching options. - (line 140) + (line 147) * --progname=NAME: Path searching options. - (line 148) + (line 155) * --safe-in-name=NAME: Auxiliary tasks. (line 45) * --safe-out-name=NAME: Auxiliary tasks. (line 45) * --show-path=NAME: Auxiliary tasks. (line 51) * --subdir=STRING: Path searching options. - (line 153) + (line 160) * --var-value=VARIABLE: Auxiliary tasks. (line 57) * --version: Standard options. (line 11) * --with-mktextex-default: mktex configuration. (line 12) @@ -2814,7 +2986,9 @@ Index * -1 debugging value: Debugging. (line 23) * -A option to ls: ls-R. (line 33) * -D NUM: Path searching options. - (line 17) + (line 24) +* -iname, find predicate: Casefolding examples. + (line 78) * -L option to ls: ls-R. (line 38) * . directories, ignored: ls-R. (line 33) * . files: ls-R. (line 33) @@ -2935,8 +3109,10 @@ Index (line 31) * { expansion: Brace expansion. (line 6) * ~ expansion: Tilde expansion. (line 6) -* absolute filenames: Searching overview. (line 52) -* access warnings: Searching overview. (line 56) +* absolute filenames: Searching overview. (line 58) +* access system call: Casefolding examples. + (line 86) +* access warnings: Searching overview. (line 63) * AFMFONTS: Supported file formats. (line 22) * aliases for fonts: Fontmap. (line 6) @@ -2952,6 +3128,8 @@ Index (line 16) * append-only directories and mktexpk: Security. (line 36) * appendonlydir: mktex configuration. (line 60) +* Apple filesystem, case-insensitive: Casefolding rationale. + (line 6) * arguments to mktex: mktex script arguments. (line 6) * argv[0]: Calling sequence. (line 14) @@ -2981,9 +3159,14 @@ Index * bugs, reporting: Reporting bugs. (line 6) * c-*.h: Calling sequence. (line 117) * c-auto.h: Programming overview. - (line 33) + (line 35) * cache of fonts, local: Security. (line 22) * calling sequence: Calling sequence. (line 6) +* casefolding examples: Casefolding examples. + (line 6) +* casefolding fallback rationale: Casefolding rationale. + (line 6) +* casefolding search: Casefolding search. (line 6) * ChangeLog entry: Bug checklist. (line 52) * checklist for bug reports: Bug checklist. (line 6) * checksum: Suppressing warnings. @@ -3001,7 +3184,7 @@ Index (line 23) * comments, in fontmap files: Fontmap. (line 27) * comments, in texmf.cnf: Config files. (line 27) -* comments, making: Introduction. (line 28) +* comments, making: Introduction. (line 29) * common features in glyph lookup: Basic glyph lookup. (line 6) * common problems: Common problems. (line 6) * compilation value, source for path: Path sources. (line 20) @@ -3009,14 +3192,14 @@ Index (line 6) * compiler bugs, finding: TeX or Metafont failing. (line 24) -* conditions for use: Introduction. (line 31) +* conditions for use: Introduction. (line 32) * config files: Config files. (line 6) * config files, for Kpathsea-using programs: Calling sequence. (line 47) * config files, programming with: Programming with config files. (line 6) * config.h: Programming overview. - (line 33) + (line 35) * config.log: Bug checklist. (line 24) * config.ps: Specially-recognized files. (line 16) @@ -3082,7 +3265,7 @@ Index * ENCFONTS: Supported file formats. (line 61) * engine name: Path searching options. - (line 21) + (line 28) * environment variable, source for path: Path sources. (line 9) * environment variables for TeX: Supported file formats. (line 6) @@ -3091,17 +3274,19 @@ Index (line 14) * epoch, seconds since: Logging. (line 15) * error message macros: Calling sequence. (line 22) +* examples, of casefolding searches: Casefolding examples. + (line 6) * excessive startup time: Slow path searching. (line 6) * expand.c: Brace expansion. (line 26) * expanding symlinks: Calling sequence. (line 31) * expansion, default: Default expansion. (line 6) -* expansion, path element: Searching overview. (line 43) +* expansion, path element: Searching overview. (line 49) * expansion, search path: Path expansion. (line 6) * expansion, subdirectory: Subdirectory expansion. (line 6) * expansion, tilde: Tilde expansion. (line 6) * expansion, variable: Variable expansion. (line 6) -* explicitly relative filenames: Searching overview. (line 52) +* explicitly relative filenames: Searching overview. (line 58) * extensions, filename: File lookup. (line 24) * externally-built filename database: Filename database. (line 6) * extra colons: Default expansion. (line 6) @@ -3116,14 +3301,18 @@ Index * file lookup: File lookup. (line 6) * file permissions: Security. (line 47) * file types, registering new: Programming overview. - (line 39) + (line 41) * filename aliases: Filename aliases. (line 6) * filename database: Filename database. (line 6) * filenames, absolute or explicitly relative: Searching overview. - (line 52) + (line 58) * files, unable to find: Unable to find files. (line 6) * filesystem search: Searching overview. (line 22) +* filesystem, case-(in)sensitive: Casefolding rationale. + (line 6) +* Findutils, GNU package: Casefolding examples. + (line 78) * floating directories: Searching overview. (line 22) * fmtutil: mktex script names. (line 10) * fmtutil.cnf: Specially-recognized files. @@ -3168,7 +3357,7 @@ Index (line 25) * GNU C compiler bugs: TeX or Metafont failing. (line 19) -* GNU General Public License: Introduction. (line 31) +* GNU General Public License: Introduction. (line 32) * group-writable directories: Security. (line 40) * GSFTOPK_DEBUG (128): Debugging. (line 88) * hash table buckets, printing: Debugging. (line 105) @@ -3184,8 +3373,8 @@ Index (line 84) * input lines, reading: Calling sequence. (line 110) * interactive query: Path searching options. - (line 119) -* interface, not frozen: Introduction. (line 28) + (line 126) +* interface, not frozen: Introduction. (line 29) * introduction: Introduction. (line 6) * kdebug:: Debugging. (line 105) * kdefault.c: Default expansion. (line 48) @@ -3193,7 +3382,7 @@ Index * Knuth, Donald E., archive of programs by: unixtex.ftp. (line 19) * Kpathsea config file, source for path: Path sources. (line 17) * kpathsea.h: Programming overview. - (line 24) + (line 26) * kpathsea_cnf_get: Programming with config files. (line 23) * KPATHSEA_DEBUG: Calling sequence. (line 28) @@ -3238,7 +3427,7 @@ Index (line 21) * leaf directory trick: Subdirectory expansion. (line 22) -* license for using the library: Introduction. (line 31) +* license for using the library: Introduction. (line 32) * LIGFONTS: Supported file formats. (line 88) * lines, reading arbitrary-length: Calling sequence. (line 110) @@ -3246,13 +3435,15 @@ Index * local cache of fonts: Security. (line 22) * log file: Logging. (line 6) * logging successful searches: Logging. (line 6) -* lost+found directory: Searching overview. (line 56) +* lost+found directory: Searching overview. (line 63) * lostchar: Suppressing warnings. (line 19) * ls-R: Supported file formats. (line 91) * ls-R database file: ls-R. (line 6) * ls-R, simplest build: ls-R. (line 18) +* Mac filesystem, case-insensitive: Casefolding rationale. + (line 6) * MacKenzie, David: History. (line 44) * MacKenzie, David <1>: Subdirectory expansion. (line 22) @@ -3359,7 +3550,7 @@ Index * path searching, standalone: Invoking kpsewhich. (line 6) * path sources: Path sources. (line 6) * pathsearch.h: Programming overview. - (line 24) + (line 26) * pc Pascal compiler: History. (line 12) * pdfglyphlist.txt: Specially-recognized files. (line 31) @@ -3369,7 +3560,7 @@ Index (line 161) * pdftexconfig.tex: Specially-recognized files. (line 34) -* permission denied: Searching overview. (line 56) +* permission denied: Searching overview. (line 63) * permissions, directory: Security. (line 51) * permissions, file: Security. (line 47) * PKFONTS: Supported file formats. @@ -3393,17 +3584,19 @@ Index (line 169) * pxp Pascal preprocessor: History. (line 12) * quoting variable values: Variable expansion. (line 17) +* rationale for casefolding fallback: Casefolding rationale. + (line 6) * re-entrant API: Programming overview. (line 16) * readable: Suppressing warnings. (line 26) * reading arbitrary-length lines: Calling sequence. (line 110) * recording successful searches: Logging. (line 6) -* relative filenames: Searching overview. (line 52) +* relative filenames: Searching overview. (line 58) * reporting bugs: Reporting bugs. (line 6) * resident.c: Calling sequence. (line 47) * resolution, setting: Path searching options. - (line 17) + (line 24) * resolutions, last-resort: Fallback font. (line 6) * retrieving TeX: unixtex.ftp. (line 6) * right-hand side of variable assignments: Config files. (line 56) @@ -3416,6 +3609,7 @@ Index * Sauter fonts, and dynamic source creation: mktex scripts. (line 6) * scripts for file creation: mktex scripts. (line 6) * search path, defined: Searching overview. (line 6) +* search, case-insensitive: Casefolding search. (line 6) * searching for files: File lookup. (line 6) * searching for glyphs: Glyph lookup. (line 6) * searching overview: Searching overview. (line 6) @@ -3458,7 +3652,7 @@ Index * subdirectory searching: Subdirectory expansion. (line 6) * suffixes, filename: File lookup. (line 24) -* suggestions, making: Introduction. (line 28) +* suggestions, making: Introduction. (line 29) * Sun 2: History. (line 12) * supplier directory, omitting: mktex configuration. (line 102) * supplier directory, omitting <1>: mktex configuration. (line 108) @@ -3472,6 +3666,8 @@ Index * symlinks, resolving: Calling sequence. (line 31) * system C compiler bugs: TeX or Metafont failing. (line 19) +* system-dependent casefolding behavior: Casefolding rationale. + (line 6) * T1FONTS: Supported file formats. (line 211) * T1INPUTS: Supported file formats. @@ -3491,13 +3687,13 @@ Index * TeX file lookup: File lookup. (line 6) * TeX glyph lookup: Glyph lookup. (line 6) * TeX support: TeX support. (line 6) -* TeX Users Group: Introduction. (line 40) +* TeX Users Group: Introduction. (line 43) * tex-file.c: File lookup. (line 38) * tex-file.h: Programming overview. - (line 24) + (line 26) * tex-glyph.c: Glyph lookup. (line 26) * tex-glyph.h: Programming overview. - (line 24) + (line 26) * tex-k@tug.org: Mailing lists. (line 6) * tex-k@tug.org (bug address): Reporting bugs. (line 6) * tex.web: unixtex.ftp. (line 19) @@ -3554,6 +3750,7 @@ Index (line 191) * texmfvar: mktex configuration. (line 122) * TEXMFVAR: mktex configuration. (line 123) +* texmf_casefold_search: Casefolding search. (line 12) * TEXPICTS: Supported file formats. (line 79) * TEXPKS: Supported file formats. @@ -3567,7 +3764,7 @@ Index * TEXSIZES: Fallback font. (line 6) * TEXSOURCES: Supported file formats. (line 188) -* TEX_HUSH: Searching overview. (line 56) +* TEX_HUSH: Searching overview. (line 63) * TEX_HUSH <1>: Suppressing warnings. (line 6) * TFMFONTS: Supported file formats. @@ -3599,7 +3796,7 @@ Index (line 31) * unreadable file warnings: Suppressing warnings. (line 27) -* unreadable files: Searching overview. (line 56) +* unreadable files: Searching overview. (line 63) * unusable ls-R warning: ls-R. (line 45) * usage patterns, finding: Logging. (line 6) * USERPROFILE, as ~ expansion: Tilde expansion. (line 6) @@ -3620,7 +3817,7 @@ Index * Walsh, Norman: History. (line 56) * warning about unusable ls-R: ls-R. (line 45) * warning, about missing texmf.cnf: Config files. (line 18) -* warnings, file access: Searching overview. (line 56) +* warnings, file access: Searching overview. (line 63) * warnings, suppressing: Suppressing warnings. (line 6) * WEB2C: Supported file formats. @@ -3631,6 +3828,8 @@ Index * whitespace, in fontmap files: Fontmap. (line 31) * whitespace, not ignored on continuation lines: Config files. (line 37) +* Windows and casefolding: Casefolding rationale. + (line 21) * www.tug.org: unixtex.ftp. (line 6) * XDvi: Specially-recognized files. (line 41) @@ -3644,58 +3843,61 @@ Index  Tag Table: Node: Top1480 -Node: Introduction2259 -Node: History4204 -Node: unixtex.ftp8801 -Node: Security10226 -Node: TeX directory structure12730 -Node: Path searching16778 -Node: Searching overview17436 -Node: Path sources20831 -Node: Config files21889 -Node: Path expansion25816 -Node: Default expansion26765 -Node: Variable expansion28835 -Node: Tilde expansion30236 -Node: Brace expansion31216 -Node: KPSE_DOT expansion32141 -Node: Subdirectory expansion32654 -Node: Filename database35008 -Node: ls-R36062 -Node: Filename aliases38957 -Node: Database format40135 -Node: Invoking kpsewhich41148 -Node: Path searching options42103 -Node: Specially-recognized files50023 -Node: Auxiliary tasks51378 -Node: Standard options53717 -Node: TeX support54073 -Node: Supported file formats55425 -Node: File lookup63090 -Node: Glyph lookup64839 -Node: Basic glyph lookup65963 -Node: Fontmap66843 -Node: Fallback font69372 -Node: Suppressing warnings70284 -Node: mktex scripts71411 -Node: mktex configuration72626 -Node: mktex script names78429 -Node: mktex script arguments79815 -Node: Programming80694 -Node: Programming overview81216 -Node: Calling sequence83913 -Node: Program-specific files90445 -Node: Programming with config files91468 -Node: Reporting bugs92780 -Node: Bug checklist93458 -Node: Mailing lists96930 -Node: Debugging97605 -Node: Logging102682 -Node: Common problems104549 -Node: Unable to find files105026 -Node: Slow path searching107436 -Node: Unable to generate fonts108811 -Node: TeX or Metafont failing111282 -Node: Index112635 +Node: Introduction2263 +Node: History4336 +Node: unixtex.ftp8932 +Node: Security10357 +Node: TeX directory structure12861 +Node: Path searching16909 +Node: Searching overview17636 +Node: Path sources21455 +Node: Config files22546 +Node: Path expansion26473 +Node: Default expansion27426 +Node: Variable expansion29496 +Node: Tilde expansion30897 +Node: Brace expansion31877 +Node: KPSE_DOT expansion32802 +Node: Subdirectory expansion33315 +Node: Casefolding search35669 +Node: Casefolding rationale36438 +Node: Casefolding examples37777 +Node: Filename database42827 +Node: ls-R43885 +Node: Filename aliases46780 +Node: Database format47958 +Node: Invoking kpsewhich48971 +Node: Path searching options49926 +Node: Specially-recognized files58128 +Node: Auxiliary tasks59483 +Node: Standard options61822 +Node: TeX support62178 +Node: Supported file formats63532 +Node: File lookup71197 +Node: Glyph lookup72946 +Node: Basic glyph lookup74070 +Node: Fontmap74950 +Node: Fallback font77479 +Node: Suppressing warnings78391 +Node: mktex scripts79518 +Node: mktex configuration80733 +Node: mktex script names86536 +Node: mktex script arguments87922 +Node: Programming88801 +Node: Programming overview89374 +Node: Calling sequence92235 +Node: Program-specific files98767 +Node: Programming with config files99790 +Node: Reporting bugs101102 +Node: Bug checklist101780 +Node: Mailing lists105252 +Node: Debugging105927 +Node: Logging111004 +Node: Common problems112871 +Node: Unable to find files113348 +Node: Slow path searching115758 +Node: Unable to generate fonts117133 +Node: TeX or Metafont failing119604 +Node: Index120957  End Tag Table diff --git a/Build/source/texk/kpathsea/doc/kpathsea.texi b/Build/source/texk/kpathsea/doc/kpathsea.texi index 47201531e5d..b4bab017cc8 100644 --- a/Build/source/texk/kpathsea/doc/kpathsea.texi +++ b/Build/source/texk/kpathsea/doc/kpathsea.texi @@ -2,13 +2,13 @@ @setfilename kpathsea.info @settitle Kpathsea: A library for path searching -@set version 6.2.4 -@set month-year June 2017 +@set version 6.3.0 +@set month-year February 2018 @copying This file documents the Kpathsea library for path searching. -Copyright @copyright{} 1996--2017 Karl Berry & Olaf Weber. +Copyright @copyright{} 1996--2018 Karl Berry & Olaf Weber. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are @@ -129,12 +129,12 @@ this library: @item Xdvik (see the @samp{xdvi} man page) @end itemize -@noindent Other software that we do not maintain also uses it. +@noindent Other software that we do not maintain also uses it. Kpathsea is now maintained as part of the @TeX{} Live distribution -(@url{http://tug.org/texlive}). For information on configuration, -building, installing, and more, @pxref{,,,tlbuild, Building @TeX{} -Live}. +(@url{http://tug.org/texlive}), which includes several more +Kpathsea-using programs. For information on configuration, building, +installing, and more, @pxref{,,,tlbuild, Building @TeX{} Live}. @cindex interface, not frozen @cindex comments, making @@ -146,13 +146,14 @@ suggestions, please send along (@pxref{Reporting bugs}). @cindex license for using the library @cindex GNU General Public License The Kpathsea library is distributed under the GNU Library General -Public License (LGPL). In short, this means if you write a program -using the library, you must (offer to) distribute the source to the -library, along with any changes you have made, and allow anyone to -modify the library source and distribute their modifications. It does -not mean you have to distribute the source to your program, although -we hope you will. See accompanying files for the text of the GNU -licenses, or @url{http://www.gnu.org/licenses}. +Public License (LGPL), version@tie{}2.1 or (at your option) any later +version. In short, this means if you write a program using the +library, you must (offer to) distribute the source to the library, +along with any changes you have made, and allow anyone to modify the +library source and distribute their modifications. It does not mean +you have to distribute the source to your program using the library, +although we hope you will. See accompanying files for the text of the +GNU licenses, or @url{http2://www.gnu.org/licenses}. @cindex @TeX{} Users Group If you know enough about @TeX{} to be reading this manual, then you (or @@ -160,7 +161,7 @@ your institution) should consider joining the @TeX{} Users Group (if you're already a member, thanks!). TUG produces the periodical @cite{TUGboat}, sponsors an annual meeting and publishes the proceedings, and arranges courses on @TeX{} for all levels of users -throughout the world. See @url{http://tug.org} for information. +throughout the world. See @url{https://tug.org} for information. @menu * History:: @@ -261,14 +262,14 @@ part of the burden, and I volunteered. @cindex Hoekwater, Taco @cindex Breitenlohner, Peter [Karl writes again.] Indeed, time goes on. As of 2006 or so, Olaf's -available time for Kpathsea became rather reduced, and I started -taking overall care of it again, although I did not do any significant -new development. In 2009, Taco Hoekwater made a major rearrangement -to make the library suitable for use within the MetaPost library -(@pxref{Programming overview}). Also, for some years now, Peter -Breitenlohner has made many improvements to the infrastructure and -kept up-to-date with respect to the overall @TeX{} Live build, where -Kpathsea is now maintained. +available time for Kpathsea was reduced, and I started taking overall +care of it again, although I did not do any significant new +development. In 2009, Taco Hoekwater implemented a major +rearrangement to make the library suitable for use within the MetaPost +library (@pxref{Programming overview}). Also, for some years now, +Peter Breitenlohner has made many improvements to the infrastructure +and kept it up-to-date with respect to the overall @TeX{} Live build, +where Kpathsea is now maintained. @c emacs-page separate file so we can easily generate unixtex.ftp. @@ -448,6 +449,7 @@ provides. For information about searching for particular file types * Searching overview:: Basic scheme for searching. * Path sources:: Where search paths can be defined. * Path expansion:: Special constructs in search paths. +* Casefolding search:: Fallback to case-insensitive search. * Filename database:: Using an externally-built list to search. * Invoking kpsewhich:: Standalone path lookup. @end menu @@ -506,11 +508,18 @@ be wrong to search the disk for them. Therefore, if you fail to update @file{ls-R} when you install a new VF file, it will not be found. -Each path element is checked in turn: first the database, then the disk. -If a match is found, the search stops and the result is returned. This +Each path element is checked in turn: first the database, then the +disk. If a match is found, the search stops and the result is +returned (unless the search explicitly requested all matches). This avoids possibly-expensive processing of path specifications that are -never needed on a particular run. (Unless the search explicitly -requested all matches.) +never needed on a particular run. + +On Unix-like systems, if no match is found by any of the above, and +the path element allows checking the filesystem (per the above), a +final check is made for a case-insensitive match. Thus, looking for a +name like @samp{./FooBar.TeX} will match a file @samp{./foobar.tex}, +and vice versa. This is not done on Windows. @xref{Casefolding +search}. @cindex expansion, path element Although the simplest and most common path element is a directory name, @@ -528,7 +537,8 @@ order as the sections. @cindex filenames, absolute or explicitly relative Exception to all of the above: If the filename being searched for is absolute or explicitly relative, i.e., starts with @samp{/} or @samp{./} -or @samp{../}, Kpathsea simply checks if that file exists. +or @samp{../}, Kpathsea simply checks if that file exists, with a +fallback to a casefolding match if needed and enabled, as described above. @cindex permission denied @cindex unreadable files @@ -555,8 +565,8 @@ lookup}, and @ref{Glyph lookup}). @cindex path sources @cindex sources for search paths -A search path can come from many sources. In the order in which -Kpathsea uses them: +A search path or other configuration value can come from many sources. +In the order in which Kpathsea looks for them: @enumerate @item @@ -726,8 +736,9 @@ Kpathsea recognizes certain special characters and constructions in search paths, similar to that in shells. As a general example: @samp{~$USER/@{foo,bar@}//baz} expands to all subdirectories under directories @file{foo} and @file{bar} in @t{$USER}'s home directory that -contain a directory or file @file{baz}. These expansions are explained -in the sections below. +contain a directory or file @file{baz}. + +These expansions are explained in the sections below. @menu * Default expansion:: a: or :a or a::b expands to a default. @@ -1007,6 +1018,178 @@ Subdirectory expansion is implemented in the source file @file{kpathsea/elt-dirs.c}. +@node Casefolding search +@section Casefolding search + +@cindex casefolding search +@cindex search, case-insensitive + +In Kpathsea version 6.3.0 (released with @TeX{} Live 2018), a new +fallback search was implemented on Unix-like systems, including Macs: +for each path element in turn, if no match is found by the normal +search, and the path element allows for checking the filesystem, a +second check is made for a case-insensitive match. + +@vindex texmf_casefold_search +This is enabled at compile-time on Unix systems, and enabled at +runtime by setting the configuration variable +@code{texmf_casefold_search}, to a true value, e.g., @samp{1}; this is +done by default in @TeX{} Live. + +@menu +* Rationale: Casefolding rationale. +* Examples: Casefolding examples. +@end menu + +@node Casefolding rationale +@subsection Casefolding rationale + +@cindex casefolding fallback rationale +@cindex rationale for casefolding fallback +@cindex system-dependent casefolding behavior + +@cindex filesystem, case-(in)sensitive +@cindex Apple filesystem, case-insensitive +@cindex Mac filesystem, case-insensitive +The purpose of the fallback casefolding search is to ease moving +complex documents between case-insensitive (file)systems and +case-sensitive ones. In particular, Apple decided to make the default +filesystem on Macs be case-insensitive some years ago, and this has +exacerbated a problem of people creating documents that use, say, an +image under the name @file{foo.jpg}, while the actual file is named +@file{foo.JPG} or @file{Foo.jpg}. It works on the Mac but if the +document is transferred and run on a standard case-sensitive Unix +(file)system, the file can't be found, due only to differences in +case. + +This same problematic scenario has always existed on Windows, but for +whatever reason, it has become much more common since Apple also went +to a case-insensitive filesystem. Hence the move to change the +Kpathsea behavior now. + +@cindex Windows and casefolding +The fallback case-insensitive search is omitted at compile-time on +Windows, where (for practical purposes) all file names are +case-insensitive at the kernel level, and so the normal search will +already have definitively matched or not. Therefore, search results +in unusual cases can be different on Windows and Unix---but this has +always been true. + + +@node Casefolding examples +@subsection Casefolding examples + +@cindex casefolding examples +@cindex examples, of casefolding searches + +The casefolding implementation prefers exact matches to casefolded +matches within a given path element, so as to retain most +compatibility. Backward compatibility is not perfect, however, as a +casefolded match may be found in an earlier path element than an exact +match was previously found (see example #4 below). Still, preferring +the match in the earlier element seemed potentially less confusing +than otherwise, and is in fact consistent with past behavior on +Windows. Since case mismatches are rare to begin with, and name +collisions with respect only to case thus even more rare, the hope is +that it will not cause difficulties in practice. + +If it's desirable in a given situation to have the exact same search +behavior as previously, that can be accomplished by setting the +configuration variable @code{texmf_casefold_search} to @samp{0} +(@pxref{Path sources}). + +Some examples to illustrate the new behavior follow. + +Example #1: suppose the file @file{./foobar.tex} exists. Now, +searching for @file{./FooBar.TeX} (or any other case variation) will +succeed, returning @file{./foobar.tex}---the name as stored on disk. +In previous releases, or if @code{texmf_casefold_search} is false, the +search would fail. + +Example #2: suppose we are using a case-sensitive (file)system, and +the search path is @samp{.:/somedir}, and the files +@file{./foobar.tex} and @file{/somedir/FooBar.TeX} both exist. Both +now and previously, searching for @file{foobar.tex} returns +@file{./foobar.tex}. However, searching for @file{FooBar.TeX} now +returns @file{./foobar.tex} instead of @file{/somedir/FooBar.TeX}; +this is the incompatibility mentioned above. Also (as expected), +searching for @file{FOOBAR.TEX} (or whatever variation) will now +return @file{./foobar.tex}, whereas before it would fail. Searching +for all (@samp{kpsewhich --all}) @file{foobar.tex} will return both +matches. + +Example #3: same as example #2, but on a case-insensitive +(file)system: both now and previously, searching for @file{FooBar.TeX} +returns @file{./foobar.tex}, since the system considers that a match. +The Kpathsea casefolding never comes into play. + +Example #4: if we have (on a case-sensitive system) both +@file{./foobar.tex} and @file{./FOOBAR.TEX}, searching with the exact +case returns that exact match, now and previously. Searching for +@file{FooBar.tex} will now return one or the other (chosen +arbitrarily), rather than failing. Perhaps unexpectedly, searching +for all @file{foobar.tex} or @file{FooBar.tex} will also return only +one or the other, not both (see more below). + +Example #5: the font file @file{STIX-Regular.otf} is included in +@TeX{} Live in the system directory +@file{texmf-dist/fonts/opentype/public/stix}. Because Kpathsea never +searches the disk in the big system directory, the casefolding is not +done, and a search for @samp{stix-regular.otf} will fail (on +case-sensitive systems), as it always has. + +The caveat about not searching the disk amounts to saying that +casefolding does not happen in the trees specified with @samp{!!} +(@pxref{ls-R}), that is, where only database (@file{ls-R}) searching +is done. In @TeX{} Live, that is the @samp{texmf-local} and +@samp{texmf-dist} trees (also @code{$TEXMFSYSCONFIG} and +@code{$TEXMFSYSVAR}, but those are rarely noticed). The rationale for +this is that in practice, case mangling happens with user-created +files, not with packages distributed as part of the @TeX{} system. + +One more caveat: the purpose of @code{kpsewhich} is to exercise the +path searching in Kpathsea as it is actually done. Therefore, as +shown above, @samp{kpsewhich --all} will not return all matches +regardless of case within a given path element. If you want to find +all matches in all directories, @code{find} is the best tool, although +the setup takes a couple steps: + +@example +kpsewhich -show-path=tex >/tmp/texpath # search path specification +kpsewhich -expand-path="`cat /tmp/texpath`" >/tmp/texdirs # all dirs +tr ':' '\n' /tmp/texdirlist # colons to newlines +find `cat /tmp/texdirlist` -iname somefile.tex -print debug |= atoi (optarg); } else if (ARGUMENT_IS ("dpi") || ARGUMENT_IS ("D")) { @@ -650,6 +661,9 @@ read_command_line (kpathsea kpse, int argc, string *argv) } else if (ARGUMENT_IS ("mode")) { mode = optarg; + } else if (ARGUMENT_IS ("no-casefold-search")) { + xputenv ("texmf_casefold_search", "0"); + } else if (ARGUMENT_IS ("no-mktex")) { kpathsea_maketex_option (kpse, optarg, false); must_exist = 0; @@ -678,8 +692,8 @@ read_command_line (kpathsea kpse, int argc, string *argv) } else if (ARGUMENT_IS ("version")) { puts (kpathsea_version_string); - puts ("Copyright 2017 Karl Berry & Olaf Weber.\n\ -License LGPLv2.1+: GNU Lesser GPL version 2.1 or later \n\ + puts ("Copyright 2018 Karl Berry & Olaf Weber.\n\ +License LGPLv2.1+: GNU Lesser GPL version 2.1 or later \n\ This is free software: you are free to change and redistribute it.\n\ There is NO WARRANTY, to the extent permitted by law.\n"); exit (0); diff --git a/Build/source/texk/kpathsea/pathsearch.c b/Build/source/texk/kpathsea/pathsearch.c index 24dc472b536..ad6f0cd0199 100644 --- a/Build/source/texk/kpathsea/pathsearch.c +++ b/Build/source/texk/kpathsea/pathsearch.c @@ -27,6 +27,7 @@ #include #include #include +#include #include /* for `time' */ @@ -50,6 +51,23 @@ kpathsea_instance to distinguish the first search from all others. */ + +#ifdef KPSE_DEBUG +/* Print on FH elements of L surrounded by brackets, separated by spaces. */ + +static void +print_space_list (FILE *fh, string *l) +{ + fputs ("[", fh); + while (l && *l) { + fputs (*l, fh); + l++; + if (*l) + fputs (" ", fh); + } + fputs ("]", fh); +} +#endif /* KPSE_DEBUG */ /* This function is called after every search (except the first, since we definitely want to allow enabling the logging in texmf.cnf) to @@ -59,8 +77,10 @@ static void log_search (kpathsea kpse, str_list_type filenames) { if (kpse->log_opened == false) { - /* Get name from either envvar or config file. */ - string log_name = kpathsea_var_value (kpse, "TEXMFLOG"); + /* Get name from either envvar or config file. Thus, the first time + is called, for the first search, we will be opening texmf.cnf + and ls-R just to resolve the variable. */ + string log_name = kpathsea_var_value (kpse, "TEXMFLOG"); kpse->log_opened = true; if (log_name) { kpse->log_file = fopen (log_name, FOPEN_A_MODE); @@ -89,8 +109,9 @@ log_search (kpathsea kpse, str_list_type filenames) } #ifdef KPSE_DEBUG - /* And show them online, if debugging. We've already started - the debugging line in `search', where this is called, so + /* And show them online, if debugging. We've already started the + debugging line in `search' and + `kpathsea_path_search_list_generic', where this is called, so just print the filename here, don't use DEBUGF. */ if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) { putc (' ', stderr); @@ -101,21 +122,103 @@ log_search (kpathsea kpse, str_list_type filenames) } } -/* Concatenate each element in DIRS with NAME (assume each ends with a - /, to save time). If SEARCH_ALL is false, return the first readable - regular file. Else continue to search for more. In any case, if - none, return a list containing just NULL. +/* Either casefold_readable_file or kpathsea_readable_file. We need the + type even if we don't have casefolding enabled at compile-time. */ +typedef string (*readable_file_fn_type) (kpathsea, string); + +#ifdef MONOCASE_FILENAMES +/* Don't do any of this fallback casefolding stuff on Windows. */ +#undef KPSE_CASEFOLDING_SEARCH +#else +#define KPSE_CASEFOLDING_SEARCH 1 +#endif + +#ifdef KPSE_CASEFOLDING_SEARCH + +/* Same as kpathsea_readable_file (readable.c), but check + case-insensitively on the last file name component. We return the + first match (in new memory), or NULL. In practice this is always + called after checking the filename as-is, so there's no use in + continuing to look for an exact match. The KPSE arg is only passed + to kpathsea_readable_file if we have a candidate match. + + Clearly we could do some caching here, but let's see if it's actually + necessary, given all the other levels of caching (disk, memory, cpu) + that are going on these days. */ + +static string +casefold_readable_file (kpathsea kpse, string name) +{ + string ret = NULL; + const_string this_base_name = xbasename (name); + string this_dir_name = xdirname (name); + DIR *thisdir = opendir (this_dir_name); + +#ifdef KPSE_DEBUG + if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) { + DEBUGF2 (" casefold_readable_file(%s) in %s => ", + this_base_name, this_dir_name); + } +#endif + + /* We can be called with a name like `subdir/somefile', where subdir/ + does not exist. So the opendir might fail, and that's ok. */ + if (thisdir) { + struct dirent *e; + + while ((e = readdir (thisdir)) != NULL) { + /* The standard strcasecmp seems like enough for the comparison? */ + if (strcasecmp (e->d_name, this_base_name) == 0) { + ret = concat3 (this_dir_name, DIR_SEP_STRING, e->d_name); + if (kpathsea_readable_file (kpse, ret)) { + break; /* success */ + } else { + /* This only happens the name matches, but the potential file is + not actually readable, e.g., a broken symlink. It seems + sufficiently unusual to be worth logging. */ + #ifdef KPSE_DEBUG + if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) { + fprintf (stderr, "{casefolded candidate %s not readable, continuing}",ret); + } + #endif + free (ret); /* not readable, keep looking */ + ret = NULL; + } + } + } /* end of readdir loop */ + xclosedir (thisdir); + } + free (this_dir_name); + + if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) { + fputs (ret ? ret : "(nil)", stderr); + fputc ('\n', stderr); + } + return ret; +} +#endif /* KPSE_CASEFOLDING_SEARCH */ + +/* Return a str_list of matches in DIRS of NAME. + + Concatenate each element in DIRS with NAME, assuming each ends with /. + If SEARCH_ALL is false, return a list containing just the first + readable (according to the READABLE_FILE_P function) regular file. + Else continue to search and return them all. In any case, if none, + return a list containing just NULL. + + DIRS is modified only in that the directory where a search matches is + floated toward the top of the list. We keep a single buffer for the potential filenames and reallocate only when necessary. I'm not sure it's noticeably faster, but it does seem cleaner. (We do waste a bit of space in the return - value, though, since we don't shrink it to the final size returned.) */ + value, since we don't shrink it to the final size returned.) */ #define INIT_ALLOC 75 /* Doesn't much matter what this number is. */ static str_list_type -dir_list_search (kpathsea kpse, str_llist_type *dirs, const_string name, - boolean search_all) +dir_list_search (kpathsea kpse, str_llist_type *dirs, const_string name, + boolean search_all, readable_file_fn_type readable_file_p) { str_llist_elt_type *elt; str_llist_elt_type *next_elt; @@ -124,9 +227,23 @@ dir_list_search (kpathsea kpse, str_llist_type *dirs, const_string name, unsigned allocated = INIT_ALLOC; string potential = (string) xmalloc (allocated); +#ifdef KPSE_DEBUG + if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) { + const_string casefold = +#ifdef KPSE_CASEFOLDING_SEARCH + (readable_file_p == casefold_readable_file) ? "yes" : "no"; +#else + "No"; +#endif + DEBUGF3 (" dir_list_search(file=%s, find_all=%d, casefold=%s)\n", + name, search_all, casefold); + } +#endif + ret = str_list_init (); for (elt = *dirs; elt; elt = next_elt) { + string readable_name; const_string dir = STR_LLIST (*elt); unsigned dir_len = strlen (dir); @@ -136,12 +253,12 @@ dir_list_search (kpathsea kpse, str_llist_type *dirs, const_string name, allocated += allocated; XRETALLOC (potential, allocated, char); } - strcpy (potential, dir); strcat (potential, name); - if (kpathsea_readable_file (kpse, potential)) { - str_list_add (&ret, potential); + readable_name = readable_file_p (kpse, potential); + if (readable_name) { + str_list_add (&ret, readable_name); /* Move this element towards the top of the list. */ str_llist_float (dirs, elt); @@ -165,11 +282,16 @@ dir_list_search (kpathsea kpse, str_llist_type *dirs, const_string name, return ret; } -/* Note: NAMES[i] is not modified. */ +/* This is analogous to dir_list_search above, except we search for + multiple NAMES instead of one (unfortunately the code is duplicated). + Absolute or explicitly relative items in NAMES are ignored; the + caller (kpathsea_path_search_list_generic) deals with those + separately. NAMES[i] is not modified. */ + static str_list_type dir_list_search_list (kpathsea kpse, str_llist_type *dirs, string* names, - boolean search_all) + boolean search_all, readable_file_fn_type readable_file_p) { str_llist_elt_type *elt; str_llist_elt_type *next_elt; @@ -177,12 +299,27 @@ dir_list_search_list (kpathsea kpse, str_llist_type *dirs, string* names, unsigned allocated = INIT_ALLOC; string potential = XTALLOC (allocated, char); +#ifdef KPSE_DEBUG + if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) { + const_string casefold = +#ifdef KPSE_CASEFOLDING_SEARCH + (readable_file_p == casefold_readable_file) ? "yes" : "no"; +#else + "No"; +#endif + DEBUGF (" dir_list_search_list(files="); + print_space_list (stderr, names); + fprintf (stderr, ", find_all=%d, casefold=%s)\n", search_all, casefold); + } +#endif + ret = str_list_init (); for (elt = *dirs; elt; elt = next_elt) { + int i; + string readable_name; const_string dir = STR_LLIST (*elt); unsigned dir_len = strlen (dir); - int i; next_elt = STR_LLIST_NEXT (*elt); /* in case elt floats */ @@ -202,10 +339,10 @@ dir_list_search_list (kpathsea kpse, str_llist_type *dirs, string* names, } strcpy (potential, dir); - strcat (potential+dir_len, name); - - if (kpathsea_readable_file (kpse, potential)) { - str_list_add (&ret, potential); + strcat (potential + dir_len, name); + readable_name = readable_file_p (kpse, potential); + if (readable_name) { + str_list_add (&ret, readable_name); /* Move this element towards the top of the list. */ str_llist_float (dirs, elt); @@ -231,40 +368,73 @@ dir_list_search_list (kpathsea kpse, str_llist_type *dirs, string* names, } /* This is called when NAME is absolute or explicitly relative; if it's - readable, return (a list containing) it; otherwise, return NULL. */ + readable, return a one-element str_list containing it (in new + memory); otherwise, return an empty list. (We return a list so as to + have the same return value as the path_search function.) We also + check case-insensitively if enabled and needed. */ static str_list_type absolute_search (kpathsea kpse, string name) { str_list_type ret_list; - string found = kpathsea_readable_file (kpse, name); + string found; /* Some old compilers can't initialize structs. */ ret_list = str_list_init (); - /* If NAME wasn't found, free the expansion. */ - if (name != found) - free (name); + /* Do the first check. */ + found = kpathsea_readable_file (kpse, name); +#ifdef KPSE_DEBUG + if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) { + DEBUGF2 (" absolute_search(%s) => %s\n", name, found ? found : "(nil)"); + } +#endif + if (found) { + found = xstrdup (found); /* Return new memory. */ + } - /* Add `found' to the return list even if it's null; that tells - the caller we didn't find anything. */ - str_list_add (&ret_list, found); +#ifdef KPSE_CASEFOLDING_SEARCH + /* Do the casefolding search only if both needed and enabled. */ + if (!found) { + if (KPSE_CNF_P (kpathsea_var_value (kpse, "texmf_casefold_search"))) { + found = casefold_readable_file (kpse, name); +#ifdef KPSE_DEBUG + if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) { + DEBUGF2 (" casefold search(%s) => %s\n",name,found ? found : "(nil)"); + } +#endif /* KPSE_DEBUG */ + } + } +#endif /* KPSE_CASEFOLDING_SEARCH */ + + if (found) { + /* If we didn't find anything, we'll return an empty list. */ + str_list_add (&ret_list, found); + } return ret_list; } /* This is the hard case -- look for NAME in PATH. If ALL is false, - return the first file found. Otherwise, search all elements of PATH. */ + return the first file found. Otherwise, search all elements of PATH. + We also check case-insensitively if needed and requested. */ static str_list_type -path_search (kpathsea kpse, const_string path, string name, - boolean must_exist, boolean all) +path_search (kpathsea kpse, const_string path, string name, + boolean must_exist, boolean all) { string elt; str_list_type ret_list; boolean done = false; ret_list = str_list_init (); /* some compilers lack struct initialization */ +#ifdef KPSE_DEBUG + if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) { + DEBUGF4 (" path_search(file=%s, must_exist=%d, find_all=%d, path=%s)\n", + name, all, must_exist, path); + } +#endif + for (elt = kpathsea_path_element (kpse, path); !done && elt; elt = kpathsea_path_element (kpse, NULL)) { str_list_type *found; @@ -277,32 +447,45 @@ path_search (kpathsea kpse, const_string path, string name, elt += 2; } - /* See elt-dirs.c for side effects of this function */ + /* See elt-dirs.c for side effects of this function. */ kpathsea_normalize_path (kpse, elt); /* Try ls-R, unless we're searching for texmf.cnf. Our caller - (search), also tests first_search, and does the resetting. */ + (search), also tests followup_search, and does the resetting. */ found = kpse->followup_search ? kpathsea_db_search (kpse, name, elt, all) : NULL; /* Search the filesystem if (1) the path spec allows it, and either - (2a) we are searching for texmf.cnf ; or + (2a) we are searching for texmf.cnf; or (2b) no db exists; or (2c) no db's are relevant to this elt; or (3) MUST_EXIST && NAME was not in the db. In (2*), `found' will be NULL. In (3), `found' will be an empty list. */ - if (allow_disk_search && (!found || (must_exist && !STR_LIST (*found)))) { - str_llist_type *dirs = kpathsea_element_dirs (kpse, elt); + if (allow_disk_search + && (!found || (must_exist && !STR_LIST (*found)))) { + /* Determine the directories in which to search: */ + str_llist_type *dirs = kpathsea_element_dirs (kpse, elt); if (dirs && *dirs) { if (!found) { found = XTALLOC1 (str_list_type); } - *found = dir_list_search (kpse, dirs, name, all); + /* Search in the directories: */ + *found = dir_list_search (kpse, dirs, name, all, + kpathsea_readable_file); +#ifdef KPSE_CASEFOLDING_SEARCH + if (!STR_LIST (*found) + && KPSE_CNF_P (kpathsea_var_value (kpse, + "texmf_casefold_search"))) { + /* Nothing found; search again, case-insensitively: */ + *found = dir_list_search (kpse, dirs, name, all, + casefold_readable_file); + } +#endif /* KPSE_CASEFOLDING_SEARCH */ } } - /* Did we find anything anywhere? */ + /* Did we find anything? */ if (found && STR_LIST (*found)) { if (all) { str_list_concat (&ret_list, *found); @@ -319,10 +502,6 @@ path_search (kpathsea kpse, const_string path, string name, } } - /* Free the expanded name we were passed. It can't be in the return - list, since the path directories got unconditionally prepended. */ - free (name); - return ret_list; } @@ -332,7 +511,13 @@ path_search (kpathsea kpse, const_string path, string name, Always return a list; if no files are found, the list will contain just NULL. If ALL is true, the list will be - terminated with NULL. */ + terminated with NULL. + + This function is a special case of kpathsea_path_search_list_generic + below (which takes a list of names, instead of a single name, to + search for), and so should be rewritten to call it. But this + function came first, and life is short, so the code duplication + is here. Sorry. Please fix. */ static string * search (kpathsea kpse, const_string path, const_string original_name, @@ -367,16 +552,16 @@ search (kpathsea kpse, const_string path, const_string original_name, /* Make a leading ~ count as an absolute filename, and expand $FOO's. */ name = kpathsea_expand (kpse, original_name); - /* If the first name is absolute or explicitly relative, no need to - consider PATH at all. */ - absolute_p = kpathsea_absolute_p (kpse, name, true); - #ifdef KPSE_DEBUG if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) - DEBUGF4 ("start search(file=%s, must_exist=%d, find_all=%d, path=%s).\n", + DEBUGF4 ("start search(xname=%s, must_exist=%d, find_all=%d, path=%s).\n", name, must_exist, all, path); #endif /* KPSE_DEBUG */ + /* If the first name is absolute or explicitly relative, no need to + consider PATH at all. */ + absolute_p = kpathsea_absolute_p (kpse, name, true); + /* Find the file(s). */ ret_list = absolute_p ? absolute_search (kpse, name) : path_search (kpse, path, name, must_exist, all); @@ -396,7 +581,7 @@ search (kpathsea kpse, const_string path, const_string original_name, debugging line if we're doing that. */ #ifdef KPSE_DEBUG if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) - DEBUGF1 ("search(%s) =>", original_name); + DEBUGF1 ("returning from search(%s) =>", original_name); #endif /* KPSE_DEBUG */ log_search (kpse, ret_list); #ifdef KPSE_DEBUG @@ -410,12 +595,17 @@ search (kpathsea kpse, const_string path, const_string original_name, _djstat_flags = save_djgpp_flags; #endif + /* Free the expanded name we were passed. It can't be in the return + list, since the path directories got unconditionally prepended. */ + free (name); + return STR_LIST (ret_list); } -/* Search PATH for NAMES. Always return a list; if no files are found, - the list will contain just NULL. If ALL is true, the list will be - terminated with NULL. */ +/* Search PATH for null-terminated array of NAMES. Always return a list; + if no files are found, the list will contain just NULL. If ALL is + true, the list will be terminated with NULL (but no NULL terminator + if ALL is false). This is a generalization of the `search' fn above. */ string * kpathsea_path_search_list_generic (kpathsea kpse, @@ -439,27 +629,26 @@ kpathsea_path_search_list_generic (kpathsea kpse, #ifdef KPSE_DEBUG if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) { - DEBUGF1 ("start search(files=[%s", *names); - for (namep = names+1; *namep != NULL; namep++) { - fputc (' ', stderr); - fputs (*namep, stderr); - } - fprintf (stderr, "], must_exist=%d, find_all=%d, path=%s).\n", + DEBUGF ("start generic search(files="); + print_space_list (stderr, names); + fprintf (stderr, ", must_exist=%d, find_all=%d, path=%s)\n", must_exist, all, path); } #endif /* KPSE_DEBUG */ /* kpathsea_find_file_generic in tex-file.c does the variable and - tilde expansion, so don't redo that here. Maybe we should have done - it differently originally, but we certainly don't want to create an + tilde expansion, so don't redo that here. Maybe we should have + done it differently, but we certainly don't want to create an incompatibility now. */ /* First catch any absolute or explicit relative names. */ for (namep = names; *namep; namep++) { if (kpathsea_absolute_p (kpse, *namep, true)) { - if (kpathsea_readable_file (kpse, *namep)) { - str_list_add (&ret_list, xstrdup (*namep)); - if (!all) { + str_list_type abs_ret_list = absolute_search (kpse, *namep); + /* That search can only return a zero- or one-element list, so: */ + if (!STR_LIST_EMPTY (abs_ret_list)) { + str_list_add (&ret_list, STR_LIST_FIRST_ELT (abs_ret_list)); + if (!all) { /* if they only wanted one, we're done */ goto out; } } @@ -471,41 +660,59 @@ kpathsea_path_search_list_generic (kpathsea kpse, we can skip the rest. Typically, if one name is absolute, they all are, because our caller derived them from each other. */ if (all_absolute) { +#ifdef KPSE_DEBUG + if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) { + unsigned i; + DEBUGF (" generic search: all absolute, candidates are:"); + /* List might not be NULL-terminated, so can't use print_space_list. */ + for (i = 0; i < STR_LIST_LENGTH (ret_list); i++) { + fprintf (stderr, " %s", STR_LIST_ELT (ret_list, i)); + } + fputs (".\n", stderr); + } +#endif goto out; } - /* Look at each path element in turn. */ + /* Look at each path element in turn. This is essentially the same + code as `path_search' above, unfortunately. */ for (elt = kpathsea_path_element (kpse, path); !done && elt; elt = kpathsea_path_element (kpse, NULL)) { str_list_type *found; boolean allow_disk_search = true; + if (elt[0] == '!' && elt[1] == '!') { - /* !! magic -> disallow disk searches. */ + /* !! magic string -> disallow disk searches. */ allow_disk_search = false; elt += 2; } - /* See elt-dirs.c for side effects of this function. */ + /* See elt-dirs.c for side effects of this function. */ kpathsea_normalize_path (kpse, elt); - /* Try ls-R, unless we're searching for texmf.cnf. */ + /* Try ls-R, unless we're searching for texmf.cnf. */ found = kpse->followup_search ? kpathsea_db_search_list (kpse, names, elt, all) : NULL; - /* Search the filesystem if (1) the path spec allows it, and either - (2a) we are searching for texmf.cnf ; or - (2b) no db exists; or - (2c) no db's are relevant to this elt; or - (3) MUST_EXIST && NAME was not in the db. - In (2*), `found' will be NULL. - In (3), `found' will be an empty list. */ - if (allow_disk_search && (!found || (must_exist && !STR_LIST (*found)))) { - str_llist_type *dirs = kpathsea_element_dirs (kpse, elt); + /* Search the filesystem in the same cases as `path_search' above. */ + if (allow_disk_search + && (!found || (must_exist && !STR_LIST (*found)))) { + str_llist_type *dirs = kpathsea_element_dirs (kpse, elt); if (dirs && *dirs) { if (!found) { found = XTALLOC1 (str_list_type); } - *found = dir_list_search_list (kpse, dirs, names, all); + /* Search in the directories: */ + *found = dir_list_search_list (kpse, dirs, names, all, + kpathsea_readable_file); +#ifdef KPSE_CASEFOLDING_SEARCH + if (!STR_LIST (*found) && KPSE_CNF_P (kpathsea_var_value (kpse, + "texmf_casefold_search"))) { + /* Still nothing; search again, case-insensitively: */ + *found = dir_list_search_list (kpse, dirs, names, all, + casefold_readable_file); + } +#endif } } @@ -525,7 +732,7 @@ kpathsea_path_search_list_generic (kpathsea kpse, more than once. */ str_list_uniqify (&ret_list); - /* Add NULL if we will be returning multiple elements. */ + /* Add NULL element to terminate return list if empty or multiple. */ if (STR_LIST_EMPTY (ret_list) || (all && STR_LIST_LAST_ELT (ret_list) != NULL)) str_list_add (&ret_list, NULL); @@ -537,12 +744,9 @@ kpathsea_path_search_list_generic (kpathsea kpse, debugging line if we're doing that. */ #ifdef KPSE_DEBUG if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) { - DEBUGF1 ("search([%s", *names); - for (namep = names+1; *namep != NULL; namep++) { - fputc (' ', stderr); - fputs (*namep, stderr); - } - fputs ("]) =>", stderr); + DEBUGF ("returning from generic search("); + print_space_list (stderr, names); + fputs (") =>", stderr); } #endif /* KPSE_DEBUG */ log_search (kpse, ret_list); @@ -578,28 +782,41 @@ kpathsea_path_search (kpathsea kpse, const_string path, const_string name, string * kpathsea_all_path_search (kpathsea kpse, const_string path, const_string name) { - string *ret = search (kpse, path, name, true, true); + string *ret = search (kpse, path, name, true, true); return ret; } #if defined (KPSE_COMPAT_API) string -kpse_path_search (const_string path, const_string name, boolean must_exist) +kpse_path_search (const_string path, const_string name, boolean must_exist) { - return kpathsea_path_search (kpse_def, path, name, must_exist); + return kpathsea_path_search (kpse_def, path, name, must_exist); } string * -kpse_all_path_search (const_string path, const_string name) +kpse_all_path_search (const_string path, const_string name) { - return kpathsea_all_path_search (kpse_def, path, name); + return kpathsea_all_path_search (kpse_def, path, name); } #endif /* KPSE_COMPAT_API */ #ifdef TEST -void +/* Each element of L on its own line, prefixed by a tab. */ + +static void +print_tab_list (string *l) +{ + while (l && *l) { + if (*l) + putchar ('\t'); + printf ("%s\n", *l); + l++; + } +} + +static void test_path_search (const_string path, const_string file) { string answer; @@ -612,40 +829,91 @@ test_path_search (const_string path, const_string file) printf ("Search %s for all %s:\t", path, file); answer_list = kpse_all_path_search (path, file); putchar ('\n'); - while (*answer_list) - { - putchar ('\t'); - puts (*answer_list); - answer_list++; - } + print_tab_list (answer_list); } -#define TEXFONTS "/usr/local/lib/tex/fonts" +static void +test_path_search_list_generic (void) +{ + const_string path = "/u/karl/.fonts"; + /* absolute: should return just console/both, because no case + sensitive match */ + // string names[] = { "/u/karl/.fonts/lucidaConsoleDK.otf", + // "/u/karl/.fonts/lucidaGrandeMonoDK.otf", NULL }; + + /* dirs: should return just grande, because case sensitive wins */ + // string names[] = { "lucidaConsoleDK.otf", "LucidaGrandeMonoDK.otf", NULL }; + + /* dirs: should return just console/both, because no case sensitive match */ + string names[] = { "lucidaConsoleDK.otf", "lucidaGrandeMonoDK.otf", NULL }; + + boolean all; + string *answer_list; + + printf ("\nGeneric search %s for ", path); + print_space_list (stdout, names); + puts (":\t"); + + all = false; answer_list + = kpathsea_path_search_list_generic (kpse_def, path, names, false, all); + puts (answer_list && *answer_list ? *answer_list : "(nil)"); + + printf ("\nGeneric search %s for all ", path); + print_space_list (stdout, names); + puts (":"); + + all = true; answer_list + = kpathsea_path_search_list_generic (kpse_def, path, names, false, all); + print_tab_list (answer_list); +} + +#define TEXFONTS "/usr/local/texlive-rel/texmf-dist/fonts" int main (int argc, char **argv) { + xputenv ("KPATHSEA_DEBUG", "-1"); /* must be before setting progname */ kpse_set_program_name (argv[0], NULL); + + xputenv ("MALLOC_CHECK_", "3"); + xputenv ("MALLOC_PERTURB_", "75"); + + xputenv ("texmf_casefold_search", "1"); + test_path_search (".:/k", "readme"); + exit (0); + test_path_search_list_generic (); + exit (0); + + xputenv ("TEXMFCNF", "/nc"); + /* casefolding with absolute search: */ + test_path_search ("/k", "/u/karl/.fonts/lucidaConsoleDK.otf"); + /* casefolding with directory search: */ + test_path_search ("/u/karl/.fonts", "Lucidaconsoledk.otf"); + /* exit (0); */ + xputenv ("texmf_casefold_search", "0"); + /* should fail since no casefolding: */ + test_path_search ("/u/karl/.fonts", "lucidaconsoledk.otf"); + /* All lists end with NULL. */ test_path_search (".", "nonexistent"); test_path_search (".", "/nonexistent"); - test_path_search ("/k" ENV_SEP_STRING ".", "kpathsea.texi"); + test_path_search ("/k" ENV_SEP_STRING ".", "README"); test_path_search ("/k" ENV_SEP_STRING ".", "/etc/fstab"); test_path_search ("." ENV_SEP_STRING TEXFONTS "//", "cmr10.tfm"); test_path_search ("." ENV_SEP_STRING TEXFONTS "//", "logo10.tfm"); test_path_search (TEXFONTS "//times" ENV_SEP_STRING "." ENV_SEP_STRING ENV_SEP_STRING, "ptmr.vf"); - test_path_search (TEXFONTS "/adobe//" ENV_SEP_STRING - "/usr/local/src/TeX+MF/typefaces//", "plcr.pfa"); + test_path_search (TEXFONTS ENV_SEP_STRING + "/u/karl/.fonts", "LucidaConsoleDK.otf"); - test_path_search ("~karl", ".bashrc"); - test_path_search ("/k", "~karl/.bashrc"); + test_path_search ("~karl", ".profile"); // nil, no ~ expansion on path + test_path_search ("/k", "~karl/.profile"); xputenv ("NONEXIST", "nonexistent"); - test_path_search (".", "$NONEXISTENT"); + test_path_search (".", "$NONEXIST"); xputenv ("KPATHSEA", "kpathsea"); - test_path_search ("/k" ENV_SEP_STRING ".", "$KPATHSEA.texi"); - test_path_search ("/k" ENV_SEP_STRING ".", "${KPATHSEA}.texi"); + test_path_search ("/k" ENV_SEP_STRING "./doc", "$KPATHSEA.texi"); + test_path_search ("/k" ENV_SEP_STRING "./doc", "${KPATHSEA}.texi"); test_path_search ("$KPATHSEA" ENV_SEP_STRING ".", "README"); test_path_search ("." ENV_SEP_STRING "$KPATHSEA", "README"); @@ -655,8 +923,10 @@ main (int argc, char **argv) #endif /* TEST */ -/* +/* ${wc} is the corresponding build directory. + -DMAKE_KPSE_DLL for inlined str_list_init etc. + Memory checking: -fsanitize=address or -lefence. Local variables: -standalone-compile-command: "gcc -posix -g -I. -I.. -DTEST pathsearch.c kpathsea.a" +standalone-compile-command: "make --no-print-dir -C ${wc} && gcc -g -I. -I.. -I${wc}/.. -DMAKE_KPSE_DLL -DTEST pathsearch.c ${wc}/.libs/libkpathsea.a && ./a.out" End: */ diff --git a/Build/source/texk/kpathsea/tests/kpsewhich.test b/Build/source/texk/kpathsea/tests/kpsewhich.test index 6f065f0f328..4b29d139924 100755 --- a/Build/source/texk/kpathsea/tests/kpsewhich.test +++ b/Build/source/texk/kpathsea/tests/kpsewhich.test @@ -1,6 +1,6 @@ #! /bin/sh -vx # $Id$ -# Copyright 2017 Karl Berry +# Copyright 2018 Karl Berry # Copyright 2010-2013 Peter Breitenlohner # You may freely use, modify and/or distribute this file. @@ -8,11 +8,21 @@ TEXMFCNF=$srcdir export TEXMFCNF ./kpsewhich --var-value=TEXMFCNF || exit 1 # environment variable - ./kpsewhich --var-value=TEXMFMAIN || exit 1 - ./kpsewhich --expand-var=\$TEXMFMAIN || exit 1 +# It turns out --all and no --all go through rather different code +# in pathsearch.c, so try them both. +TEXINPUTS=$srcdir/../tests/texmf \ + ./kpsewhich --casefold-search --all Plain.TeX || exit 1 +TEXINPUTS=$srcdir/../tests/texmf \ + ./kpsewhich --casefold-search Plain.TeX || exit 1 +# +TEXINPUTS=$srcdir/../tests/texmf \ + ./kpsewhich --no-casefold-search --all Plain.TeX && exit 1 +TEXINPUTS=$srcdir/../tests/texmf \ + ./kpsewhich --no-casefold-search Plain.TeX && exit 1 + TEXINPUTS=$srcdir/../tests/texmf \ ./kpsewhich --all plain || exit 1 diff --git a/Build/source/texk/kpathsea/texmf.cnf b/Build/source/texk/kpathsea/texmf.cnf index ab81145d03f..4074418d054 100644 --- a/Build/source/texk/kpathsea/texmf.cnf +++ b/Build/source/texk/kpathsea/texmf.cnf @@ -685,6 +685,13 @@ TEX.pmpost = eptex % given as command line option or environment variable. BIBTEX_CSFILE = 88591lat.csf +% This variable is specific to Unix, to fall back to case-insensitive +% search in non-system directories if there is no exact match. It is +% enabled by default in texmf.cnf, but not enabled by default at +% compile-time. +% +texmf_casefold_search = 1 + % This variable is specific to Windows. It must be set to 0 or 1. The % default is 0. Setting it to 1 tells the Windows script wrappers to % use an already installed Perl interpreter if one is found on the diff --git a/Build/source/texk/kpathsea/version.ac b/Build/source/texk/kpathsea/version.ac index ba1c9594c1b..d7e9c33c1a2 100644 --- a/Build/source/texk/kpathsea/version.ac +++ b/Build/source/texk/kpathsea/version.ac @@ -1,5 +1,5 @@ dnl $Id$ -dnl Copyright 2016-2017 Karl Berry +dnl Copyright 2016-2018 Karl Berry dnl Copyright 2011-2015 Peter Breitenlohner dnl dnl This file is free software; the copyright holder @@ -20,4 +20,4 @@ dnl append "dev", to distinguish binaries built between releases. dnl -------------------------------------------------------- dnl dnl this file is m4-included from configure.ac -m4_define([kpse_version], [6.2.4/dev]) +m4_define([kpse_version], [6.3.0/dev]) -- cgit v1.2.3