#!/bin/ksh93 VERSION='$Id: mktexlsr 36855 2015-04-14 12:15:08Z preining $' typeset -r FPROG=${.sh.file} typeset -r PROG=${FPROG##*/} SDIR=${FPROG%/*} function showUsage { [[ -z $1 ]] && X='--man' || X='-?' getopts -a ${PROG} "${ print ${USAGE} ; }" OPT $X } function cleanup { cd / [[ -n ${TDIR} && -d ${TDIR} ]] && rm -rf ${TDIR} } # mktexupd and mktexlsr make sure they're coordinated via this. A copy # is found mktex.opt LS_R_MAGIC='% ls-R -- filename database for kpathsea; do not change this line.' # The old string, which should continue to work. OLD_LS_R_MAGIC='% ls-R -- maintained by MakeTeXls-R; do not change this line.' # Temp working dir TDIR= function doMain { #[[ -z $1 ]] && showUsage 1 && return 1 TDIR=${ mktemp -t -d ${PROG}.XXXXXX ; } [[ -z ${TDIR} ]] && return 2 # Add the location of the script to the PATH if necessary. This must be # done before kpsewhich can be called, and thus cannot be put into mktex.opt [[ ${SDIR:0:1} == '/' ]] && \ PATH="${SDIR}:${PATH}" || PATH="${PWD}/${SDIR}:${PATH}" typeset DIRS DIR DB_DIR DB_FILE X= while [[ -n $1 ]]; do X+="$1\n" shift done # If one uses '\n' as part of a dir name, this stupid egg gets, what it # deserves ... Same thing for dirs with leading or trailing whitespace(s). [[ -z $X ]] && X=${ kpsewhich --show-path=ls-R | tr ':' '\n' ; } print "$X" | sort -u | while read DIR ; do [[ -z ${DIR} ]] && continue [[ -d ${DIR} ]] && DIRS+=( "${DIR}" ) || \ print -u2 "${PROG}: '${DIR}' is not a directory, skipping." done (( ${#DIRS[@]} )) || { print -u2 'Nothing to do - exiting.'; return 0; } for DIR in "${DIRS[@]}" ; do [[ -z ${DIR} ]] && continue # Prepend cwd if the directory was relative. [[ ${DIR:0:1} == '/' ]] || DIR="${PWD}/${DIR}" # Allow for either ls-R and ls-r to exist. But create ls-R if we're # working from scratch. if [[ -f ${DIR}/ls-R ]]; then DB_FILE="${DIR}/ls-R" elif [[ -f ${DIR}/ls-r ]]; then DB_FILE="${DIR}/ls-r" else DB_FILE="${DIR}/ls-R" fi # Follow a possible symlink to get the right filesystem. X=${ kpsereadlink "${DIR}/ls-R" 2>/dev/null ; } if [[ -n $X ]]; then [[ ${X:0:1} == '/' ]] && DB_FILE="$X" || DB_FILE="${DIR}/$X" fi DB_DIR="${DB_FILE%/*}" # want to be silent if the directory doesn't exist, since the ls-R # path ordinarily contains many nonexistent directories. [[ -d ${DB_DIR} ]] || continue if [[ ! -f ${DB_FILE} ]]; then if ! cp /dev/null "${DB_FILE}"; then print -u2 "${PROG}: '${DB_DIR}' directory not writable," 'skipping ...' continue fi # Use same permissions as parent directory, minus x,s, or t bits. chmod ${ kpsestat -xst "${DB_DIR}" ; } "${DB_FILE}" elif [[ -s "${DB_FILE}" ]]; then read X < "${DB_FILE}" # read 1st line if [[ $X != ${LS_R_MAGIC} && $X != ${OLD_LS_R_MAGIC} ]]; then print -u2 "${PROG}: '${DB_FILE}' no magic string, skipping..." continue fi fi # Skip if we cannot write the file: if ! kpseaccess -w "${DB_FILE}" ; then print -u2 "${PROG}: '${DB_FILE}' no write permission, skipping..." continue fi DB_FILE_TMP="${TDIR}/lsR.tmp" rm -f "${DB_FILE_TMP}" (( VERBOSE )) && print "${PROG}: Updating '${DB_FILE}'..." (( DRY_RUN )) && continue print "${LS_R_MAGIC}" >"${DB_FILE_TMP}" # The main task. The sed command removes ., .., and # version control entries from the list. Also omit contents of any # the version directories; sed apparently requires that we do that # operation in a separate invocation. We do not try to support colons # in directory names. print './:' >>"${DB_FILE_TMP}" VC_DIRS='\.\(bzr\|git\|hg\|svn\)\|_darcs' ( cd "${DIR}" && \ls -LRa 2>/dev/null ) | \ sed -e '/^$/ n' \ -e '/^\.$/ d' \ -e '/^\.\.$/ d' \ -e '/^'${VC_DIRS}'$/ d;' | \ sed -e /${VC_DIRS}'.*:$/,/^$/ d' \ >>"${DB_FILE_TMP}" # this shouldn't take much time cp "${DB_FILE_TMP}" "${DB_FILE}" done (( VERBOSE )) && print "${PROG}: Done." return 0 } USAGE='[-?'"${VERSION}"' ] [-author?Thomas Esser (1994 "texhash")] [-author?Jens Elkner (2015 ksh93 port/cleanup)] [-license?Public domain.] [+NAME?'"${PROG}"' - create or rebuild ls-R file(s)] [+DESCRIPTION?'"${PROG}"' rebuilds \bls-R\b filename databases used by TeX. If one or more \adirectory\a operands are given, these are used as the directories in which to build \bls-R\b. Otherwise all directories in the search path for \bls-R\b files (\b$TEXMFDBS\b) are used.] [+?For more information, see the \bFilename database\b section of Kpathsea manual available at \bhttp://tug.org/kpathsea/\b.] [h:help?Print this help and exit.] [F:functions?Print a list of all functions available.] [T:trace]:[fnList?A comma separated list of functions of this script to trace (convinience for troubleshooting).] [+?] [n:dry-run?Do not actually update anything.] [q:quiet?Cancel --verbose.] [s:silent?Same as --quiet.] [v:verbose?Explain what is being done (default, if standard input is a terminal).] [V:version?Output version information and exit.] [+BUGS?Report bugs to: tex-k@tug.org] [+?TeX Live home page: \bhttp://tug.org/texlive/\b.] \n\n\adirectory\a ... ' X="${ print ${USAGE} ; }" integer VERBOSE=0 DRY_RUN=0 tty -s && VERBOSE=1 while getopts "${X}" OPT ; do case ${OPT} in h) showUsage ; exit 0 ;; T) if [[ ${OPTARG} == 'ALL' ]]; then typeset -ft ${ typeset +f ; } else typeset -ft ${OPTARG//,/ } fi ;; F) typeset +f && exit 0 ;; V) print "${PROG} ${VERSION}" ; kpsewhich --version ; exit 0 ;; v) VERBOSE=1 ;; n) DRY_RUN=1 ;; q|s) VERBOSE=0 ;; *) showUsage 1; exit 1 ;; esac done X=$((OPTIND-1)) shift $X && OPTIND=1 unset X trap cleanup EXIT doMain "$@"