diff --git a/source/build-aux/config.guess b/source/build-aux/config.guess
index 8e2a58b864fd4c0bd174bd1d8faeeb1c62b3afe2..a81aa505ba845d2161cf11d04521db37f0d1137c 100755
--- a/source/build-aux/config.guess
+++ b/source/build-aux/config.guess
@@ -2,7 +2,7 @@
 # Attempt to guess a canonical system name.
 #   Copyright 1992-2019 Free Software Foundation, Inc.
 
-timestamp='2019-01-03'
+timestamp='2019-01-15'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -385,20 +385,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
 	echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
 	exit ;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
-	set_cc_for_build
-	SUN_ARCH=sparc
-	# If there is a compiler, see if it is configured for 64-bit objects.
-	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
-	# This test works for both compilers.
-	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
-	    if (echo '#ifdef __sparcv9'; echo IS_64BIT_ARCH; echo '#endif') | \
-		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
-		grep IS_64BIT_ARCH >/dev/null
-	    then
-		SUN_ARCH=sparcv9
-	    fi
-	fi
-	echo "$SUN_ARCH"-sun-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+	echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
 	exit ;;
     i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
 	echo i386-pc-auroraux"$UNAME_RELEASE"
diff --git a/source/build-aux/config.sub b/source/build-aux/config.sub
index a8f3f7e7cde8d60f4956d7e7fc0e56dc6609cf9a..3b4c7624b68d2d7f84618e1b5fa2badd43a48325 100755
--- a/source/build-aux/config.sub
+++ b/source/build-aux/config.sub
@@ -2,7 +2,7 @@
 # Configuration validation subroutine script.
 #   Copyright 1992-2019 Free Software Foundation, Inc.
 
-timestamp='2019-01-01'
+timestamp='2019-01-05'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -111,6 +111,7 @@ case $# in
 esac
 
 # Split fields of configuration type
+# shellcheck disable=SC2162
 IFS="-" read field1 field2 field3 field4 <<EOF
 $1
 EOF
@@ -918,6 +919,7 @@ case $basic_machine in
 		;;
 
 	*-*)
+		# shellcheck disable=SC2162
 		IFS="-" read cpu vendor <<EOF
 $basic_machine
 EOF
@@ -1183,13 +1185,13 @@ case $cpu-$vendor in
 			| le32 | le64 \
 			| lm32 \
 			| m32c | m32r | m32rle \
-			| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k | v70 | w65 \
-			| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip \
+			| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
+			| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
 			| m88110 | m88k | maxq | mb | mcore | mep | metag \
 			| microblaze | microblazeel \
 			| mips | mipsbe | mipseb | mipsel | mipsle \
 			| mips16 \
-			| mips64 | mips64el \
+			| mips64 | mips64eb | mips64el \
 			| mips64octeon | mips64octeonel \
 			| mips64orion | mips64orionel \
 			| mips64r5900 | mips64r5900el \
@@ -1216,11 +1218,12 @@ case $cpu-$vendor in
 			| nds32 | nds32le | nds32be \
 			| nfp \
 			| nios | nios2 | nios2eb | nios2el \
-			| none | np1 | ns16k | ns32k \
+			| none | np1 | ns16k | ns32k | nvptx \
 			| open8 \
 			| or1k* \
 			| or32 \
 			| orion \
+			| picochip \
 			| pdp10 | pdp11 | pj | pjl | pn | power \
 			| powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
 			| pru \
@@ -1228,7 +1231,8 @@ case $cpu-$vendor in
 			| riscv | riscv32 | riscv64 \
 			| rl78 | romp | rs6000 | rx \
 			| score \
-			| sh | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
+			| sh | shl \
+			| sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
 			| sh[1234]e[lb] |  sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
 			| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
 			| sparclite \
@@ -1238,10 +1242,10 @@ case $cpu-$vendor in
 			| tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
 			| tron \
 			| ubicom32 \
-			| v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
+			| v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
 			| vax \
 			| visium \
-			| wasm32 \
+			| w65 | wasm32 \
 			| we32k \
 			| x86 | x86_64 | xc16x | xgate | xps100 \
 			| xstormy16 | xtensa* \
diff --git a/source/build-aux/texinfo.tex b/source/build-aux/texinfo.tex
index 66a832e0b4f2479b9d792a5a596eb3f5bf120fb7..48d532bc6261b7bee88c87096b97df03164214e2 100644
--- a/source/build-aux/texinfo.tex
+++ b/source/build-aux/texinfo.tex
@@ -3,7 +3,8 @@
 % Load plain if necessary, i.e., if running under initex.
 \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
 %
-\def\texinfoversion{2018-12-28.17}
+\def\texinfoversion{2019-01-03-15}
+
 %
 % Copyright 1985, 1986, 1988, 1990-2018 Free Software Foundation, Inc.
 %
@@ -5043,8 +5044,8 @@ end
   \commondummyword\xref
 }
 
-% For testing: output @{ and @} in index sort strings as \{ and \}.
-\newif\ifusebracesinindexes
+% This does nothing, but for a time it was recommended to use
+% \usebracesinindexestrue to be able to use braces in index entries.
 
 \let\indexlbrace\relax
 \let\indexrbrace\relax
diff --git a/source/libs/README b/source/libs/README
index ec47781e585fa4b0bf1cd64e1a2572e65ee4514f..92d5bc7a4c5ee374f6889b73e8e20e89f712a9d4 100644
--- a/source/libs/README
+++ b/source/libs/README
@@ -1,4 +1,4 @@
-$Id: README 49473 2018-12-22 00:39:38Z kakuto $
+$Id: README 49641 2019-01-08 19:24:46Z karl $
 Public domain.  Originally created by Karl Berry, 2005.
 
 Libraries we compile for TeX Live.
@@ -28,7 +28,7 @@ graphite2 1.3.13 - checked 21dec18
 harfbuzz 2.3.0 - checked 22dec18
   http://www.freedesktop.org/software/harfbuzz/release/
 
-icu 61.1 - checked 29mar18
+icu 63.1 - checked 8jan19
   http://download.icu-project.org/files/icu4c/
 
 libpaper 1.1.24+nmu2 - checked 24oct13
diff --git a/source/libs/luajit/configure b/source/libs/luajit/configure
index f96fff5e37786498694078d59c7b992f08f8e073..1c0ad48d980a74ad56a65566f0099fdfedca451a 100755
--- a/source/libs/luajit/configure
+++ b/source/libs/luajit/configure
@@ -14372,15 +14372,6 @@ case $host_os:$host_cpu in #(
   *) :
      ;;
 esac
-case $host_os:$host_cpu:$CC in #(
-  *openbsd*:x86_64:clang) :
-    LIBLUAJIT_LDEXTRA='-lc++abi -lpthread' ;; #(
-  *openbsd*:i386:clang) :
-    LIBLUAJIT_LDEXTRA='-lc++abi -lpthread' ;; #(
-  *) :
-     ;;
-esac
-
 
 
  if test "x$enable_build" != xno; then
diff --git a/source/libs/luajit/configure.ac b/source/libs/luajit/configure.ac
index c4d73344ee32c9426f5770ad9ac2a238c4c7e15d..f3e20d48159412674edc7c04439e9aac52062f83 100644
--- a/source/libs/luajit/configure.ac
+++ b/source/libs/luajit/configure.ac
@@ -63,18 +63,10 @@ AC_SUBST([LUAJIT_CFLAGS])
 AC_SUBST([LJHOST])
 AC_SUBST([LJVM_MODE])
 
-dnl Extra switches
-dnl We support openbsd x86_64 and i386,
-dnl other platforms could be require different switches .
-dnl
 AS_CASE([$host_os:$host_cpu],
-        [*darwin*:x86_64],  [LIBLUAJIT_LDEXTRA='-image_base 7fff04c4a000'])
-AS_CASE([$host_os:$host_cpu:$CC],
-        [*openbsd*:x86_64:clang], [LIBLUAJIT_LDEXTRA='-lc++abi -lpthread'],
-        [*openbsd*:i386:clang], [LIBLUAJIT_LDEXTRA='-lc++abi -lpthread'])
+        [*darwin*:x86_64], [LIBLUAJIT_LDEXTRA='-image_base 7fff04c4a000'])
 AC_SUBST([LIBLUAJIT_LDEXTRA])
 
-
 AM_CONDITIONAL([build], [test "x$enable_build" != xno])
 
 if test "x$enable_build" != xno || test -f config.force; then
diff --git a/source/m4/ChangeLog b/source/m4/ChangeLog
index 957005d800d6a12f1d6543bbeee2c3624208f26b..e5f5d9f0d50ca02d9d182baf1fb8a5aaf48c30b0 100644
--- a/source/m4/ChangeLog
+++ b/source/m4/ChangeLog
@@ -1,3 +1,19 @@
+2019-01-11  Karl Berry  <karl@freefriends.org>
+
+	* kpse-luajit-flags.m4 (KPSE_LUAJIT_FLAGS): try LIBLUAJIT_LDEXTRA,
+	following (sort of):
+	https://github.com/TeX-Live/luatex/commit/273de1c6308ab9378905a5e1929b19207e2765af
+
+2019-01-10  Karl Berry  <karl@freefriends.org>
+
+	* kpse-luajit-flags.m4 (KPSE_LUAJIT_FLAGS): check for
+	-lc++abi -lpthread, needed with clang on openbsd.
+	Test from Mojca.
+
+2019-01-08  Karl Berry  <karl@tug.org>
+
+	* kpse-pkgs.m4 (KPSE_LIBS_PKGS): lua52 gone.
+
 2018-12-24  Karl Berry  <karl@freefriends.org>
 
 	* kpse-common.m4,
diff --git a/source/m4/kpse-luajit-flags.m4 b/source/m4/kpse-luajit-flags.m4
index e846c3087f2943930c0552b8b91c35506f84c5b7..1677a72742a96a21461ba9f98c2a2c76fa57ab0f 100644
--- a/source/m4/kpse-luajit-flags.m4
+++ b/source/m4/kpse-luajit-flags.m4
@@ -1,5 +1,7 @@
+# $Id$
 # Public macros for the TeX Live (TL) tree.
-# Copyright (C) 2014 Peter Breitenlohner <tex-live@tug.org>
+# Copyright 2019 Karl Berry <tex-live@tug.org>
+# Copyright 2014 Peter Breitenlohner <tex-live@tug.org>
 #
 # This file is free software; the copyright holder
 # gives unlimited permission to copy and/or distribute it,
@@ -10,9 +12,53 @@
 # Set the make variables LUAJIT_INCLUDES and LUAJIT_LIBS to the CPPFLAGS and
 # LIBS required for the `-ltexluajit' library in libs/luajit/ of the TL tree.
 AC_DEFUN([KPSE_LUAJIT_FLAGS], [dnl
+echo 'tldbg:[$0] called.' >&AS_MESSAGE_LOG_FD
 _KPSE_LIB_FLAGS([luajit], [texluajit], [lt tree],
-                [-IBLD/libs/luajit/include], [BLD/libs/luajit/libtexluajit.la], [],
-                [], [${top_builddir}/../../libs/luajit/include/luajit.h])[]dnl
+                [-IBLD/libs/luajit/include],
+                [BLD/libs/luajit/libtexluajit.la],
+                [],
+                [],
+                [${top_builddir}/../../libs/luajit/include/luajit.h])[]dnl
+#
+# checking for openbsd for additional jit libraries needed, which is the
+# case for clang; no point in going to the trouble elsewhere since no
+# other system needs it.
+case $build_os in
+openbsd*)
+AC_MSG_CHECKING([on openbsd if additional jit libraries are needed])
+AC_LINK_IFELSE(
+  [AC_LANG_PROGRAM(
+    [[#include "stdint.h"
+      typedef struct _Unwind_Context _Unwind_Context;
+      extern uintptr_t _Unwind_GetCFA(_Unwind_Context *);]],
+    [[_Unwind_Context *ctx;
+      _Unwind_GetCFA(ctx);]]
+  )],
+  [AC_MSG_RESULT([no])],
+  [
+    jitlibs="-lc++abi -lpthread"
+    save_LIBS=$LIBS
+    LIBS="$LIBS $jitlibs"
+    AC_LINK_IFELSE(
+      [AC_LANG_PROGRAM(
+        [[#include "stdint.h"
+          typedef struct _Unwind_Context _Unwind_Context;
+          extern uintptr_t _Unwind_GetCFA(_Unwind_Context *);]],
+        [[_Unwind_Context *ctx;
+          _Unwind_GetCFA(ctx);]]
+      )],
+      [
+        AC_MSG_RESULT(["$jitlibs"])
+        LIBLUAJIT_LDEXTRA="$LIBLUAJIT_LDEXTRA $jitlibs"
+      ],
+      [AC_MSG_FAILURE([luajit could not be linked])]
+    )
+    LIBS=$save_LIBS
+  ]
+)
+  ;;
+esac
+echo 'tldbg:[$0] done.' >&AS_MESSAGE_LOG_FD
 ]) # KPSE_LUAJIT_FLAGS
 
 # KPSE_LUAJIT_DEFINES
diff --git a/source/m4/kpse-pkgs.m4 b/source/m4/kpse-pkgs.m4
index 50df0e583c18bc073254409eb61046746f7904a7..334a4225101917bef4bc53cc018c130e5e86f63e 100644
--- a/source/m4/kpse-pkgs.m4
+++ b/source/m4/kpse-pkgs.m4
@@ -1,6 +1,6 @@
-# $Id: kpse-pkgs.m4 49495 2018-12-24 23:17:30Z karl $
+# $Id: kpse-pkgs.m4 49640 2019-01-08 18:57:53Z karl $
 # Private Autoconf macros for the TeX Live (TL) tree.
-# Copyright 2016-2018 Karl Berry <tex-live@tug.org>
+# Copyright 2016-2019 Karl Berry <tex-live@tug.org>
 # Copyright 2009-2015 Peter Breitenlohner <tex-live@tug.org>
 #
 # This file is free software; the copyright holder
@@ -41,7 +41,6 @@ freetype2
 libpng
 libpaper
 luajit
-lua52
 lua53
 zlib
 ])[]dnl
diff --git a/source/texk/kpathsea/ChangeLog b/source/texk/kpathsea/ChangeLog
index 5d0e755174cebafeff43d9dbf030edf5557e8ff5..52ce7a51ed9acdd93f6f879e54ef9116f86eb7fe 100644
--- a/source/texk/kpathsea/ChangeLog
+++ b/source/texk/kpathsea/ChangeLog
@@ -1,3 +1,18 @@
+2019-01-19  Karl Berry  <karl@freefriends.org>
+
+	* variable.h (kpathsea_var_expand): returns string "$FOO" if FOO
+	is not defined, not the empty string; whereas ${FOO} does return
+	the empty string. Maybe not the ideal interface, but seems
+	undesirable to change now.
+	* doc/kpathsea.texi (Programming with config files),
+	(Auxiliary tasks): document this.
+	Noted by Andreas Scherer, r49726.
+
+2019-01-19  Karl Berry  <karl@tug.org>
+
+	* texmf.cnf (TEXMFLOCALEDIR): define as $TEXMFMAIN/locale,
+	for cweb translations now, and hopefully more later.
+
 2018-12-30  Karl Berry  <karl@tug.org>
 
 	* texmf.cnf (shell_escape_commands): make that r-mpost.
diff --git a/source/texk/kpathsea/doc/kpathsea.info b/source/texk/kpathsea/doc/kpathsea.info
index b6438df80adcbd18a3fe05fe61bd2f89740e6324..377d74391ef96ff9d1f8680df1579dd0ca736429 100644
--- a/source/texk/kpathsea/doc/kpathsea.info
+++ b/source/texk/kpathsea/doc/kpathsea.info
@@ -3,7 +3,7 @@ kpathsea.texi.
 
 This file documents the Kpathsea library for path searching.
 
-   Copyright (C) 1996-2018 Karl Berry & Olaf Weber.
+   Copyright (C) 1996-2019 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.3.0, released in December 2018.
+corresponds to version 6.3.0, released in January 2019.
 
 * Menu:
 
@@ -62,7 +62,7 @@ File: kpathsea.info,  Node: Introduction,  Next: unixtex.ftp,  Prev: Top,  Up: T
 **************
 
 This manual corresponds to version 6.3.0 of the Kpathsea library,
-released in December 2018.
+released in January 2019.
 
    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
@@ -1450,6 +1450,9 @@ Kpsewhich provides some features in addition to path lookup as such:
      Output the variable and tilde expansion of STRING.  For example,
      with the usual 'texmf.cnf', 'kpsewhich --expand-var='$TEXMF''
      returns the TeX system hierarchy root(s).  *Note Path expansion::.
+     The specified STRING can contain anything, though, not just
+     variable references.  This calls 'kpse_var_expand' (*note
+     Programming with config files::).
 
 '--help-formats'
      Output information about each supported format (*note Supported
@@ -2484,18 +2487,22 @@ You can (and probably should) use the same 'texmf.cnf' configuration
 file that Kpathsea uses for your program.  This helps installers by
 keeping all configuration in one place.
 
-   To retrieve a value VAR from config files, the best way is to call
-'kpathsea_var_value' on the string 'VAR'.  This will look first for an
-environment variable VAR, then a config file value.  The result will be
-the value found or 'NULL'.  This function is declared in
+   To retrieve a value for a configuration variable VAR, the best way is
+to call 'kpathsea_var_value' on the string 'VAR'.  This will look first
+for an environment variable VAR, then a config file value.  The result
+will be the value found or 'NULL'.  This function is declared in
 'kpathsea/variable.h'.  For an example, see the 'shell_escape' code in
 'web2c/lib/texmfmp.c'.
 
-   The routine to do variable expansion in the context of a search path
-(as opposed to simply retrieving a value) is 'kpathsea_var_expand', also
-declared in 'kpathsea/variable.h'.  It's generally only necessary to set
+   The routine to do full variable and tilde expansion of an arbitrary
+string in the context of a search path (as opposed to simply retrieving
+a value) is 'kpathsea_var_expand', also declared in
+'kpathsea/variable.h'.  However, it's generally only necessary to set
 the search path structure components as explained in the previous
-section, rather than using this yourself.
+section instead of using this directly.  Because of its usage with any
+input string, undefined '$FOO' constructs in the argument to
+'kpathsea_var_expand' are returned literally ('"$FOO"'), while undefined
+'${FOO}' constructs are expanded to the empty string.
 
    If for some reason you want to retrieve a value _only_ from a config
 file, not automatically looking for a corresponding environment
@@ -2974,7 +2981,7 @@ Index
 * --format=NAME:                         Path searching options.
                                                               (line  48)
 * --help:                                Standard options.    (line   8)
-* --help-formats:                        Auxiliary tasks.     (line  39)
+* --help-formats:                        Auxiliary tasks.     (line  42)
 * --interactive:                         Path searching options.
                                                               (line 130)
 * --mktex=FILETYPE:                      Path searching options.
@@ -2991,13 +2998,13 @@ Index
                                                               (line 151)
 * --progname=NAME:                       Path searching options.
                                                               (line 159)
-* --safe-in-name=NAME:                   Auxiliary tasks.     (line  45)
-* --safe-out-name=NAME:                  Auxiliary tasks.     (line  45)
-* --show-path=NAME:                      Auxiliary tasks.     (line  51)
+* --safe-in-name=NAME:                   Auxiliary tasks.     (line  48)
+* --safe-out-name=NAME:                  Auxiliary tasks.     (line  48)
+* --show-path=NAME:                      Auxiliary tasks.     (line  54)
 * --subdir=STRING:                       Path searching options.
                                                               (line 164)
-* --var-brace-value=VARIABLE:            Auxiliary tasks.     (line  57)
-* --var-value=VARIABLE:                  Auxiliary tasks.     (line  71)
+* --var-brace-value=VARIABLE:            Auxiliary tasks.     (line  60)
+* --var-value=VARIABLE:                  Auxiliary tasks.     (line  74)
 * --version:                             Standard options.    (line  11)
 * --with-mktextex-default:               mktex configuration. (line  12)
 * --without-mktexfmt-default:            mktex configuration. (line  12)
@@ -3204,7 +3211,7 @@ Index
 * cmr10.vf:                              Searching overview.  (line  31)
 * cnf.c:                                 Config files.        (line  86)
 * cnf.h:                                 Programming with config files.
-                                                              (line  23)
+                                                              (line  27)
 * comments, in fontmap files:            Fontmap.             (line  27)
 * comments, in texmf.cnf:                Config files.        (line  27)
 * comments, making:                      Introduction.        (line  29)
@@ -3407,7 +3414,7 @@ Index
 * kpathsea.h:                            Programming overview.
                                                               (line  26)
 * kpathsea_cnf_get:                      Programming with config files.
-                                                              (line  23)
+                                                              (line  27)
 * KPATHSEA_DEBUG:                        Calling sequence.    (line  28)
 * KPATHSEA_DEBUG <1>:                    Debugging.           (line  18)
 * kpathsea_find_file:                    File lookup.         (line  38)
@@ -3866,61 +3873,61 @@ Index
 
 Tag Table:
 Node: Top1480
-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 expansion32816
-Node: Subdirectory expansion33329
-Node: Casefolding search35683
-Node: Casefolding rationale36452
-Node: Casefolding examples37791
-Node: Filename database42841
-Node: ls-R43899
-Node: Filename aliases46794
-Node: Database format47972
-Node: Invoking kpsewhich48985
-Node: Path searching options49940
-Node: Specially-recognized files58459
-Node: Auxiliary tasks59814
-Node: Standard options63353
-Node: TeX support63709
-Node: Supported file formats65063
-Node: File lookup72728
-Node: Glyph lookup74477
-Node: Basic glyph lookup75601
-Node: Fontmap76481
-Node: Fallback font79010
-Node: Suppressing warnings79922
-Node: mktex scripts81049
-Node: mktex configuration82264
-Node: mktex script names88067
-Node: mktex script arguments89453
-Node: Programming90332
-Node: Programming overview90905
-Node: Calling sequence93766
-Node: Program-specific files100298
-Node: Programming with config files101321
-Node: Reporting bugs102633
-Node: Bug checklist103311
-Node: Mailing lists106783
-Node: Debugging107458
-Node: Logging112535
-Node: Common problems114402
-Node: Unable to find files114879
-Node: Slow path searching117289
-Node: Unable to generate fonts118664
-Node: TeX or Metafont failing121135
-Node: Index122337
+Node: Introduction2262
+Node: History4334
+Node: unixtex.ftp8930
+Node: Security10355
+Node: TeX directory structure12859
+Node: Path searching16907
+Node: Searching overview17634
+Node: Path sources21453
+Node: Config files22544
+Node: Path expansion26471
+Node: Default expansion27424
+Node: Variable expansion29494
+Node: Tilde expansion30895
+Node: Brace expansion31875
+Node: KPSE_DOT expansion32814
+Node: Subdirectory expansion33327
+Node: Casefolding search35681
+Node: Casefolding rationale36450
+Node: Casefolding examples37789
+Node: Filename database42839
+Node: ls-R43897
+Node: Filename aliases46792
+Node: Database format47970
+Node: Invoking kpsewhich48983
+Node: Path searching options49938
+Node: Specially-recognized files58457
+Node: Auxiliary tasks59812
+Node: Standard options63518
+Node: TeX support63874
+Node: Supported file formats65228
+Node: File lookup72893
+Node: Glyph lookup74642
+Node: Basic glyph lookup75766
+Node: Fontmap76646
+Node: Fallback font79175
+Node: Suppressing warnings80087
+Node: mktex scripts81214
+Node: mktex configuration82429
+Node: mktex script names88232
+Node: mktex script arguments89618
+Node: Programming90497
+Node: Programming overview91070
+Node: Calling sequence93931
+Node: Program-specific files100463
+Node: Programming with config files101486
+Node: Reporting bugs103073
+Node: Bug checklist103751
+Node: Mailing lists107223
+Node: Debugging107898
+Node: Logging112975
+Node: Common problems114842
+Node: Unable to find files115319
+Node: Slow path searching117729
+Node: Unable to generate fonts119104
+Node: TeX or Metafont failing121575
+Node: Index122777
 
 End Tag Table
diff --git a/source/texk/kpathsea/doc/kpathsea.texi b/source/texk/kpathsea/doc/kpathsea.texi
index 449bd0e74893b06ad984492f0a88b46314dfa75c..1dd8e3f57bec20504d44ac5d25d0c1f463241616 100644
--- a/source/texk/kpathsea/doc/kpathsea.texi
+++ b/source/texk/kpathsea/doc/kpathsea.texi
@@ -3,12 +3,12 @@
 @settitle Kpathsea: A library for path searching
 
 @set version 6.3.0
-@set month-year December 2018
+@set month-year January 2019
 
 @copying
 This file documents the Kpathsea library for path searching.
 
-Copyright @copyright{} 1996--2018 Karl Berry & Olaf Weber.
+Copyright @copyright{} 1996--2019 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
@@ -1795,10 +1795,12 @@ For one-shot uses of an arbitrary (not built in to Kpathsea) path, see
 
 @item --expand-var=@var{string}
 @opindex --expand-var=@var{string}
-Output the variable and tilde expansion of @var{string}. For example,
+Output the variable and tilde expansion of @var{string}.  For example,
 with the usual @file{texmf.cnf}, @samp{kpsewhich
 --expand-var='$TEXMF'} returns the @TeX{} system hierarchy root(s).
-@xref{Path expansion}.
+@xref{Path expansion}.  The specified @var{string} can contain
+anything, though, not just variable references.  This calls
+@code{kpse_var_expand} (@pxref{Programming with config files}).
 
 @item --help-formats
 @opindex --help-formats
@@ -3264,18 +3266,24 @@ installers by keeping all configuration in one place.
 @findex kpathsea_var_value
 @flindex variable.h
 @vindex shell_escape@r{, example for code}
-To retrieve a value @var{var} from config files, the best way is to call
-@code{kpathsea_var_value} on the string @code{@var{var}}.  This will look
-first for an environment variable @var{var}, then a config file value.
-The result will be the value found or @samp{NULL}.  This function is
-declared in @file{kpathsea/variable.h}.  For an example, see the
+To retrieve a value for a configuration variable @var{var}, the best
+way is to call @code{kpathsea_var_value} on the string
+@code{@var{var}}.  This will look first for an environment variable
+@var{var}, then a config file value.  The result will be the value
+found or @samp{NULL}.  This function is declared in
+@file{kpathsea/variable.h}.  For an example, see the
 @code{shell_escape} code in @file{web2c/lib/texmfmp.c}.
 
-The routine to do variable expansion in the context of a search path (as
-opposed to simply retrieving a value) is @code{kpathsea_var_expand}, also
-declared in @file{kpathsea/variable.h}.  It's generally only necessary
-to set the search path structure components as explained in the previous
-section, rather than using this yourself.
+The routine to do full variable and tilde expansion of an arbitrary
+string in the context of a search path (as opposed to simply
+retrieving a value) is @code{kpathsea_var_expand}, also declared in
+@file{kpathsea/variable.h}.  However, it's generally only necessary to
+set the search path structure components as explained in the previous
+section instead of using this directly.  Because of its usage with any
+input string, undefined @code{$FOO} constructs in the argument to
+@code{kpathsea_var_expand} are returned literally (@code{"$FOO"}),
+while undefined @code{$@{FOO@}} constructs are expanded to the empty
+string.
 
 @findex kpathsea_cnf_get
 @flindex cnf.h
diff --git a/source/texk/kpathsea/texmf.cnf b/source/texk/kpathsea/texmf.cnf
index 65c5c40c687c2436993ed2c9c3f3fe7c0b5d9f81..3c5ae3018c0e08f92d1aa111fde36b19c5cf3705 100644
--- a/source/texk/kpathsea/texmf.cnf
+++ b/source/texk/kpathsea/texmf.cnf
@@ -430,6 +430,11 @@ FC_CACHEDIR = $TEXMFSYSVAR/fonts/cache
 TEXDOCS = $TEXMF/doc//
 TEXSOURCES = $TEXMFDOTDIR;$TEXMF/source//
 
+% Top-level directory for any string translations for the binaries, in
+% the same structure as the usual system locale/ directories. This is a
+% single directory, not a path.
+TEXMFLOCALEDIR = $TEXMFMAIN/locale
+
 % Web and CWeb input paths.
 WEBINPUTS = $TEXMFDOTDIR;$TEXMF/web//
 CWEBINPUTS = $TEXMFDOTDIR;$TEXMF/cweb//
diff --git a/source/texk/kpathsea/variable.h b/source/texk/kpathsea/variable.h
index ab4a22a6924c9e278d5317d7db3b475a19b5e07b..6bd2a62bf988c55aac10852ca54be694c86c97f0 100644
--- a/source/texk/kpathsea/variable.h
+++ b/source/texk/kpathsea/variable.h
@@ -1,6 +1,6 @@
 /* variable.h: declare variable expander.
 
-   Copyright 1993, 1995, 2008 Karl Berry.
+   Copyright 1993, 1995, 2008, 2019 Karl Berry.
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -39,7 +39,9 @@ extern KPSEDLL string kpathsea_var_value (kpathsea kpse, const_string var);
 
    In any case, ``expansion'' means calling `getenv'; if the variable is not
    set, look in texmf.cnf files for a definition.  If not set there, either,
-   the expansion is the empty string (no error).  */
+   the expansion of a $FOO construct is its literal text ("$FOO"), while
+   the expansion of a ${BAR} construct is the empty string.  This is so
+   at least some file names containing $ characters will work.  */
 extern KPSEDLL string kpathsea_var_expand (kpathsea kpse, const_string src);
 
 #if defined (KPSE_COMPAT_API)
diff --git a/source/texk/web2c/ChangeLog b/source/texk/web2c/ChangeLog
index 4960c098620858a2e0c70c5496b004b420210857..6dec8c637141b25496cda3e90d4d7da5032facab 100644
--- a/source/texk/web2c/ChangeLog
+++ b/source/texk/web2c/ChangeLog
@@ -1,3 +1,46 @@
+2019-01-19  Andreas Scherer  <https://ascherer.github.io>
+
+	* help.h: Fix CTWILL '--help' text.
+
+2019-01-15  Andreas Scherer  <https://ascherer.github.io>
+
+	* cwebboot.cin: Provisional 'bindtextdomain' lookup in TDS.
+
+2019-01-10  Andreas Scherer  <https://ascherer.github.io>
+
+	* help.h (CTWILLHELP): update.
+
+2019-01-09  Andreas Scherer  <https://ascherer.github.io>
+	
+	* help.h (CTANGLEHELP, CWEAVEHELP, CTWILLHELP): update.
+
+2019-01-06  Andreas Scherer  <https://ascherer.github.io>
+
+	Integration of CWEBbin as the new CWEB in TeX Live,
+	https://github.com/ascherer/cwebbin.
+	
+	Purge cweb.h and cwebboot.h[in] from CWEB build process.
+	* am/bootstrap.am (cweb.h): no longer created at common-ctangle.
+	(DISTCLEANFILES): do not remove cweb.h or cwebboot.h.
+	$(ctangleboot_OBJECTS): do not depend on cwebboot.h.
+	(EXTRA_DIST): omit no-longer-created cwebboot.hin.
+	(ctangle.c),
+	* am/cweb.am (cweave.c): depend on new file cwebdir/comm-w2c.h,
+	instead of common.h.
+	$(cweave_OBJECTS): remove rule.
+	* ctangleboot-sh.in <common>: only generate .c, not .h;
+	don't try to #include cwebboot.h.
+	* ctangleboot.cin,
+	* cwebboot.cin: regenerate.
+	* cwebboot.hin: delete.
+	* help.h (CTWILLHELP): new help string.
+	(CTANGLEHELP, CWEAVEHELP): update.
+	
+	Add CTWILL material on top of CWEAVE.
+	* am/bootstrap.am (NEVER_DIST): omit {ctwill,refsort,twinx}.{log,trs}.
+	* am/cweb.am (bin_programs): add ctwill, ctwill-refsort, ctwill-twinx,
+	with related targets and dependencies.
+
 2018-12-30  Karl Berry  <karl@tug.org>
 
 	* mplibdir/am/mplib.am,
diff --git a/source/texk/web2c/Makefile.in b/source/texk/web2c/Makefile.in
index ea032018d472b8fdac0787a42394f389c6fd1c17..9d32fe46b49c08bed58627724136dd26c4febe8c 100644
--- a/source/texk/web2c/Makefile.in
+++ b/source/texk/web2c/Makefile.in
@@ -106,15 +106,17 @@ EXTRA_PROGRAMS = $(am__EXEEXT_1) tex$(EXEEXT) mf$(EXEEXT) \
 	xetex$(EXEEXT) $(am__EXEEXT_4) aleph$(EXEEXT) synctex$(EXEEXT) \
 	md5main$(EXEEXT)
 bin_PROGRAMS = tangle$(EXEEXT) ctangle$(EXEEXT) $(am__EXEEXT_5) \
-	ctie$(EXEEXT) cweave$(EXEEXT) tie$(EXEEXT) $(am__EXEEXT_6) \
-	$(am__EXEEXT_7) $(am__EXEEXT_8) $(am__EXEEXT_9) \
-	$(am__EXEEXT_10) $(am__EXEEXT_11) $(am__EXEEXT_12) \
-	$(am__EXEEXT_13) $(am__EXEEXT_14) $(am__EXEEXT_15) \
-	$(am__EXEEXT_16) $(am__EXEEXT_17) $(am__EXEEXT_18) \
-	$(am__EXEEXT_19) $(am__EXEEXT_20) $(am__EXEEXT_21) \
-	$(am__EXEEXT_22) $(am__EXEEXT_23) $(am__EXEEXT_24) \
-	$(am__EXEEXT_25) $(am__EXEEXT_26) $(am__EXEEXT_27) \
-	$(am__EXEEXT_28) $(am__EXEEXT_29) $(am__EXEEXT_30)
+	ctie$(EXEEXT) cweave$(EXEEXT) ctwill$(EXEEXT) \
+	ctwill-refsort$(EXEEXT) ctwill-twinx$(EXEEXT) tie$(EXEEXT) \
+	$(am__EXEEXT_6) $(am__EXEEXT_7) $(am__EXEEXT_8) \
+	$(am__EXEEXT_9) $(am__EXEEXT_10) $(am__EXEEXT_11) \
+	$(am__EXEEXT_12) $(am__EXEEXT_13) $(am__EXEEXT_14) \
+	$(am__EXEEXT_15) $(am__EXEEXT_16) $(am__EXEEXT_17) \
+	$(am__EXEEXT_18) $(am__EXEEXT_19) $(am__EXEEXT_20) \
+	$(am__EXEEXT_21) $(am__EXEEXT_22) $(am__EXEEXT_23) \
+	$(am__EXEEXT_24) $(am__EXEEXT_25) $(am__EXEEXT_26) \
+	$(am__EXEEXT_27) $(am__EXEEXT_28) $(am__EXEEXT_29) \
+	$(am__EXEEXT_30)
 noinst_PROGRAMS = tangleboot$(EXEEXT) ctangleboot$(EXEEXT) \
 	$(am__EXEEXT_31) $(am__EXEEXT_32) $(am__EXEEXT_33) \
 	$(am__EXEEXT_34) $(am__EXEEXT_35) $(am__EXEEXT_36) \
@@ -1149,6 +1151,18 @@ nodist_ctie_OBJECTS = ctie.$(OBJEXT)
 ctie_OBJECTS = $(nodist_ctie_OBJECTS)
 ctie_LDADD = $(LDADD)
 ctie_DEPENDENCIES = $(proglib) $(am__DEPENDENCIES_1)
+nodist_ctwill_OBJECTS = ctwill.$(OBJEXT) cweb.$(OBJEXT)
+ctwill_OBJECTS = $(nodist_ctwill_OBJECTS)
+ctwill_LDADD = $(LDADD)
+ctwill_DEPENDENCIES = $(proglib) $(am__DEPENDENCIES_1)
+nodist_ctwill_refsort_OBJECTS = ctwill-refsort.$(OBJEXT)
+ctwill_refsort_OBJECTS = $(nodist_ctwill_refsort_OBJECTS)
+ctwill_refsort_LDADD = $(LDADD)
+ctwill_refsort_DEPENDENCIES = $(proglib) $(am__DEPENDENCIES_1)
+nodist_ctwill_twinx_OBJECTS = ctwill-twinx.$(OBJEXT)
+ctwill_twinx_OBJECTS = $(nodist_ctwill_twinx_OBJECTS)
+ctwill_twinx_LDADD = $(LDADD)
+ctwill_twinx_DEPENDENCIES = $(proglib) $(am__DEPENDENCIES_1)
 nodist_cweave_OBJECTS = cweave.$(OBJEXT) cweb.$(OBJEXT)
 cweave_OBJECTS = $(nodist_cweave_OBJECTS)
 cweave_LDADD = $(LDADD)
@@ -1546,12 +1560,14 @@ am__depfiles_remade = ./$(DEPDIR)/aleph-aleph-pool.Po \
 	./$(DEPDIR)/call_pmpost-callexe.Po \
 	./$(DEPDIR)/call_upmpost-callexe.Po ./$(DEPDIR)/ctangle.Po \
 	./$(DEPDIR)/ctangleboot.Po ./$(DEPDIR)/ctie.Po \
-	./$(DEPDIR)/cweave.Po ./$(DEPDIR)/cweb.Po \
-	./$(DEPDIR)/cwebboot.Po ./$(DEPDIR)/dvicopy.Po \
-	./$(DEPDIR)/dvitype.Po ./$(DEPDIR)/eptex-eptex-pool.Po \
-	./$(DEPDIR)/eptex-eptex0.Po ./$(DEPDIR)/eptex-eptexini.Po \
-	./$(DEPDIR)/etex-etex-pool.Po ./$(DEPDIR)/etex-etex0.Po \
-	./$(DEPDIR)/etex-etexini.Po ./$(DEPDIR)/euptex-euptex-pool.Po \
+	./$(DEPDIR)/ctwill-refsort.Po ./$(DEPDIR)/ctwill-twinx.Po \
+	./$(DEPDIR)/ctwill.Po ./$(DEPDIR)/cweave.Po \
+	./$(DEPDIR)/cweb.Po ./$(DEPDIR)/cwebboot.Po \
+	./$(DEPDIR)/dvicopy.Po ./$(DEPDIR)/dvitype.Po \
+	./$(DEPDIR)/eptex-eptex-pool.Po ./$(DEPDIR)/eptex-eptex0.Po \
+	./$(DEPDIR)/eptex-eptexini.Po ./$(DEPDIR)/etex-etex-pool.Po \
+	./$(DEPDIR)/etex-etex0.Po ./$(DEPDIR)/etex-etexini.Po \
+	./$(DEPDIR)/euptex-euptex-pool.Po \
 	./$(DEPDIR)/euptex-euptex0.Po ./$(DEPDIR)/euptex-euptexini.Po \
 	./$(DEPDIR)/gftodvi.Po ./$(DEPDIR)/gftopk.Po \
 	./$(DEPDIR)/gftype.Po ./$(DEPDIR)/initex-callexe.Po \
@@ -2166,7 +2182,9 @@ SOURCES = $(libff_a_SOURCES) $(libkanji_a_SOURCES) \
 	$(nodist_call_mfluajit_SOURCES) $(nodist_call_mpost_SOURCES) \
 	$(nodist_call_pmpost_SOURCES) $(nodist_call_upmpost_SOURCES) \
 	$(nodist_ctangle_SOURCES) $(nodist_ctangleboot_SOURCES) \
-	$(nodist_ctie_SOURCES) $(nodist_cweave_SOURCES) \
+	$(nodist_ctie_SOURCES) $(nodist_ctwill_SOURCES) \
+	$(nodist_ctwill_refsort_SOURCES) \
+	$(nodist_ctwill_twinx_SOURCES) $(nodist_cweave_SOURCES) \
 	$(nodist_dvicopy_SOURCES) $(nodist_dvitype_SOURCES) \
 	$(dist_eptex_SOURCES) $(nodist_eptex_SOURCES) \
 	$(dist_etex_SOURCES) $(nodist_etex_SOURCES) \
@@ -2812,19 +2830,18 @@ TEST_EXTENSIONS = .pl .test
 #dist_liblua53tex_sources = $(dist_libluatex_sources)
 EXTRA_DIST = PROJECTS cftests cpascal.h help.h w2c/config.h \
 	triptrap-sh tangle.web tangle.ch tangleboot.pin cwebdir \
-	ctangleboot.cin cwebboot.cin cwebboot.hin tangle.test \
-	$(web_programs:=.web) $(web_programs:=.ch) $(web_tests) \
-	tests/memdata1.bst tests/memdata2.bst tests/memdata3.bst \
-	tests/auxinclude.aux tests/auxinclude.bbl tests/auxinclude.bib \
-	tests/auxinclude.tex tests/auxinclude2.aux \
-	tests/auxinclude2.tex tests/allbib.aux tests/allbib.tex \
-	tests/apalike.bst tests/badpl.pl tests/badtfm.tfm \
-	tests/badvf.tfm tests/badvf.vf tests/badvpl.vpl \
-	tests/batch.tex tests/check.log tests/cmr10.600gf \
-	tests/cmr10.pk tests/cmr10.pl tests/cmr10.tfm tests/cmr7.tfm \
-	tests/cmr8.tfm tests/cmti10.tfm tests/cmtt10.tfm \
-	tests/cmtt8.tfm tests/dict tests/eight.tex tests/end.tex \
-	tests/exampl.aux tests/exampl.tex tests/gray.tfm \
+	ctangleboot.cin cwebboot.cin tangle.test $(web_programs:=.web) \
+	$(web_programs:=.ch) $(web_tests) tests/memdata1.bst \
+	tests/memdata2.bst tests/memdata3.bst tests/auxinclude.aux \
+	tests/auxinclude.bbl tests/auxinclude.bib tests/auxinclude.tex \
+	tests/auxinclude2.aux tests/auxinclude2.tex tests/allbib.aux \
+	tests/allbib.tex tests/apalike.bst tests/badpl.pl \
+	tests/badtfm.tfm tests/badvf.tfm tests/badvf.vf \
+	tests/badvpl.vpl tests/batch.tex tests/check.log \
+	tests/cmr10.600gf tests/cmr10.pk tests/cmr10.pl \
+	tests/cmr10.tfm tests/cmr7.tfm tests/cmr8.tfm tests/cmti10.tfm \
+	tests/cmtt10.tfm tests/cmtt8.tfm tests/dict tests/eight.tex \
+	tests/end.tex tests/exampl.aux tests/exampl.tex tests/gray.tfm \
 	tests/hello.tex tests/io.mf tests/just.texi tests/label.mp \
 	tests/label.mpx tests/logo8.tfm tests/longline.aux \
 	tests/longline.bib tests/longline.tex tests/longtfm.tex \
@@ -3153,12 +3170,11 @@ EXTRA_DIST = PROJECTS cftests cpascal.h help.h w2c/config.h \
 	synctexdir/synctex-xe-rec.ch3 $(synctex_tests) libmd5/md5.test
 DISTCLEANFILES = CXXLD.sh tangle.c tangle.h tangle.p tangle-web2c \
 	tangleboot.c tangleboot.h tangleboot.p tangleboot-web2c \
-	ctangle.c cweb.c cweb.h common-ctangle ctangleboot.c \
-	cwebboot.c cwebboot.h cftest.p $(web_programs:=.c) \
-	$(web_programs:=.h) $(web_programs:=.p) \
-	$(web_programs:=-web2c) tests/xexampl.aux tests/xexampl.bbl \
-	tests/xexampl.blg longline.aux longline.bbl longline.bib \
-	longline.blg tests/memtest.bib tests/memtest?.* \
+	ctangle.c cweb.c common-ctangle ctangleboot.c cwebboot.c \
+	cftest.p $(web_programs:=.c) $(web_programs:=.h) \
+	$(web_programs:=.p) $(web_programs:=-web2c) tests/xexampl.aux \
+	tests/xexampl.bbl tests/xexampl.blg longline.aux longline.bbl \
+	longline.bib longline.blg tests/memtest.bib tests/memtest?.* \
 	tests/xstory.dvi tests/xpplr.dvi tests/xstory.dvityp \
 	tests/xpagenum.typ cmr10.dvi tests/xcmr10.dvi cmr10.pk \
 	tests/xcmr10.pk tests/xcmr10.gft1 tests/xcmr10.gft2 io.tex \
@@ -3166,21 +3182,22 @@ DISTCLEANFILES = CXXLD.sh tangle.c tangle.h tangle.p tangle-web2c \
 	tests/xcmr10.600gf tests/xcmr10.pktyp badpl.* tests/xcmr10.tfm \
 	tests/xtexpool.typ badtfm.* tests/xcmr10*.pl badvf.* \
 	tests/xptmr*.vpl badvpl.* tests/yptmr*.* pooltype.tex ctie.c \
-	cweave.c tie.c ctie.outc ctie.outm common.tex common.scn \
-	common.idx tie.outc tie.outm $(nodist_tex_SOURCES) \
-	tex-final.ch tex-web2c tex.p tex.pool tex-tangle trip.diffs \
-	write18-quote.log mftrap.diffs $(nodist_libmf_a_SOURCES) \
-	mf-final.ch mf-web2c mf.p mf.pool mf-tangle mfluatrap.diffs \
-	$(nodist_libmflua_a_SOURCES) mflua.web mflua.ch mflua-web2c \
-	mflua.p mflua.pool mflua-tangle mfluatrap.diffs \
-	mfluajittrap.diffs $(nodist_libmfluajit_a_SOURCES) \
-	mfluajit.web mfluajit.ch mfluajit-web2c mfluajit.p \
-	mfluajit.pool mfluajit-tangle mfluajittrap.diffs \
-	$(nodist_mpost_SOURCES) mpxout-tangle mptrap.diffs ptmr.mpx \
-	tests/xptmr.mpx tests/xstory.mpx $(nodist_pmpost_SOURCES) \
-	pmp.w pmpost.w pmpxout.w ppsout.w psvgout.w ptfmin.w \
-	pmp-tangle pmpxout-tangle ppsout-tangle psvgout-tangle \
-	pmpsamp.* upmpsamp.* $(nodist_libmplibcore_a_SOURCES) \
+	cweave.c ctwill.c ctwill-refsort.c ctwill-twinx.c tie.c \
+	ctie.outc ctie.outm common.tex common.scn common.idx tie.outc \
+	tie.outm $(nodist_tex_SOURCES) tex-final.ch tex-web2c tex.p \
+	tex.pool tex-tangle trip.diffs write18-quote.log mftrap.diffs \
+	$(nodist_libmf_a_SOURCES) mf-final.ch mf-web2c mf.p mf.pool \
+	mf-tangle mfluatrap.diffs $(nodist_libmflua_a_SOURCES) \
+	mflua.web mflua.ch mflua-web2c mflua.p mflua.pool mflua-tangle \
+	mfluatrap.diffs mfluajittrap.diffs \
+	$(nodist_libmfluajit_a_SOURCES) mfluajit.web mfluajit.ch \
+	mfluajit-web2c mfluajit.p mfluajit.pool mfluajit-tangle \
+	mfluajittrap.diffs $(nodist_mpost_SOURCES) mpxout-tangle \
+	mptrap.diffs ptmr.mpx tests/xptmr.mpx tests/xstory.mpx \
+	$(nodist_pmpost_SOURCES) pmp.w pmpost.w pmpxout.w ppsout.w \
+	psvgout.w ptfmin.w pmp-tangle pmpxout-tangle ppsout-tangle \
+	psvgout-tangle pmpsamp.* upmpsamp.* \
+	$(nodist_libmplibcore_a_SOURCES) \
 	$(nodist_libmplibextramath_a_SOURCES) \
 	$(nodist_libmplibbackends_a_SOURCES) mp-tangle mpmath-tangle \
 	mpmathdecimal-tangle mpmathdouble-tangle mpstrings-tangle \
@@ -3255,7 +3272,9 @@ uninstall_exe_links = $(am__append_13) $(am__append_23) \
 	$(am__append_32) $(am__append_40) $(am__append_48) \
 	$(am__append_53) $(am__append_87) $(am__append_92)
 NEVER_DIST = `find . $(NEVER_NAMES)` cwebdir/cweave.log \
-	cwebdir/cweave.trs ctiedir/ctie.log ctiedir/ctie.trs \
+	cwebdir/cweave.trs cwebdir/ctwill.log cwebdir/ctwill.trs \
+	cwebdir/refsort.log cwebdir/refsort.trs cwebdir/twinx.log \
+	cwebdir/twinx.trs ctiedir/ctie.log ctiedir/ctie.trs \
 	tiedir/tie.log tiedir/tie.trs
 NEVER_NAMES = -name .svn
 NEVER_NAMES_SUB = -o -name .deps -o -name .dirstamp -o -name '*.$(OBJEXT)'
@@ -3332,7 +3351,7 @@ nodist_tangle_SOURCES = tangle.c tangle.h
 nodist_tangleboot_SOURCES = tangleboot.c tangleboot.h
 tangleboot_DEPENDENCIES = $(default_dependencies)
 nodist_ctangle_SOURCES = ctangle.c cweb.c
-# ctangle.c and cweb.[ch] are special cases, since they are needed to compile
+# ctangle.c and cweb.c are special cases, since they are needed to compile
 # themselves.  We depend on ctangleboot, even though we might not use it.
 ctangleboot = AM_V_P=$(AM_V_P) $(SHELL) ./ctangleboot-sh $@
 nodist_ctangleboot_SOURCES = ctangleboot.c cwebboot.c
@@ -3362,6 +3381,9 @@ nodist_vptovf_SOURCES = vptovf.c vptovf.h
 nodist_weave_SOURCES = weave.c weave.h
 nodist_ctie_SOURCES = ctie.c
 nodist_cweave_SOURCES = cweave.c cweb.c
+nodist_ctwill_SOURCES = ctwill.c cweb.c
+nodist_ctwill_refsort_SOURCES = ctwill-refsort.c
+nodist_ctwill_twinx_SOURCES = ctwill-twinx.c
 nodist_tie_SOURCES = tie.c
 tie_CPPFLAGS = $(AM_CPPFLAGS) -DNOT_WEB2C
 initex_CPPFLAGS = -DEXEPROG=\"tex.exe\"
@@ -6788,6 +6810,18 @@ ctie$(EXEEXT): $(ctie_OBJECTS) $(ctie_DEPENDENCIES) $(EXTRA_ctie_DEPENDENCIES)
 	@rm -f ctie$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(ctie_OBJECTS) $(ctie_LDADD) $(LIBS)
 
+ctwill$(EXEEXT): $(ctwill_OBJECTS) $(ctwill_DEPENDENCIES) $(EXTRA_ctwill_DEPENDENCIES) 
+	@rm -f ctwill$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(ctwill_OBJECTS) $(ctwill_LDADD) $(LIBS)
+
+ctwill-refsort$(EXEEXT): $(ctwill_refsort_OBJECTS) $(ctwill_refsort_DEPENDENCIES) $(EXTRA_ctwill_refsort_DEPENDENCIES) 
+	@rm -f ctwill-refsort$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(ctwill_refsort_OBJECTS) $(ctwill_refsort_LDADD) $(LIBS)
+
+ctwill-twinx$(EXEEXT): $(ctwill_twinx_OBJECTS) $(ctwill_twinx_DEPENDENCIES) $(EXTRA_ctwill_twinx_DEPENDENCIES) 
+	@rm -f ctwill-twinx$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(ctwill_twinx_OBJECTS) $(ctwill_twinx_LDADD) $(LIBS)
+
 cweave$(EXEEXT): $(cweave_OBJECTS) $(cweave_DEPENDENCIES) $(EXTRA_cweave_DEPENDENCIES) 
 	@rm -f cweave$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(cweave_OBJECTS) $(cweave_LDADD) $(LIBS)
@@ -7168,6 +7202,9 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctangle.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctangleboot.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctie.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctwill-refsort.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctwill-twinx.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctwill.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cweave.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cweb.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cwebboot.Po@am__quote@ # am--include-marker
@@ -16514,6 +16551,9 @@ distclean: distclean-recursive
 	-rm -f ./$(DEPDIR)/ctangle.Po
 	-rm -f ./$(DEPDIR)/ctangleboot.Po
 	-rm -f ./$(DEPDIR)/ctie.Po
+	-rm -f ./$(DEPDIR)/ctwill-refsort.Po
+	-rm -f ./$(DEPDIR)/ctwill-twinx.Po
+	-rm -f ./$(DEPDIR)/ctwill.Po
 	-rm -f ./$(DEPDIR)/cweave.Po
 	-rm -f ./$(DEPDIR)/cweb.Po
 	-rm -f ./$(DEPDIR)/cwebboot.Po
@@ -17162,6 +17202,9 @@ maintainer-clean: maintainer-clean-recursive
 	-rm -f ./$(DEPDIR)/ctangle.Po
 	-rm -f ./$(DEPDIR)/ctangleboot.Po
 	-rm -f ./$(DEPDIR)/ctie.Po
+	-rm -f ./$(DEPDIR)/ctwill-refsort.Po
+	-rm -f ./$(DEPDIR)/ctwill-twinx.Po
+	-rm -f ./$(DEPDIR)/ctwill.Po
 	-rm -f ./$(DEPDIR)/cweave.Po
 	-rm -f ./$(DEPDIR)/cweb.Po
 	-rm -f ./$(DEPDIR)/cwebboot.Po
@@ -17881,15 +17924,14 @@ tangleboot-web2c: tangleboot.p $(web2c_depend)
 .pin.p:
 	$(cp_silent)cp -f $< $@
 $(tangleboot_OBJECTS): $(tangleboot_DEPENDENCIES)
-$(ctangle_OBJECTS): cweb.h
-ctangle.c: ctangleboot$(EXEEXT) cwebdir/common.h cwebdir/ctangle.w cwebdir/ctang-w2c.ch ctangleboot-sh
+ctangle.c: ctangleboot$(EXEEXT) cwebdir/comm-w2c.h cwebdir/ctangle.w cwebdir/ctang-w2c.ch ctangleboot-sh
 	@$(ctangleboot) ctangle ctang-w2c
-cweb.c cweb.h: common-ctangle
+cweb.c: common-ctangle
 	@$(ctangleboot) common comm-w2c cweb.c
 common-ctangle: ctangleboot$(EXEEXT) cwebdir/common.w cwebdir/comm-w2c.ch ctangleboot-sh
 	@$(ctangleboot) common comm-w2c cweb.c
-$(ctangleboot_OBJECTS): cwebboot.h $(ctangleboot_DEPENDENCIES)
-# ctangleboot.cin and cwebboot.[ch]in are in the distribution
+$(ctangleboot_OBJECTS): $(ctangleboot_DEPENDENCIES)
+# ctangleboot.cin and cwebboot.cin are in the distribution
 .cin.c:
 	$(cp_silent)cp -f $< $@
 .hin.h:
@@ -18011,13 +18053,21 @@ weave.p: tangle$(EXEEXT) weave.web weave.ch
 weave.log: weave$(EXEEXT)
 ctie.c: ctangle$(EXEEXT) ctiedir/ctie.w ctiedir/ctie-k.ch
 	$(ctangle_silent)CWEBINPUTS=$(srcdir)/ctiedir $(ctangle) ctie.w ctie-k.ch
-$(cweave_OBJECTS): cweb.h
-cweave.c: ctangle$(EXEEXT) cwebdir/common.h cwebdir/cweave.w cwebdir/prod.w cwebdir/cweav-w2c.ch
+cweave.c: ctangle$(EXEEXT) cwebdir/comm-w2c.h cwebdir/cweave.w cwebdir/prod.w cwebdir/cweav-w2c.ch
 	$(ctangle_silent)CWEBINPUTS=$(srcdir)/cwebdir $(ctangle) cweave cweav-w2c
+ctwill.c: ctangle$(EXEEXT) cwebdir/comm-w2c.h cwebdir/cweave.w cwebdir/prod-twill.w cwebdir/ctwill-w2c.ch
+	$(ctangle_silent)CWEBINPUTS=$(srcdir)/cwebdir $(ctangle) cweave ctwill-w2c ctwill.c
+ctwill-refsort.c: ctangle$(EXEEXT) cwebdir/refsort.w
+	$(ctangle_silent)CWEBINPUTS=$(srcdir)/cwebdir $(ctangle) refsort - ctwill-refsort.c
+ctwill-twinx.c: ctangle$(EXEEXT) cwebdir/twinx.w
+	$(ctangle_silent)CWEBINPUTS=$(srcdir)/cwebdir $(ctangle) twinx - ctwill-twinx.c
 tie.c: ctangle$(EXEEXT) tiedir/tie.w tiedir/tie-w2c.ch
 	$(ctangle_silent)CWEBINPUTS=$(srcdir)/tiedir $(ctangle) tie.w tie-w2c.ch
 ctiedir/ctie.log: ctie$(EXEEXT)
 cwebdir/cweave.log: cweave$(EXEEXT)
+cwebdir/ctwill.log: ctwill$(EXEEXT)
+cwebdir/ctwill-refsort.log: ctwill-refsort$(EXEEXT)
+cwebdir/ctwill-twinx.log: ctwill-twinx$(EXEEXT)
 tiedir/tie.log: tie$(EXEEXT)
 $(tex_OBJECTS): $(tex_prereq)
 
diff --git a/source/texk/web2c/NEWS b/source/texk/web2c/NEWS
index fff0534840620b72bf23f9b438d236946af83efe..673f331bdee68935d9465191b8809f4866cb712d 100644
--- a/source/texk/web2c/NEWS
+++ b/source/texk/web2c/NEWS
@@ -3,10 +3,13 @@ This file records noteworthy changes.  (Public domain.)
 BibTeX: subsidiary .aux files are looked for in the directory of the
 main .aux file, if not found as-is (to work better with -output-directory).
 
+CWEB: now comes from the CWEBbin package
+(https://github.com/ascherer/cwebbin), with translation capabilities,
+more language support, and more.
+
 
 2018 (for TeX Live 2018, 14 April 2018)
 * Directories in the -output-directory do not mask files by the same name.
-
 
 2017 (for TeX Live 2017, 19 May 2017)
 2016 (for TeX Live 2016, 21 May 2016)
diff --git a/source/texk/web2c/am/bootstrap.am b/source/texk/web2c/am/bootstrap.am
index f37c6ddbcd63cbd1d33be5b96a58815b8a7a6c59..5199f430e2645e2ebc82b02a6b80cb47aff98dc0 100644
--- a/source/texk/web2c/am/bootstrap.am
+++ b/source/texk/web2c/am/bootstrap.am
@@ -56,36 +56,38 @@ EXTRA_DIST += tangleboot.pin
 DISTCLEANFILES += tangleboot.c tangleboot.h tangleboot.p tangleboot-web2c
 
 # Bootstrapping ctangle requires making it with itself.  We use the opportunity
-# to create an up-to-date ctangleboot.cin and cwebboot.[ch]in as well.
+# to create an up-to-date ctangleboot.cin and cwebboot.cin as well.
 bin_PROGRAMS += ctangle
 nodist_ctangle_SOURCES = ctangle.c cweb.c
-$(ctangle_OBJECTS): cweb.h
-# ctangle.c and cweb.[ch] are special cases, since they are needed to compile
+# ctangle.c and cweb.c are special cases, since they are needed to compile
 # themselves.  We depend on ctangleboot, even though we might not use it.
 ctangleboot = AM_V_P=$(AM_V_P) $(SHELL) ./ctangleboot-sh $@
-ctangle.c: ctangleboot$(EXEEXT) cwebdir/common.h cwebdir/ctangle.w cwebdir/ctang-w2c.ch ctangleboot-sh
+ctangle.c: ctangleboot$(EXEEXT) cwebdir/comm-w2c.h cwebdir/ctangle.w cwebdir/ctang-w2c.ch ctangleboot-sh
 	@$(ctangleboot) ctangle ctang-w2c
-cweb.c cweb.h: common-ctangle
+cweb.c: common-ctangle
 	@$(ctangleboot) common comm-w2c cweb.c
 common-ctangle: ctangleboot$(EXEEXT) cwebdir/common.w cwebdir/comm-w2c.ch ctangleboot-sh
 	@$(ctangleboot) common comm-w2c cweb.c
 EXTRA_DIST += cwebdir
 NEVER_DIST += cwebdir/cweave.log cwebdir/cweave.trs
+NEVER_DIST += cwebdir/ctwill.log cwebdir/ctwill.trs
+NEVER_DIST += cwebdir/refsort.log cwebdir/refsort.trs
+NEVER_DIST += cwebdir/twinx.log cwebdir/twinx.trs
 ## We install man/cweb.man, not cwebdir/cweb.1
 ## nodist_man_MANS += cwebdir/cweb.1
-DISTCLEANFILES += ctangle.c cweb.c cweb.h common-ctangle
+DISTCLEANFILES += ctangle.c cweb.c common-ctangle
 
 noinst_PROGRAMS += ctangleboot
 nodist_ctangleboot_SOURCES = ctangleboot.c cwebboot.c
-$(ctangleboot_OBJECTS): cwebboot.h $(ctangleboot_DEPENDENCIES)
-# ctangleboot.cin and cwebboot.[ch]in are in the distribution
+$(ctangleboot_OBJECTS): $(ctangleboot_DEPENDENCIES)
+# ctangleboot.cin and cwebboot.cin are in the distribution
 .cin.c:
 	$(cp_silent)cp -f $< $@
 .hin.h:
 	$(cp_silent)cp -f $< $@
 ctangleboot_DEPENDENCIES = $(default_dependencies)
-EXTRA_DIST += ctangleboot.cin cwebboot.cin cwebboot.hin
-DISTCLEANFILES += ctangleboot.c cwebboot.c cwebboot.h
+EXTRA_DIST += ctangleboot.cin cwebboot.cin
+DISTCLEANFILES += ctangleboot.c cwebboot.c
 
 ## Tests
 ##
diff --git a/source/texk/web2c/am/cweb.am b/source/texk/web2c/am/cweb.am
index b55ae163884938373cbbaca652b4edc468b723bb..90c10db2d67d2dcf5523be853de9ac29a4150142 100644
--- a/source/texk/web2c/am/cweb.am
+++ b/source/texk/web2c/am/cweb.am
@@ -3,7 +3,7 @@
 ## Copyright (C) 2009-2015 Peter Breitenlohner <tex-live@tug.org>
 ## You may freely use, modify and/or distribute this file.
 
-bin_PROGRAMS += ctie cweave tie
+bin_PROGRAMS += ctie cweave ctwill ctwill-refsort ctwill-twinx tie
 EXTRA_DIST += ctiedir tiedir
 NEVER_DIST += ctiedir/ctie.log ctiedir/ctie.trs tiedir/tie.log tiedir/tie.trs
 
@@ -15,11 +15,25 @@ ctie.c: ctangle$(EXEEXT) ctiedir/ctie.w ctiedir/ctie-k.ch
 DISTCLEANFILES += ctie.c
 
 nodist_cweave_SOURCES = cweave.c cweb.c
-$(cweave_OBJECTS): cweb.h
-cweave.c: ctangle$(EXEEXT) cwebdir/common.h cwebdir/cweave.w cwebdir/prod.w cwebdir/cweav-w2c.ch
+cweave.c: ctangle$(EXEEXT) cwebdir/comm-w2c.h cwebdir/cweave.w cwebdir/prod.w cwebdir/cweav-w2c.ch
 	$(ctangle_silent)CWEBINPUTS=$(srcdir)/cwebdir $(ctangle) cweave cweav-w2c
 DISTCLEANFILES += cweave.c
 
+nodist_ctwill_SOURCES = ctwill.c cweb.c
+ctwill.c: ctangle$(EXEEXT) cwebdir/comm-w2c.h cwebdir/cweave.w cwebdir/prod-twill.w cwebdir/ctwill-w2c.ch
+	$(ctangle_silent)CWEBINPUTS=$(srcdir)/cwebdir $(ctangle) cweave ctwill-w2c ctwill.c
+DISTCLEANFILES += ctwill.c
+
+nodist_ctwill_refsort_SOURCES = ctwill-refsort.c
+ctwill-refsort.c: ctangle$(EXEEXT) cwebdir/refsort.w
+	$(ctangle_silent)CWEBINPUTS=$(srcdir)/cwebdir $(ctangle) refsort - ctwill-refsort.c
+DISTCLEANFILES += ctwill-refsort.c
+
+nodist_ctwill_twinx_SOURCES = ctwill-twinx.c
+ctwill-twinx.c: ctangle$(EXEEXT) cwebdir/twinx.w
+	$(ctangle_silent)CWEBINPUTS=$(srcdir)/cwebdir $(ctangle) twinx - ctwill-twinx.c
+DISTCLEANFILES += ctwill-twinx.c
+
 nodist_tie_SOURCES = tie.c
 tie_CPPFLAGS = $(AM_CPPFLAGS) -DNOT_WEB2C
 ## We install man/tie.man, not tiedir/tie.1
@@ -33,6 +47,9 @@ DISTCLEANFILES += tie.c
 TESTS += ctiedir/ctie.test cwebdir/cweave.test tiedir/tie.test
 ctiedir/ctie.log: ctie$(EXEEXT)
 cwebdir/cweave.log: cweave$(EXEEXT)
+cwebdir/ctwill.log: ctwill$(EXEEXT)
+cwebdir/ctwill-refsort.log: ctwill-refsort$(EXEEXT)
+cwebdir/ctwill-twinx.log: ctwill-twinx$(EXEEXT)
 tiedir/tie.log: tie$(EXEEXT)
 
 ## ctiedir/ctie.test
diff --git a/source/texk/web2c/configure b/source/texk/web2c/configure
index a8308b3a4003bc120bd077321213e99ae2338217..aa495fa4d8b728e3a92ee00fadba0012e0f8d72d 100755
--- a/source/texk/web2c/configure
+++ b/source/texk/web2c/configure
@@ -25007,6 +25007,7 @@ $(LUA52_DEPEND): ${top_builddir}/../../libs/lua52/include/lua.h
 ${top_builddir}/../../libs/lua52/include/lua.h:
 	cd ${top_builddir}/../../libs/lua52 && $(MAKE) $(AM_MAKEFLAGS) rebuild'
 
+echo 'tldbg:KPSE_LUAJIT_FLAGS called.' >&5
 ##tldbg _KPSE_LIB_FLAGS: Setup luajit (-ltexluajit) flags.
 echo 'tldbg:_KPSE_LIB_FLAGS called: libdir=luajit, libname=texluajit, options=lt tree, tlincl=-IBLD/libs/luajit/include, tllib=BLD/libs/luajit/libtexluajit.la, tlextra=, rebuildsrcdeps=, rebuildblddeps=${top_builddir}/../../libs/luajit/include/luajit.h.' >&5
 ##tldbg _KPSE_LIB_FLAGS_TL: luajit (texluajit) lt tree.
@@ -25018,6 +25019,76 @@ $(LUAJIT_DEPEND): ${top_builddir}/../../libs/luajit/include/luajit.h
 	cd ${top_builddir}/../../libs/luajit && $(MAKE) $(AM_MAKEFLAGS) rebuild
 ${top_builddir}/../../libs/luajit/include/luajit.h:
 	cd ${top_builddir}/../../libs/luajit && $(MAKE) $(AM_MAKEFLAGS) rebuild'
+#
+# checking for openbsd for additional jit libraries needed, which is the
+# case for clang; no point in going to the trouble elsewhere since no
+# other system needs it.
+case $build_os in
+openbsd*)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking on openbsd if additional jit libraries are needed" >&5
+$as_echo_n "checking on openbsd if additional jit libraries are needed... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include "stdint.h"
+      typedef struct _Unwind_Context _Unwind_Context;
+      extern uintptr_t _Unwind_GetCFA(_Unwind_Context *);
+int
+main ()
+{
+_Unwind_Context *ctx;
+      _Unwind_GetCFA(ctx);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+else
+
+    jitlibs="-lc++abi -lpthread"
+    save_LIBS=$LIBS
+    LIBS="$LIBS $jitlibs"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include "stdint.h"
+          typedef struct _Unwind_Context _Unwind_Context;
+          extern uintptr_t _Unwind_GetCFA(_Unwind_Context *);
+int
+main ()
+{
+_Unwind_Context *ctx;
+          _Unwind_GetCFA(ctx);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$jitlibs\"" >&5
+$as_echo "\"$jitlibs\"" >&6; }
+        LIBLUAJIT_LDEXTRA="$LIBLUAJIT_LDEXTRA $jitlibs"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "luajit could not be linked
+See \`config.log' for more details" "$LINENO" 5; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LIBS=$save_LIBS
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  ;;
+esac
+echo 'tldbg:KPSE_LUAJIT_FLAGS done.' >&5
 
 ##tldbg _KPSE_LIB_FLAGS: Setup libpng (-lpng) flags.
 echo 'tldbg:_KPSE_LIB_FLAGS called: libdir=libpng, libname=png, options=, tlincl=-IBLD/libs/libpng/include, tllib=BLD/libs/libpng/libpng.a, tlextra=, rebuildsrcdeps=, rebuildblddeps=${top_builddir}/../../libs/libpng/include/png.h.' >&5
diff --git a/source/texk/web2c/ctangleboot-sh.in b/source/texk/web2c/ctangleboot-sh.in
index db5da006b6cdb544aac478907c04b1ac3e5ead81..1cc839f058c8054d39d19f0d267a19f22e78ad98 100644
--- a/source/texk/web2c/ctangleboot-sh.in
+++ b/source/texk/web2c/ctangleboot-sh.in
@@ -12,7 +12,7 @@
 target=$1; shift
 base=$1
 case $base in
-  common) file=cweb; exts='c h';;
+  common) file=cweb; exts=c;;
   ctangle) file=ctangle; exts=c;;
   *) echo "Usage: $0 TARGET {common|ctangle} [CHANGEFILE]" >&2; exit 1;;
 esac
@@ -64,7 +64,6 @@ for ext in $exts; do
   src=$file.$ext
   dst=@srcdir@/${file}boot.${ext}in
   sed -e 's,@srcdir@/cwebdir,cwebdir,' \
-      -e 's,^#include "cweb.h",#include "cwebboot.h",' \
       $src >$stamp.tmp
   if cmp -s $stamp.tmp $dst; then
     rm -f $stamp.tmp
diff --git a/source/texk/web2c/ctangleboot.cin b/source/texk/web2c/ctangleboot.cin
index 0a4e286176ad4b148335040a1eaa8ae44156ad60..21b3cf5c6cb83a425f37e904691e6e175a2d1f0a 100644
--- a/source/texk/web2c/ctangleboot.cin
+++ b/source/texk/web2c/ctangleboot.cin
@@ -1,24 +1,40 @@
 /*1:*/
 #line 64 "cwebdir/ctangle.w"
 
-/*5:*/
-#line 35 "cwebdir/common.h"
+/*2:*/
+#line 60 "cwebdir/ctang-w2c.ch"
+
+#include <string.h> 
+#line 83 "cwebdir/ctangle.w"
+
+/*:2*//*6:*/
+#line 45 "cwebdir/comm-w2c.h"
+
+#ifndef HAVE_GETTEXT
+#define HAVE_GETTEXT 0
+#endif
+
+#if HAVE_GETTEXT
+#include <libintl.h> 
+#else
+#define gettext(A) A
+#endif
 
-#line 120 "cwebdir/ctang-w2c.ch"
-#include <kpathsea/kpathsea.h> 
+#include <stdbool.h> 
+#include <stdint.h> 
 #include <stdio.h> 
-#line 37 "cwebdir/common.h"
 
-/*:5*//*61:*/
+/*:6*//*62:*/
 #line 888 "cwebdir/ctangle.w"
 
-#line 890 "cwebdir/ctangle.w"
+#include <ctype.h>  
 #include <stdlib.h>  
 
-/*:61*/
+/*:62*/
 #line 65 "cwebdir/ctangle.w"
 
 #define banner "This is CTANGLE, Version 3.64" \
+ \
 
 #define max_bytes 1000000 \
 
@@ -32,15 +48,17 @@
 #define buf_size 1000 \
 
 #define ctangle 0
-#define cweave 1 \
+#define cweave 1
+#define ctwill 2 \
 
+#define _(STRING) gettext(STRING) 
 #define and_and 04
 #define lt_lt 020
 #define gt_gt 021
 #define plus_plus 013
 #define minus_minus 01
 #define minus_gt 031
-#define not_eq 032
+#define non_eq 032
 #define lt_eq 034
 #define gt_eq 035
 #define eq_eq 036
@@ -57,7 +75,7 @@
 #define xisupper(c) (isupper((eight_bits) c) &&((eight_bits) c<0200) ) 
 #define xisxdigit(c) (isxdigit((eight_bits) c) &&((eight_bits) c<0200) )  \
 
-#define length(c) (c+1) ->byte_start-(c) ->byte_start
+#define length(c) (size_t) ((c+1) ->byte_start-(c) ->byte_start) 
 #define print_id(c) term_write((c) ->byte_start,length((c) ) ) 
 #define llink link
 #define rlink dummy.Rlink
@@ -71,7 +89,7 @@
 #define fatal_message 3
 #define mark_harmless {if(history==spotless) history= harmless_message;}
 #define mark_error history= error_message
-#define confusion(s) fatal("! This can't happen: ",s)  \
+#define confusion(s) fatal(_("! This can't happen: ") ,s)  \
 
 #define max_file_name_length 1024
 #define cur_file file[include_depth]
@@ -81,7 +99,8 @@
 
 #define show_banner flags['b']
 #define show_progress flags['p']
-#define show_happiness flags['h'] \
+#define show_happiness flags['h']
+#define make_xrefs flags['x'] \
 
 #define update_terminal fflush(stdout) 
 #define new_line putchar('\n') 
@@ -137,37 +156,40 @@
 #define compress(c) if(loc++<=limit) return(c)  \
 
 #define macro 0
-#define app_repl(c) {if(tok_ptr==tok_mem_end) overflow("token") ;*tok_ptr++= c;} \
+#define app_repl(c) {if(tok_ptr==tok_mem_end) overflow(_("token") ) ;*tok_ptr++= c;} \
+
+#define max_banner 50 \
 
 
 #line 66 "cwebdir/ctangle.w"
 
-/*4:*/
-#line 29 "cwebdir/common.h"
+/*5:*/
+#line 37 "cwebdir/comm-w2c.h"
 
-#line 31 "cwebdir/common.h"
-typedef char unsigned eight_bits;
-extern boolean program;
+typedef bool boolean;
+typedef uint8_t eight_bits;
+typedef uint16_t sixteen_bits;
+extern int program;
 extern int phase;
 
-/*:4*//*6:*/
-#line 57 "cwebdir/common.h"
+/*:5*//*7:*/
+#line 79 "cwebdir/comm-w2c.h"
 
 char section_text[longest_name+1];
 char*section_text_end= section_text+longest_name;
 char*id_first;
 char*id_loc;
 
-/*:6*//*7:*/
-#line 72 "cwebdir/common.h"
+/*:7*//*8:*/
+#line 94 "cwebdir/comm-w2c.h"
 
 extern char buffer[];
 extern char*buffer_end;
 extern char*loc;
 extern char*limit;
 
-/*:7*//*8:*/
-#line 87 "cwebdir/common.h"
+/*:8*//*9:*/
+#line 109 "cwebdir/comm-w2c.h"
 
 typedef struct name_info{
 char*byte_start;
@@ -177,7 +199,7 @@ struct name_info*Rlink;
 
 char Ilk;
 }dummy;
-char*equiv_or_xref;
+void*equiv_or_xref;
 }name_info;
 typedef name_info*name_pointer;
 typedef name_pointer*hash_pointer;
@@ -190,76 +212,91 @@ extern char*byte_ptr;
 extern name_pointer hash[];
 extern hash_pointer hash_end;
 extern hash_pointer h;
-#line 147 "cwebdir/ctang-w2c.ch"
-#include "cwebboot.h"
-#line 112 "cwebdir/common.h"
+extern boolean names_match(name_pointer,const char*,size_t,eight_bits);
+extern name_pointer id_lookup(const char*,const char*,char);
 
-/*:8*//*9:*/
-#line 122 "cwebdir/common.h"
+extern name_pointer section_lookup(char*,char*,int);
+extern void init_node(name_pointer);
+extern void init_p(name_pointer,eight_bits);
+extern void print_prefix_name(name_pointer);
+extern void print_section_name(name_pointer);
+extern void sprint_section_name(char*,name_pointer);
+
+/*:9*//*10:*/
+#line 150 "cwebdir/comm-w2c.h"
 
-#line 159 "cwebdir/ctang-w2c.ch"
 extern int history;
-#line 128 "cwebdir/common.h"
+extern int wrap_up(void);
+extern void err_print(const char*);
+extern void fatal(const char*,const char*);
+extern void overflow(const char*);
 
-/*:9*//*10:*/
-#line 137 "cwebdir/common.h"
+/*:10*//*11:*/
+#line 165 "cwebdir/comm-w2c.h"
 
-#line 173 "cwebdir/ctang-w2c.ch"
 extern int include_depth;
-#line 139 "cwebdir/common.h"
 extern FILE*file[];
 extern FILE*change_file;
 extern char C_file_name[];
 extern char tex_file_name[];
 extern char idx_file_name[];
 extern char scn_file_name[];
+extern char check_file_name[];
 extern char file_name[][max_file_name_length];
 
 extern char change_file_name[];
-#line 181 "cwebdir/ctang-w2c.ch"
 extern int line[];
 extern int change_line;
 extern int change_depth;
-#line 151 "cwebdir/common.h"
 extern boolean input_has_ended;
 extern boolean changing;
 extern boolean web_file_open;
-#line 157 "cwebdir/common.h"
+extern boolean get_line(void);
+extern void check_complete(void);
+extern void reset_input(void);
 
-/*:10*//*11:*/
-#line 159 "cwebdir/common.h"
+/*:11*//*12:*/
+#line 188 "cwebdir/comm-w2c.h"
 
-typedef unsigned short sixteen_bits;
 extern sixteen_bits section_count;
 extern boolean changed_section[];
 extern boolean change_pending;
 extern boolean print_where;
 
-/*:11*//*12:*/
-#line 171 "cwebdir/common.h"
+/*:12*//*13:*/
+#line 200 "cwebdir/comm-w2c.h"
 
 extern int argc;
 extern char**argv;
 extern boolean flags[];
 
-/*:12*//*13:*/
-#line 183 "cwebdir/common.h"
+/*:13*//*14:*/
+#line 212 "cwebdir/comm-w2c.h"
 
 extern FILE*C_file;
 extern FILE*tex_file;
 extern FILE*idx_file;
 extern FILE*scn_file;
+extern FILE*check_file;
 extern FILE*active_file;
 
-/*:13*//*14:*/
-#line 192 "cwebdir/common.h"
+/*:14*//*15:*/
+#line 222 "cwebdir/comm-w2c.h"
 
+extern void common_init(void);
+extern void print_stats(void);
+extern void cb_show_banner(void);
 #line 128 "cwebdir/ctangle.w"
 
-/*:14*/
+/*:15*//*104:*/
+#line 836 "cwebdir/ctang-w2c.ch"
+
+extern char cb_banner[];
+
+/*:104*/
 #line 67 "cwebdir/ctangle.w"
 
-/*15:*/
+/*16:*/
 #line 152 "cwebdir/ctangle.w"
 
 typedef struct{
@@ -268,7 +305,7 @@ sixteen_bits text_link;
 }text;
 typedef text*text_pointer;
 
-/*:15*//*26:*/
+/*:16*//*27:*/
 #line 296 "cwebdir/ctangle.w"
 
 typedef struct{
@@ -280,10 +317,10 @@ sixteen_bits section_field;
 }output_state;
 typedef output_state*stack_pointer;
 
-/*:26*/
+/*:27*/
 #line 68 "cwebdir/ctangle.w"
 
-/*16:*/
+/*17:*/
 #line 159 "cwebdir/ctangle.w"
 
 text text_info[max_texts];
@@ -293,12 +330,12 @@ eight_bits tok_mem[max_toks];
 eight_bits*tok_mem_end= tok_mem+max_toks-1;
 eight_bits*tok_ptr;
 
-/*:16*//*22:*/
+/*:17*//*23:*/
 #line 227 "cwebdir/ctangle.w"
 
 text_pointer last_unnamed;
 
-/*:22*//*27:*/
+/*:23*//*28:*/
 #line 312 "cwebdir/ctangle.w"
 
 output_state cur_state;
@@ -307,18 +344,18 @@ output_state stack[stack_size+1];
 stack_pointer stack_ptr;
 stack_pointer stack_end= stack+stack_size;
 
-/*:27*//*31:*/
+/*:28*//*32:*/
 #line 384 "cwebdir/ctangle.w"
 
 int cur_val;
 
-/*:31*//*35:*/
+/*:32*//*36:*/
 #line 473 "cwebdir/ctangle.w"
 
 eight_bits out_state;
 boolean protect;
 
-/*:35*//*37:*/
+/*:36*//*38:*/
 #line 502 "cwebdir/ctangle.w"
 
 name_pointer output_files[max_files];
@@ -326,118 +363,135 @@ name_pointer*cur_out_file,*end_output_files,*an_output_file;
 char cur_section_name_char;
 char output_file_name[longest_name];
 
-/*:37*//*44:*/
+/*:38*//*45:*/
 #line 599 "cwebdir/ctangle.w"
 
 boolean output_defs_seen= 0;
 
-/*:44*//*50:*/
+/*:45*//*51:*/
 #line 710 "cwebdir/ctangle.w"
 
 char translit[128][translit_length];
 
-/*:50*//*55:*/
+/*:51*//*56:*/
 #line 789 "cwebdir/ctangle.w"
 
 eight_bits ccode[256];
 
-/*:55*//*58:*/
+/*:56*//*59:*/
 #line 845 "cwebdir/ctangle.w"
 
 boolean comment_continues= 0;
 
-/*:58*//*60:*/
+/*:59*//*61:*/
 #line 884 "cwebdir/ctangle.w"
 
 name_pointer cur_section_name;
 int no_where;
 
-/*:60*//*74:*/
+/*:61*//*75:*/
 #line 1195 "cwebdir/ctangle.w"
 
 text_pointer cur_text;
 eight_bits next_control;
 
-/*:74*//*81:*/
+/*:75*//*82:*/
 #line 1353 "cwebdir/ctangle.w"
 
 extern sixteen_bits section_count;
 
-/*:81*/
+/*:82*/
 #line 69 "cwebdir/ctangle.w"
 
-/*40:*/
+/*41:*/
 #line 533 "cwebdir/ctangle.w"
 
-#line 284 "cwebdir/ctang-w2c.ch"
+#line 251 "cwebdir/ctang-w2c.ch"
 static void phase_two(void);
 #line 535 "cwebdir/ctangle.w"
 
-/*:40*//*45:*/
+/*:41*//*46:*/
 #line 602 "cwebdir/ctangle.w"
 
-#line 310 "cwebdir/ctang-w2c.ch"
+#line 335 "cwebdir/ctang-w2c.ch"
 static void output_defs(void);
 #line 604 "cwebdir/ctangle.w"
 
-/*:45*//*47:*/
+/*:46*//*48:*/
 #line 648 "cwebdir/ctangle.w"
 
-#line 328 "cwebdir/ctang-w2c.ch"
+#line 355 "cwebdir/ctang-w2c.ch"
 static void out_char(eight_bits);
 #line 650 "cwebdir/ctangle.w"
 
-/*:47*//*89:*/
+/*:48*//*90:*/
 #line 1460 "cwebdir/ctangle.w"
 
-#line 442 "cwebdir/ctang-w2c.ch"
+#line 651 "cwebdir/ctang-w2c.ch"
 static void phase_one(void);
 #line 1462 "cwebdir/ctangle.w"
 
-/*:89*//*91:*/
+/*:90*//*92:*/
 #line 1478 "cwebdir/ctangle.w"
 
-#line 460 "cwebdir/ctang-w2c.ch"
+#line 665 "cwebdir/ctang-w2c.ch"
 static void skip_limbo(void);
 #line 1480 "cwebdir/ctangle.w"
 
-/*:91*/
+/*:92*//*97:*/
+#line 752 "cwebdir/ctang-w2c.ch"
+
+static eight_bits get_next(void);
+static eight_bits skip_ahead(void);
+static boolean skip_comment(boolean);
+static void flush_buffer(void);
+static void get_output(void);
+static void pop_level(int);
+static void push_level(name_pointer);
+static void scan_repl(eight_bits);
+static void scan_section(void);
+static void store_two_bytes(sixteen_bits);
+
+/*:97*/
 #line 70 "cwebdir/ctangle.w"
 
 
-#line 83 "cwebdir/ctangle.w"
-
-/*:1*//*2:*/
+#line 55 "cwebdir/ctang-w2c.ch"
+/*:1*//*3:*/
 #line 91 "cwebdir/ctangle.w"
 
 #line 69 "cwebdir/ctang-w2c.ch"
-int main(int ac,char**av)
+int main(
+int ac,
+char**av)
 #line 95 "cwebdir/ctangle.w"
 {
 argc= ac;argv= av;
 program= ctangle;
-/*17:*/
+/*18:*/
 #line 167 "cwebdir/ctangle.w"
 
 text_info->tok_start= tok_ptr= tok_mem;
 text_ptr= text_info+1;text_ptr->tok_start= tok_mem;
 
 
-/*:17*//*19:*/
+/*:18*//*20:*/
 #line 177 "cwebdir/ctangle.w"
 
-name_dir->equiv= (char*)text_info;
+#line 130 "cwebdir/ctang-w2c.ch"
+init_node(name_dir);
+#line 179 "cwebdir/ctangle.w"
 
-/*:19*//*23:*/
+/*:20*//*24:*/
 #line 230 "cwebdir/ctangle.w"
 last_unnamed= text_info;text_info->text_link= 0;
 
-/*:23*//*38:*/
+/*:24*//*39:*/
 #line 512 "cwebdir/ctangle.w"
 
 cur_out_file= end_output_files= output_files+max_files;
 
-/*:38*//*51:*/
+/*:39*//*52:*/
 #line 713 "cwebdir/ctangle.w"
 
 {
@@ -445,7 +499,7 @@ int i;
 for(i= 0;i<128;i++)sprintf(translit[i],"X%02X",(unsigned)(128+i));
 }
 
-/*:51*//*56:*/
+/*:52*//*57:*/
 #line 792 "cwebdir/ctangle.w"
 {
 int c;
@@ -465,72 +519,88 @@ ccode['<']= ccode['(']= section_name;
 ccode['\'']= ord;
 }
 
-/*:56*//*70:*/
+/*:57*//*71:*/
 #line 1116 "cwebdir/ctangle.w"
 section_text[0]= ' ';
 
-/*:70*/
+/*:71*//*105:*/
+#line 839 "cwebdir/ctang-w2c.ch"
+
+strncpy(cb_banner,banner,max_banner-1);
+
+/*:105*/
 #line 98 "cwebdir/ctangle.w"
 ;
 common_init();
-#line 75 "cwebdir/ctang-w2c.ch"
-if(show_banner){
-printf("%s%s\n",banner,versionstring);
-}
+#line 77 "cwebdir/ctang-w2c.ch"
+if(show_banner)cb_show_banner();
 #line 101 "cwebdir/ctangle.w"
 phase_one();
 phase_two();
 return wrap_up();
 }
 
-/*:2*//*20:*/
+/*:3*//*21:*/
 #line 183 "cwebdir/ctangle.w"
 
-#line 208 "cwebdir/ctang-w2c.ch"
-int names_match(name_pointer p,const char*first,int l,char t)
-#line 188 "cwebdir/ctangle.w"
-{
+#line 140 "cwebdir/ctang-w2c.ch"
+boolean names_match(
+name_pointer p,
+const char*first,
+size_t l,
+eight_bits t)
+{(void)t;
+#line 189 "cwebdir/ctangle.w"
 if(length(p)!=l)return 0;
 return!strncmp(first,p->byte_start,l);
 }
 
-/*:20*//*21:*/
+/*:21*//*22:*/
 #line 198 "cwebdir/ctangle.w"
 
+#line 153 "cwebdir/ctang-w2c.ch"
 void
-#line 217 "cwebdir/ctang-w2c.ch"
- init_node(name_pointer node)
+init_node(
+name_pointer node)
 #line 202 "cwebdir/ctangle.w"
 {
-node->equiv= (char*)text_info;
+#line 161 "cwebdir/ctang-w2c.ch"
+node->equiv= (void*)text_info;
+#line 204 "cwebdir/ctangle.w"
 }
+#line 168 "cwebdir/ctang-w2c.ch"
 void
-#line 223 "cwebdir/ctang-w2c.ch"
- init_p(name_pointer p,char t){}
+init_p(name_pointer p,eight_bits t){(void)p;(void)t;}
 #line 207 "cwebdir/ctangle.w"
 
-/*:21*//*25:*/
+/*:22*//*26:*/
 #line 260 "cwebdir/ctangle.w"
 
-#line 233 "cwebdir/ctang-w2c.ch"
+#line 177 "cwebdir/ctang-w2c.ch"
 static void
-store_two_bytes(sixteen_bits x)
+store_two_bytes(
+sixteen_bits x)
 #line 264 "cwebdir/ctangle.w"
 {
-if(tok_ptr+2> tok_mem_end)overflow("token");
+#line 185 "cwebdir/ctang-w2c.ch"
+if(tok_ptr+2> tok_mem_end)overflow(_("token"));
+#line 266 "cwebdir/ctangle.w"
 *tok_ptr++= x>>8;
 *tok_ptr++= x&0377;
 }
 
-/*:25*//*29:*/
+/*:26*//*30:*/
 #line 336 "cwebdir/ctangle.w"
 
-#line 244 "cwebdir/ctang-w2c.ch"
+#line 193 "cwebdir/ctang-w2c.ch"
 static void
-push_level(name_pointer p)
+push_level(
+name_pointer p)
 #line 340 "cwebdir/ctangle.w"
 {
-if(stack_ptr==stack_end)overflow("stack");
+#line 201 "cwebdir/ctang-w2c.ch"
+if(stack_ptr==stack_end)overflow(_("stack"));
+#line 342 "cwebdir/ctangle.w"
 *stack_ptr= cur_state;
 stack_ptr++;
 if(p!=NULL){
@@ -540,12 +610,13 @@ cur_section= 0;
 }
 }
 
-/*:29*//*30:*/
+/*:30*//*31:*/
 #line 355 "cwebdir/ctangle.w"
 
-#line 255 "cwebdir/ctang-w2c.ch"
+#line 209 "cwebdir/ctang-w2c.ch"
 static void
-pop_level(int flag)
+pop_level(
+int flag)
 #line 359 "cwebdir/ctangle.w"
 {
 if(flag&&cur_repl->text_link<section_flag){
@@ -557,10 +628,10 @@ stack_ptr--;
 if(stack_ptr> stack)cur_state= *stack_ptr;
 }
 
-/*:30*//*32:*/
+/*:31*//*33:*/
 #line 391 "cwebdir/ctangle.w"
 
-#line 265 "cwebdir/ctang-w2c.ch"
+#line 218 "cwebdir/ctang-w2c.ch"
 static void
 get_output(void)
 #line 394 "cwebdir/ctangle.w"
@@ -582,21 +653,25 @@ a= (a-0200)*0400+*cur_byte++;
 switch(a/024000){
 case 0:cur_val= a;out_char(identifier);break;
 case 1:if(a==output_defs_flag)output_defs();
-else/*33:*/
+else/*34:*/
 #line 423 "cwebdir/ctangle.w"
 
 {
 a-= 024000;
-if((a+name_dir)->equiv!=(char*)text_info)push_level(a+name_dir);
+#line 225 "cwebdir/ctang-w2c.ch"
+if((a+name_dir)->equiv!=(void*)text_info)push_level(a+name_dir);
+#line 427 "cwebdir/ctangle.w"
 else if(a!=0){
-printf("\n! Not present: <");
+#line 231 "cwebdir/ctang-w2c.ch"
+fputs(_("\n! Not present: <"),stdout);
+#line 429 "cwebdir/ctangle.w"
 print_section_name(a+name_dir);err_print(">");
 
 }
 goto restart;
 }
 
-/*:33*/
+/*:34*/
 #line 412 "cwebdir/ctangle.w"
 ;
 break;
@@ -606,10 +681,10 @@ out_char(section_number);
 }
 }
 
-/*:32*//*36:*/
+/*:33*//*37:*/
 #line 481 "cwebdir/ctangle.w"
 
-#line 275 "cwebdir/ctang-w2c.ch"
+#line 238 "cwebdir/ctang-w2c.ch"
 static void
 flush_buffer(void)
 #line 484 "cwebdir/ctangle.w"
@@ -623,45 +698,51 @@ update_terminal;
 cur_line++;
 }
 
-/*:36*//*41:*/
+/*:37*//*42:*/
 #line 536 "cwebdir/ctangle.w"
 
-#line 293 "cwebdir/ctang-w2c.ch"
+#line 258 "cwebdir/ctang-w2c.ch"
 static void
 phase_two(void){
 #line 539 "cwebdir/ctangle.w"
 web_file_open= 0;
 cur_line= 1;
-/*28:*/
+/*29:*/
 #line 325 "cwebdir/ctangle.w"
 
 stack_ptr= stack+1;cur_name= name_dir;cur_repl= text_info->text_link+text_info;
 cur_byte= cur_repl->tok_start;cur_end= (cur_repl+1)->tok_start;cur_section= 0;
 
-/*:28*/
+/*:29*/
 #line 541 "cwebdir/ctangle.w"
 ;
-/*43:*/
+/*44:*/
 #line 595 "cwebdir/ctangle.w"
 
 if(!output_defs_seen)
 output_defs();
 
-/*:43*/
+/*:44*/
 #line 542 "cwebdir/ctangle.w"
 ;
 if(text_info->text_link==0&&cur_out_file==end_output_files){
-printf("\n! No program text was specified.");mark_harmless;
+#line 265 "cwebdir/ctang-w2c.ch"
+fputs(_("\n! No program text was specified."),stdout);mark_harmless;
+#line 545 "cwebdir/ctangle.w"
 
 }
 else{
 if(cur_out_file==end_output_files){
 if(show_progress)
-printf("\nWriting the output file (%s):",C_file_name);
+#line 271 "cwebdir/ctang-w2c.ch"
+printf(_("\nWriting the output file (%s):"),C_file_name);
+#line 551 "cwebdir/ctangle.w"
 }
 else{
 if(show_progress){
-printf("\nWriting the output files:");
+#line 277 "cwebdir/ctang-w2c.ch"
+fputs(_("\nWriting the output files:"),stdout);
+#line 555 "cwebdir/ctangle.w"
 
 printf(" (%s)",C_file_name);
 update_terminal;
@@ -670,17 +751,68 @@ if(text_info->text_link==0)goto writeloop;
 }
 while(stack_ptr> stack)get_output();
 flush_buffer();
-writeloop:/*42:*/
-#line 572 "cwebdir/ctangle.w"
+writeloop:/*43:*/
+#line 309 "cwebdir/ctang-w2c.ch"
+
+fclose(C_file);C_file= NULL;
+/*98:*/
+#line 772 "cwebdir/ctang-w2c.ch"
+
+if((C_file= fopen(C_file_name,"r"))!=NULL){
+/*99:*/
+#line 779 "cwebdir/ctang-w2c.ch"
+
+char x[BUFSIZ],y[BUFSIZ];
+int x_size,y_size,comparison;
+
+if((check_file= fopen(check_file_name,"r"))==NULL)
+fatal(_("! Cannot open output file "),check_file_name);
+
+
+/*100:*/
+#line 794 "cwebdir/ctang-w2c.ch"
+
+do{
+x_size= fread(x,1,BUFSIZ,C_file);
+y_size= fread(y,1,BUFSIZ,check_file);
+comparison= (x_size==y_size);
+if(comparison)comparison= !memcmp(x,y,x_size);
+}while(comparison&&!feof(C_file)&&!feof(check_file));
+
+/*:100*/
+#line 787 "cwebdir/ctang-w2c.ch"
+
+
+fclose(C_file);C_file= NULL;
+fclose(check_file);check_file= NULL;
+
+/*:99*/
+#line 774 "cwebdir/ctang-w2c.ch"
+
+/*101:*/
+#line 805 "cwebdir/ctang-w2c.ch"
+
+if(comparison)
+remove(check_file_name);
+else{
+remove(C_file_name);
+rename(check_file_name,C_file_name);
+}
+
+/*:101*/
+#line 775 "cwebdir/ctang-w2c.ch"
+
+}else
+rename(check_file_name,C_file_name);
+
+/*:98*/
+#line 311 "cwebdir/ctang-w2c.ch"
 
 for(an_output_file= end_output_files;an_output_file> cur_out_file;){
 an_output_file--;
 sprint_section_name(output_file_name,*an_output_file);
-fclose(C_file);
-#line 302 "cwebdir/ctang-w2c.ch"
-C_file= fopen(output_file_name,"wb");
-#line 578 "cwebdir/ctangle.w"
-if(C_file==0)fatal("! Cannot open output file:",output_file_name);
+if((C_file= fopen(check_file_name,"wb"))==NULL)
+fatal(_("! Cannot open output file "),check_file_name);
 
 printf("\n(%s)",output_file_name);update_terminal;
 cur_line= 1;
@@ -690,20 +822,80 @@ cur_repl= (text_pointer)cur_name->equiv;
 cur_byte= cur_repl->tok_start;
 cur_end= (cur_repl+1)->tok_start;
 while(stack_ptr> stack)get_output();
-flush_buffer();
+flush_buffer();fclose(C_file);C_file= NULL;
+/*102:*/
+#line 813 "cwebdir/ctang-w2c.ch"
+
+if((C_file= fopen(output_file_name,"r"))!=NULL){
+/*99:*/
+#line 779 "cwebdir/ctang-w2c.ch"
+
+char x[BUFSIZ],y[BUFSIZ];
+int x_size,y_size,comparison;
+
+if((check_file= fopen(check_file_name,"r"))==NULL)
+fatal(_("! Cannot open output file "),check_file_name);
+
+
+/*100:*/
+#line 794 "cwebdir/ctang-w2c.ch"
+
+do{
+x_size= fread(x,1,BUFSIZ,C_file);
+y_size= fread(y,1,BUFSIZ,check_file);
+comparison= (x_size==y_size);
+if(comparison)comparison= !memcmp(x,y,x_size);
+}while(comparison&&!feof(C_file)&&!feof(check_file));
+
+/*:100*/
+#line 787 "cwebdir/ctang-w2c.ch"
+
+
+fclose(C_file);C_file= NULL;
+fclose(check_file);check_file= NULL;
+
+/*:99*/
+#line 815 "cwebdir/ctang-w2c.ch"
+
+/*103:*/
+#line 822 "cwebdir/ctang-w2c.ch"
+
+if(comparison)
+remove(check_file_name);
+else{
+remove(output_file_name);
+rename(check_file_name,output_file_name);
+}
+
+/*:103*/
+#line 816 "cwebdir/ctang-w2c.ch"
+
+}else
+rename(check_file_name,output_file_name);
+
+/*:102*/
+#line 327 "cwebdir/ctang-w2c.ch"
+
 }
+strcpy(check_file_name,"");
+#line 590 "cwebdir/ctangle.w"
 
-/*:42*/
+/*:43*/
 #line 563 "cwebdir/ctangle.w"
 ;
-if(show_happiness)printf("\nDone.");
+#line 283 "cwebdir/ctang-w2c.ch"
+if(show_happiness){
+if(show_progress)new_line;
+fputs(_("Done."),stdout);
+}
+#line 565 "cwebdir/ctangle.w"
 }
 }
 
-/*:41*//*46:*/
+/*:42*//*47:*/
 #line 605 "cwebdir/ctangle.w"
 
-#line 319 "cwebdir/ctang-w2c.ch"
+#line 342 "cwebdir/ctang-w2c.ch"
 static void
 output_defs(void)
 #line 608 "cwebdir/ctangle.w"
@@ -729,7 +921,9 @@ a= (a-0200)*0400+*cur_byte++;
 if(a<024000){
 cur_val= a;out_char(identifier);
 }
-else if(a<050000){confusion("macro defs have strange char");}
+#line 349 "cwebdir/ctang-w2c.ch"
+else if(a<050000){confusion(_("macro defs have strange char"));}
+#line 631 "cwebdir/ctangle.w"
 else{
 cur_val= a-050000;cur_section= cur_val;out_char(section_number);
 }
@@ -742,12 +936,13 @@ flush_buffer();
 pop_level(0);
 }
 
-/*:46*//*48:*/
+/*:47*//*49:*/
 #line 651 "cwebdir/ctangle.w"
 
+#line 363 "cwebdir/ctang-w2c.ch"
 static void
-#line 337 "cwebdir/ctang-w2c.ch"
- out_char(eight_bits cur_char)
+out_char(
+eight_bits cur_char)
 #line 655 "cwebdir/ctangle.w"
 {
 char*j,*k;
@@ -756,7 +951,7 @@ switch(cur_char){
 case'\n':if(protect&&out_state!=verbatim)C_putc(' ');
 if(protect||out_state==verbatim)C_putc('\\');
 flush_buffer();if(out_state!=verbatim)out_state= normal;break;
-/*52:*/
+/*53:*/
 #line 719 "cwebdir/ctangle.w"
 
 case identifier:
@@ -771,10 +966,10 @@ j++;
 }
 out_state= num_or_id;break;
 
-/*:52*/
+/*:53*/
 #line 662 "cwebdir/ctangle.w"
 ;
-/*53:*/
+/*54:*/
 #line 732 "cwebdir/ctangle.w"
 
 case section_number:
@@ -801,11 +996,11 @@ C_printf("%s","\"\n");
 }
 break;
 
-/*:53*/
+/*:54*/
 #line 663 "cwebdir/ctangle.w"
 ;
-/*49:*/
-#line 681 "cwebdir/ctangle.w"
+/*50:*/
+#line 388 "cwebdir/ctang-w2c.ch"
 
 case plus_plus:C_putc('+');C_putc('+');out_state= normal;break;
 case minus_minus:C_putc('-');C_putc('-');out_state= normal;break;
@@ -815,7 +1010,7 @@ case eq_eq:C_putc('=');C_putc('=');out_state= normal;break;
 case lt_lt:C_putc('<');C_putc('<');out_state= normal;break;
 case gt_eq:C_putc('>');C_putc('=');out_state= normal;break;
 case lt_eq:C_putc('<');C_putc('=');out_state= normal;break;
-case not_eq:C_putc('!');C_putc('=');out_state= normal;break;
+case non_eq:C_putc('!');C_putc('=');out_state= normal;break;
 case and_and:C_putc('&');C_putc('&');out_state= normal;break;
 case or_or:C_putc('|');C_putc('|');out_state= normal;break;
 case dot_dot_dot:C_putc('.');C_putc('.');C_putc('.');out_state= normal;
@@ -824,8 +1019,9 @@ case colon_colon:C_putc(':');C_putc(':');out_state= normal;break;
 case period_ast:C_putc('.');C_putc('*');out_state= normal;break;
 case minus_gt_ast:C_putc('-');C_putc('>');C_putc('*');out_state= normal;
 break;
+#line 699 "cwebdir/ctangle.w"
 
-/*:49*/
+/*:50*/
 #line 664 "cwebdir/ctangle.w"
 ;
 case'=':case'>':C_putc(cur_char);C_putc(' ');
@@ -844,10 +1040,11 @@ default:C_putc(cur_char);out_state= normal;break;
 }
 }
 
-/*:48*//*57:*/
+#line 388 "cwebdir/ctang-w2c.ch"
+/*:49*//*58:*/
 #line 813 "cwebdir/ctangle.w"
 
-#line 346 "cwebdir/ctang-w2c.ch"
+#line 412 "cwebdir/ctang-w2c.ch"
 static eight_bits
 skip_ahead(void)
 #line 816 "cwebdir/ctangle.w"
@@ -864,12 +1061,12 @@ if(c!=ignore||*(loc-1)=='>')return(c);
 }
 }
 
-/*:57*//*59:*/
+/*:58*//*60:*/
 #line 848 "cwebdir/ctangle.w"
 
-#line 356 "cwebdir/ctang-w2c.ch"
-static int
-skip_comment(boolean is_long_comment)
+#line 420 "cwebdir/ctang-w2c.ch"
+static boolean skip_comment(
+boolean is_long_comment)
 #line 851 "cwebdir/ctangle.w"
 {
 char c;
@@ -878,7 +1075,9 @@ if(loc> limit){
 if(is_long_comment){
 if(get_line())return(comment_continues= 1);
 else{
-err_print("! Input ended in mid-comment");
+#line 427 "cwebdir/ctang-w2c.ch"
+err_print(_("! Input ended in mid-comment"));
+#line 859 "cwebdir/ctangle.w"
 
 return(comment_continues= 0);
 }
@@ -891,7 +1090,9 @@ loc++;return(comment_continues= 0);
 }
 if(c=='@'){
 if(ccode[(eight_bits)*loc]==new_section){
-err_print("! Section name ended in mid-comment");loc--;
+#line 433 "cwebdir/ctang-w2c.ch"
+err_print(_("! Section name ended in mid-comment"));loc--;
+#line 872 "cwebdir/ctangle.w"
 
 return(comment_continues= 0);
 }
@@ -900,10 +1101,10 @@ else loc++;
 }
 }
 
-/*:59*//*62:*/
+/*:60*//*63:*/
 #line 900 "cwebdir/ctangle.w"
 
-#line 373 "cwebdir/ctang-w2c.ch"
+#line 440 "cwebdir/ctang-w2c.ch"
 static eight_bits
 get_next(void)
 #line 903 "cwebdir/ctangle.w"
@@ -916,7 +1117,7 @@ if(preprocessing&&*(limit-1)!='\\')preprocessing= 0;
 if(get_line()==0)return(new_section);
 else if(print_where&&!no_where){
 print_where= 0;
-/*76:*/
+/*77:*/
 #line 1225 "cwebdir/ctangle.w"
 
 store_two_bytes(0150000);
@@ -928,12 +1129,12 @@ id_first= cur_file_name;
 store_two_bytes((sixteen_bits)cur_line);
 }
 id_loc= id_first+strlen(id_first);
-#line 410 "cwebdir/ctang-w2c.ch"
+#line 582 "cwebdir/ctang-w2c.ch"
 {int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200);
 app_repl(a_l%0400);}
 #line 1237 "cwebdir/ctangle.w"
 
-/*:76*/
+/*:77*/
 #line 912 "cwebdir/ctangle.w"
 ;
 }
@@ -947,7 +1148,7 @@ if(comment_continues)return('\n');
 else continue;
 }
 loc++;
-if(xisdigit(c)||c=='.')/*65:*/
+if(xisdigit(c)||c=='.')/*66:*/
 #line 978 "cwebdir/ctangle.w"
 {
 id_first= loc-1;
@@ -972,27 +1173,38 @@ id_loc= loc;
 return(constant);
 }
 
-/*:65*/
+/*:66*/
 #line 924 "cwebdir/ctangle.w"
 
-else if(c=='\''||c=='"'||(c=='L'&&(*loc=='\''||*loc=='"')))
-/*66:*/
+#line 447 "cwebdir/ctang-w2c.ch"
+else if(c=='\''||c=='"'
+||((c=='L'||c=='u'||c=='U')&&(*loc=='\''||*loc=='"'))
+||((c=='u'&&*loc=='8')&&(*(loc+1)=='\''||*(loc+1)=='"')))
+#line 926 "cwebdir/ctangle.w"
+/*67:*/
 #line 1006 "cwebdir/ctangle.w"
 {
 char delim= c;
 id_first= section_text+1;
 id_loc= section_text;*++id_loc= delim;
-if(delim=='L'){
+#line 478 "cwebdir/ctang-w2c.ch"
+if(delim=='L'||delim=='u'||delim=='U'){
+if(delim=='u'&&*loc=='8'){*++id_loc= *loc++;}
 delim= *loc++;*++id_loc= delim;
 }
+#line 1013 "cwebdir/ctangle.w"
 while(1){
 if(loc>=limit){
 if(*(limit-1)!='\\'){
-err_print("! String didn't end");loc= limit;break;
+#line 487 "cwebdir/ctang-w2c.ch"
+err_print(_("! String didn't end"));loc= limit;break;
+#line 1017 "cwebdir/ctangle.w"
 
 }
 if(get_line()==0){
-err_print("! Input ended in middle of string");loc= buffer;break;
+#line 493 "cwebdir/ctang-w2c.ch"
+err_print(_("! Input ended in middle of string"));loc= buffer;break;
+#line 1021 "cwebdir/ctangle.w"
 
 }
 else if(++id_loc<=section_text_end)*id_loc= '\n';
@@ -1010,7 +1222,9 @@ c= *loc++;
 if(++id_loc<=section_text_end)*id_loc= c;
 }
 if(id_loc>=section_text_end){
-printf("\n! String too long: ");
+#line 499 "cwebdir/ctang-w2c.ch"
+fputs(_("\n! String too long: "),stdout);
+#line 1039 "cwebdir/ctangle.w"
 
 term_write(section_text+1,25);
 err_print("...");
@@ -1019,55 +1233,62 @@ id_loc++;
 return(string);
 }
 
-/*:66*/
+/*:67*/
 #line 926 "cwebdir/ctangle.w"
 
 else if(isalpha(c)||isxalpha(c)||ishigh(c))
-/*64:*/
+/*65:*/
 #line 972 "cwebdir/ctangle.w"
 {
 id_first= --loc;
-#line 390 "cwebdir/ctang-w2c.ch"
-while(isalpha((unsigned char)*++loc)||isdigit((unsigned char)*loc)||isxalpha(*loc)||ishigh(*loc));
+#line 469 "cwebdir/ctang-w2c.ch"
+while(isalpha((eight_bits)*++loc)||isdigit((eight_bits)*loc)
+||isxalpha((eight_bits)*loc)||ishigh((eight_bits)*loc));
 #line 975 "cwebdir/ctangle.w"
 id_loc= loc;return(identifier);
 }
 
-/*:64*/
+/*:65*/
 #line 928 "cwebdir/ctangle.w"
 
-else if(c=='@')/*67:*/
+else if(c=='@')/*68:*/
 #line 1050 "cwebdir/ctangle.w"
 {
 c= ccode[(eight_bits)*loc++];
 switch(c){
 case ignore:continue;
-case translit_code:err_print("! Use @l in limbo only");continue;
+#line 505 "cwebdir/ctang-w2c.ch"
+case translit_code:err_print(_("! Use @l in limbo only"));continue;
+#line 1055 "cwebdir/ctangle.w"
 
 case control_text:while((c= skip_ahead())=='@');
 
 if(*(loc-1)!='>')
-err_print("! Double @ should be used in control text");
+#line 511 "cwebdir/ctang-w2c.ch"
+err_print(_("! Double @ should be used in control text"));
+#line 1060 "cwebdir/ctangle.w"
 
 continue;
 case section_name:
 cur_section_name_char= *(loc-1);
-/*69:*/
+/*70:*/
 #line 1098 "cwebdir/ctangle.w"
 {
 char*k;
-/*71:*/
+/*72:*/
 #line 1118 "cwebdir/ctangle.w"
 
 k= section_text;
 while(1){
 if(loc> limit&&get_line()==0){
-err_print("! Input ended in section name");
+#line 529 "cwebdir/ctang-w2c.ch"
+err_print(_("! Input ended in section name"));
+#line 1123 "cwebdir/ctangle.w"
 
 loc= buffer+1;break;
 }
 c= *loc;
-/*72:*/
+/*73:*/
 #line 1142 "cwebdir/ctangle.w"
 
 if(c=='@'){
@@ -1076,17 +1297,21 @@ if(c=='>'){
 loc+= 2;break;
 }
 if(ccode[(eight_bits)c]==new_section){
-err_print("! Section name didn't end");break;
+#line 541 "cwebdir/ctang-w2c.ch"
+err_print(_("! Section name didn't end"));break;
+#line 1150 "cwebdir/ctangle.w"
 
 }
 if(ccode[(eight_bits)c]==section_name){
-err_print("! Nesting of section names not allowed");break;
+#line 547 "cwebdir/ctang-w2c.ch"
+err_print(_("! Nesting of section names not allowed"));break;
+#line 1154 "cwebdir/ctangle.w"
 
 }
 *(++k)= '@';loc++;
 }
 
-/*:72*/
+/*:73*/
 #line 1127 "cwebdir/ctangle.w"
 ;
 loc++;if(k<section_text_end)k++;
@@ -1096,21 +1321,23 @@ c= ' ';if(*(k-1)==' ')k--;
 *k= c;
 }
 if(k>=section_text_end){
-printf("\n! Section name too long: ");
+#line 535 "cwebdir/ctang-w2c.ch"
+fputs(_("\n! Section name too long: "),stdout);
+#line 1136 "cwebdir/ctangle.w"
 
 term_write(section_text+1,25);
 printf("...");mark_harmless;
 }
 if(*k==' '&&k> section_text)k--;
 
-/*:71*/
+/*:72*/
 #line 1100 "cwebdir/ctangle.w"
 ;
 if(k-section_text> 3&&strncmp(k-2,"...",3)==0)
 cur_section_name= section_lookup(section_text+1,k-3,1);
 else cur_section_name= section_lookup(section_text+1,k,0);
 if(cur_section_name_char=='(')
-/*39:*/
+/*40:*/
 #line 516 "cwebdir/ctangle.w"
 
 {
@@ -1121,35 +1348,39 @@ if(an_output_file==end_output_files){
 if(cur_out_file> output_files)
 *--cur_out_file= cur_section_name;
 else{
-overflow("output files");
+#line 245 "cwebdir/ctang-w2c.ch"
+overflow(_("output files"));
+#line 526 "cwebdir/ctangle.w"
 }
 }
 }
 
-/*:39*/
+/*:40*/
 #line 1106 "cwebdir/ctangle.w"
 ;
 return(section_name);
 }
 
-/*:69*/
+/*:70*/
 #line 1064 "cwebdir/ctangle.w"
 ;
-case string:/*73:*/
+case string:/*74:*/
 #line 1164 "cwebdir/ctangle.w"
 {
 id_first= loc++;*(limit+1)= '@';*(limit+2)= '>';
 while(*loc!='@'||*(loc+1)!='>')loc++;
-if(loc>=limit)err_print("! Verbatim string didn't end");
+#line 553 "cwebdir/ctang-w2c.ch"
+if(loc>=limit)err_print(_("! Verbatim string didn't end"));
+#line 1168 "cwebdir/ctangle.w"
 
 id_loc= loc;loc+= 2;
 return(string);
 }
 
-/*:73*/
+/*:74*/
 #line 1065 "cwebdir/ctangle.w"
 ;
-case ord:/*68:*/
+case ord:/*69:*/
 #line 1077 "cwebdir/ctangle.w"
 
 id_first= loc;
@@ -1159,27 +1390,31 @@ if(*++loc=='\'')loc++;
 while(*loc!='\''){
 if(*loc=='@'){
 if(*(loc+1)!='@')
-err_print("! Double @ should be used in ASCII constant");
+#line 517 "cwebdir/ctang-w2c.ch"
+err_print(_("! Double @ should be used in ASCII constant"));
+#line 1086 "cwebdir/ctangle.w"
 
 else loc++;
 }
 loc++;
 if(loc> limit){
-err_print("! String didn't end");loc= limit-1;break;
+#line 523 "cwebdir/ctang-w2c.ch"
+err_print(_("! String didn't end"));loc= limit-1;break;
+#line 1092 "cwebdir/ctangle.w"
 
 }
 }
 loc++;
 return(ord);
 
-/*:68*/
+/*:69*/
 #line 1066 "cwebdir/ctangle.w"
 ;
 default:return(c);
 }
 }
 
-/*:67*/
+/*:68*/
 #line 929 "cwebdir/ctangle.w"
 
 else if(xisspace(c)){
@@ -1188,15 +1423,15 @@ if(!preprocessing||loc> limit)continue;
 else return(' ');
 }
 else if(c=='#'&&loc==buffer+1)preprocessing= 1;
-mistake:/*63:*/
+mistake:/*64:*/
 #line 950 "cwebdir/ctangle.w"
 
 switch(c){
 case'+':if(*loc=='+')compress(plus_plus);break;
 case'-':if(*loc=='-'){compress(minus_minus);}
-#line 383 "cwebdir/ctang-w2c.ch"
-else if(*loc=='>'){if(*(loc+1)=='*'){loc++;compress(minus_gt_ast);}
-else compress(minus_gt);}break;
+#line 456 "cwebdir/ctang-w2c.ch"
+else{if(*loc=='>'){if(*(loc+1)=='*'){loc++;compress(minus_gt_ast);}
+else compress(minus_gt);}}break;
 #line 956 "cwebdir/ctangle.w"
 case'.':if(*loc=='*'){compress(period_ast);}
 else if(*loc=='.'&&*(loc+1)=='.'){
@@ -1211,26 +1446,29 @@ case'<':if(*loc=='='){compress(lt_eq);}
 else if(*loc=='<')compress(lt_lt);break;
 case'&':if(*loc=='&')compress(and_and);break;
 case'|':if(*loc=='|')compress(or_or);break;
-case'!':if(*loc=='=')compress(not_eq);break;
+#line 463 "cwebdir/ctang-w2c.ch"
+case'!':if(*loc=='=')compress(non_eq);break;
+#line 970 "cwebdir/ctangle.w"
 }
 
-/*:63*/
+/*:64*/
 #line 936 "cwebdir/ctangle.w"
 
 return(c);
 }
 }
 
-/*:62*//*75:*/
+/*:63*//*76:*/
 #line 1199 "cwebdir/ctangle.w"
 
-#line 400 "cwebdir/ctang-w2c.ch"
+#line 567 "cwebdir/ctang-w2c.ch"
 static void
-scan_repl(eight_bits t)
+scan_repl(
+eight_bits t)
 #line 1203 "cwebdir/ctangle.w"
 {
 sixteen_bits a;
-if(t==section_name){/*76:*/
+if(t==section_name){/*77:*/
 #line 1225 "cwebdir/ctangle.w"
 
 store_two_bytes(0150000);
@@ -1242,16 +1480,16 @@ id_first= cur_file_name;
 store_two_bytes((sixteen_bits)cur_line);
 }
 id_loc= id_first+strlen(id_first);
-#line 410 "cwebdir/ctang-w2c.ch"
+#line 582 "cwebdir/ctang-w2c.ch"
 {int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200);
 app_repl(a_l%0400);}
 #line 1237 "cwebdir/ctangle.w"
 
-/*:76*/
+/*:77*/
 #line 1205 "cwebdir/ctangle.w"
 ;}
 while(1)switch(a= get_next()){
-/*77:*/
+/*78:*/
 #line 1238 "cwebdir/ctangle.w"
 
 case identifier:a= id_lookup(id_first,id_loc,0)-name_dir;
@@ -1259,26 +1497,28 @@ app_repl((a/0400)+0200);
 app_repl(a%0400);break;
 case section_name:if(t!=section_name)goto done;
 else{
-/*78:*/
+/*79:*/
 #line 1271 "cwebdir/ctangle.w"
 {
 char*try_loc= loc;
 while(*try_loc==' '&&try_loc<limit)try_loc++;
 if(*try_loc=='+'&&try_loc<limit)try_loc++;
 while(*try_loc==' '&&try_loc<limit)try_loc++;
-if(*try_loc=='=')err_print("! Missing `@ ' before a named section");
+#line 601 "cwebdir/ctang-w2c.ch"
+if(*try_loc=='=')err_print(_("! Missing `@ ' before a named section"));
+#line 1277 "cwebdir/ctangle.w"
 
 
 
 }
 
-/*:78*/
+/*:79*/
 #line 1244 "cwebdir/ctangle.w"
 ;
 a= cur_section_name-name_dir;
 app_repl((a/0400)+0250);
 app_repl(a%0400);
-/*76:*/
+/*77:*/
 #line 1225 "cwebdir/ctangle.w"
 
 store_two_bytes(0150000);
@@ -1290,23 +1530,25 @@ id_first= cur_file_name;
 store_two_bytes((sixteen_bits)cur_line);
 }
 id_loc= id_first+strlen(id_first);
-#line 410 "cwebdir/ctang-w2c.ch"
+#line 582 "cwebdir/ctang-w2c.ch"
 {int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200);
 app_repl(a_l%0400);}
 #line 1237 "cwebdir/ctangle.w"
 
-/*:76*/
+/*:77*/
 #line 1248 "cwebdir/ctangle.w"
 ;break;
 }
-case output_defs_code:if(t!=section_name)err_print("! Misplaced @h");
+#line 589 "cwebdir/ctang-w2c.ch"
+case output_defs_code:if(t!=section_name)err_print(_("! Misplaced @h"));
+#line 1251 "cwebdir/ctangle.w"
 
 else{
 output_defs_seen= 1;
 a= output_defs_flag;
 app_repl((a/0400)+0200);
 app_repl(a%0400);
-/*76:*/
+/*77:*/
 #line 1225 "cwebdir/ctangle.w"
 
 store_two_bytes(0150000);
@@ -1318,36 +1560,38 @@ id_first= cur_file_name;
 store_two_bytes((sixteen_bits)cur_line);
 }
 id_loc= id_first+strlen(id_first);
-#line 410 "cwebdir/ctang-w2c.ch"
+#line 582 "cwebdir/ctang-w2c.ch"
 {int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200);
 app_repl(a_l%0400);}
 #line 1237 "cwebdir/ctangle.w"
 
-/*:76*/
+/*:77*/
 #line 1257 "cwebdir/ctangle.w"
 ;
 }
 break;
 case constant:case string:
-/*79:*/
+/*80:*/
 #line 1282 "cwebdir/ctangle.w"
 
 app_repl(a);
 while(id_first<id_loc){
 if(*id_first=='@'){
 if(*(id_first+1)=='@')id_first++;
-else err_print("! Double @ should be used in string");
+#line 607 "cwebdir/ctang-w2c.ch"
+else err_print(_("! Double @ should be used in string"));
+#line 1288 "cwebdir/ctangle.w"
 
 }
 app_repl(*id_first++);
 }
 app_repl(a);break;
 
-/*:79*/
+/*:80*/
 #line 1261 "cwebdir/ctangle.w"
 ;
 case ord:
-/*80:*/
+/*81:*/
 #line 1298 "cwebdir/ctangle.w"
 {
 int c= (eight_bits)*id_first;
@@ -1374,22 +1618,24 @@ case'x':
 if(xisdigit(*(id_first+1)))c= *(++id_first)-'0';
 else if(xisxdigit(*(id_first+1))){
 ++id_first;
-#line 419 "cwebdir/ctang-w2c.ch"
-c= toupper((unsigned char)*id_first)-'A'+10;
+#line 613 "cwebdir/ctang-w2c.ch"
+c= toupper((eight_bits)*id_first)-'A'+10;
 #line 1324 "cwebdir/ctangle.w"
 }
 if(xisdigit(*(id_first+1)))c= 16*c+*(++id_first)-'0';
 else if(xisxdigit(*(id_first+1))){
 ++id_first;
-#line 424 "cwebdir/ctang-w2c.ch"
-c= 16*c+toupper((unsigned char)*id_first)-'A'+10;
+#line 619 "cwebdir/ctang-w2c.ch"
+c= 16*c+toupper((eight_bits)*id_first)-'A'+10;
 #line 1329 "cwebdir/ctangle.w"
 }
 break;
 case'\\':c= '\\';break;
 case'\'':c= '\'';break;
 case'\"':c= '\"';break;
-default:err_print("! Unrecognized escape sequence");
+#line 625 "cwebdir/ctang-w2c.ch"
+default:err_print(_("! Unrecognized escape sequence"));
+#line 1335 "cwebdir/ctangle.w"
 
 }
 }
@@ -1402,17 +1648,19 @@ app_repl(constant);
 }
 break;
 
-/*:80*/
+/*:81*/
 #line 1263 "cwebdir/ctangle.w"
 ;
 case definition:case format_code:case begin_C:if(t!=section_name)goto done;
 else{
-err_print("! @d, @f and @c are ignored in C text");continue;
+#line 595 "cwebdir/ctang-w2c.ch"
+err_print(_("! @d, @f and @c are ignored in C text"));continue;
+#line 1267 "cwebdir/ctangle.w"
 
 }
 case new_section:goto done;
 
-/*:77*/
+/*:78*/
 #line 1210 "cwebdir/ctangle.w"
 
 case')':app_repl(a);
@@ -1421,14 +1669,16 @@ break;
 default:app_repl(a);
 }
 done:next_control= (eight_bits)a;
-if(text_ptr> text_info_end)overflow("text");
+#line 575 "cwebdir/ctang-w2c.ch"
+if(text_ptr> text_info_end)overflow(_("text"));
+#line 1218 "cwebdir/ctangle.w"
 cur_text= text_ptr;(++text_ptr)->tok_start= tok_ptr;
 }
 
-/*:75*//*82:*/
+/*:76*//*83:*/
 #line 1360 "cwebdir/ctangle.w"
 
-#line 433 "cwebdir/ctang-w2c.ch"
+#line 632 "cwebdir/ctang-w2c.ch"
 static void
 scan_section(void)
 #line 1363 "cwebdir/ctangle.w"
@@ -1442,7 +1692,7 @@ printf("*%d",section_count);update_terminal;
 }
 next_control= 0;
 while(1){
-/*83:*/
+/*84:*/
 #line 1399 "cwebdir/ctangle.w"
 
 while(next_control<definition)
@@ -1451,16 +1701,18 @@ if((next_control= skip_ahead())==section_name){
 loc-= 2;next_control= get_next();
 }
 
-/*:83*/
+/*:84*/
 #line 1374 "cwebdir/ctangle.w"
 ;
 if(next_control==definition){
-/*84:*/
+/*85:*/
 #line 1406 "cwebdir/ctangle.w"
 {
 while((next_control= get_next())=='\n');
 if(next_control!=identifier){
-err_print("! Definition flushed, must start with identifier");
+#line 639 "cwebdir/ctang-w2c.ch"
+err_print(_("! Definition flushed, must start with identifier"));
+#line 1410 "cwebdir/ctangle.w"
 
 continue;
 }
@@ -1474,7 +1726,7 @@ scan_repl(macro);
 cur_text->text_link= 0;
 }
 
-/*:84*/
+/*:85*/
 #line 1376 "cwebdir/ctangle.w"
 
 continue;
@@ -1484,14 +1736,14 @@ p= name_dir;break;
 }
 if(next_control==section_name){
 p= cur_section_name;
-/*85:*/
+/*86:*/
 #line 1431 "cwebdir/ctangle.w"
 
 while((next_control= get_next())=='+');
 if(next_control!='='&&next_control!=eq_eq)
 continue;
 
-/*:85*/
+/*:86*/
 #line 1384 "cwebdir/ctangle.w"
 ;
 break;
@@ -1499,26 +1751,28 @@ break;
 return;
 }
 no_where= print_where= 0;
-/*86:*/
+/*87:*/
 #line 1436 "cwebdir/ctangle.w"
 
-/*87:*/
+/*88:*/
 #line 1441 "cwebdir/ctangle.w"
 
 store_two_bytes((sixteen_bits)(0150000+section_count));
 
 
-/*:87*/
+/*:88*/
 #line 1437 "cwebdir/ctangle.w"
 ;
 scan_repl(section_name);
-/*88:*/
+/*89:*/
 #line 1445 "cwebdir/ctangle.w"
 
 if(p==name_dir||p==0){
 (last_unnamed)->text_link= cur_text-text_info;last_unnamed= cur_text;
 }
-else if(p->equiv==(char*)text_info)p->equiv= (char*)cur_text;
+#line 645 "cwebdir/ctang-w2c.ch"
+else if(p->equiv==(void*)text_info)p->equiv= (void*)cur_text;
+#line 1450 "cwebdir/ctangle.w"
 
 else{
 q= (text_pointer)p->equiv;
@@ -1529,19 +1783,19 @@ q->text_link= cur_text-text_info;
 cur_text->text_link= section_flag;
 
 
-/*:88*/
+/*:89*/
 #line 1439 "cwebdir/ctangle.w"
 ;
 
-/*:86*/
+/*:87*/
 #line 1390 "cwebdir/ctangle.w"
 ;
 }
 
-/*:82*//*90:*/
+/*:83*//*91:*/
 #line 1463 "cwebdir/ctangle.w"
 
-#line 451 "cwebdir/ctang-w2c.ch"
+#line 658 "cwebdir/ctang-w2c.ch"
 static void
 phase_one(void){
 #line 1466 "cwebdir/ctangle.w"
@@ -1554,10 +1808,10 @@ check_complete();
 phase= 2;
 }
 
-/*:90*//*92:*/
+/*:91*//*93:*/
 #line 1481 "cwebdir/ctangle.w"
 
-#line 469 "cwebdir/ctang-w2c.ch"
+#line 672 "cwebdir/ctang-w2c.ch"
 static void
 skip_limbo(void)
 #line 1484 "cwebdir/ctangle.w"
@@ -1571,14 +1825,16 @@ if(loc++<=limit){
 c= *loc++;
 if(ccode[(eight_bits)c]==new_section)break;
 switch(ccode[(eight_bits)c]){
-case translit_code:/*93:*/
+case translit_code:/*94:*/
 #line 1510 "cwebdir/ctangle.w"
 
 while(xisspace(*loc)&&loc<limit)loc++;
 loc+= 3;
 if(loc> limit||!xisxdigit(*(loc-3))||!xisxdigit(*(loc-2))
 ||(*(loc-3)>='0'&&*(loc-3)<='7')||!xisspace(*(loc-1)))
-err_print("! Improper hex number following @l");
+#line 691 "cwebdir/ctang-w2c.ch"
+err_print(_("! Improper hex number following @l"));
+#line 1516 "cwebdir/ctangle.w"
 
 else{
 unsigned i;
@@ -1588,48 +1844,58 @@ while(xisspace(*loc)&&loc<limit)loc++;
 beg= loc;
 while(loc<limit&&(xisalpha(*loc)||xisdigit(*loc)||*loc=='_'))loc++;
 if(loc-beg>=translit_length)
-err_print("! Replacement string in @l too long");
+#line 697 "cwebdir/ctang-w2c.ch"
+err_print(_("! Replacement string in @l too long"));
+#line 1526 "cwebdir/ctangle.w"
 
 else{
-strncpy(translit[i-0200],beg,loc-beg);
+#line 703 "cwebdir/ctang-w2c.ch"
+strncpy(translit[i-0200],beg,(size_t)(loc-beg));
+#line 1529 "cwebdir/ctangle.w"
 translit[i-0200][loc-beg]= '\0';
 }
 }
 
-/*:93*/
+/*:94*/
 #line 1494 "cwebdir/ctangle.w"
 ;break;
 case format_code:case'@':break;
 case control_text:if(c=='q'||c=='Q'){
 while((c= skip_ahead())=='@');
 if(*(loc-1)!='>')
-err_print("! Double @ should be used in control text");
+#line 679 "cwebdir/ctang-w2c.ch"
+err_print(_("! Double @ should be used in control text"));
+#line 1500 "cwebdir/ctangle.w"
 
 break;
 }
-default:err_print("! Double @ should be used in limbo");
+#line 685 "cwebdir/ctang-w2c.ch"
+default:err_print(_("! Double @ should be used in limbo"));
+#line 1504 "cwebdir/ctangle.w"
 
 }
 }
 }
 }
 
-/*:92*//*94:*/
+/*:93*//*95:*/
 #line 1536 "cwebdir/ctangle.w"
 
+#line 710 "cwebdir/ctang-w2c.ch"
 void
-#line 478 "cwebdir/ctang-w2c.ch"
- print_stats(void){
-#line 1539 "cwebdir/ctangle.w"
-printf("\nMemory usage statistics:\n");
-printf("%ld names (out of %ld)\n",
+print_stats(void){
+#line 724 "cwebdir/ctang-w2c.ch"
+puts(_("\nMemory usage statistics:"));
+printf(_("%ld names (out of %ld)\n"),
 (long)(name_ptr-name_dir),(long)max_names);
-printf("%ld replacement texts (out of %ld)\n",
+printf(_("%ld replacement texts (out of %ld)\n"),
 (long)(text_ptr-text_info),(long)max_texts);
-printf("%ld bytes (out of %ld)\n",
+printf(_("%ld bytes (out of %ld)\n"),
 (long)(byte_ptr-byte_mem),(long)max_bytes);
-printf("%ld tokens (out of %ld)\n",
+printf(_("%ld tokens (out of %ld)\n"),
+#line 1547 "cwebdir/ctangle.w"
 (long)(tok_ptr-tok_mem),(long)max_toks);
 }
 
-/*:94*/
+#line 737 "cwebdir/ctang-w2c.ch"
+/*:95*/
diff --git a/source/texk/web2c/cwebboot.cin b/source/texk/web2c/cwebboot.cin
index b8f0a754cf7f2f22d968fd7c52a1deff905aaa29..66cba9d30c4e25a751dccd0a1598e7f2e23d8757 100644
--- a/source/texk/web2c/cwebboot.cin
+++ b/source/texk/web2c/cwebboot.cin
@@ -4,11 +4,7 @@
 /*5:*/
 #line 102 "cwebdir/common.w"
 
-#line 73 "cwebdir/comm-w2c.ch"
-#define CWEB
-#include "cpascal.h"
 #include <ctype.h> 
-#line 104 "cwebdir/common.w"
 
 /*:5*//*8:*/
 #line 165 "cwebdir/common.w"
@@ -18,16 +14,57 @@
 /*:8*//*22:*/
 #line 471 "cwebdir/common.w"
 
-#line 212 "cwebdir/comm-w2c.ch"
-#include <kpathsea/kpathsea.h>  
 #include <stdlib.h>  
+
+/*:22*//*81:*/
+#line 1123 "cwebdir/comm-w2c.ch"
+
+#include <string.h> 
+#line 1417 "cwebdir/common.w"
+
+#line 1130 "cwebdir/comm-w2c.ch"
+/*:81*//*85:*/
+#line 1169 "cwebdir/comm-w2c.ch"
+
+#include <stdbool.h>  
+#include <stddef.h>  
+#include <stdint.h>  
+
+/*:85*//*88:*/
+#line 1211 "cwebdir/comm-w2c.ch"
+
+#include <locale.h> 
+
+#ifndef HAVE_GETTEXT
+#define HAVE_GETTEXT 0
+#endif
+
+#if HAVE_GETTEXT
+#include <libintl.h> 
+#else
+#define bindtextdomain(A,B) ""
+#define textdomain(A) ""
+#define gettext(A) A
+#endif
+
+/*:88*//*90:*/
+#line 1301 "cwebdir/comm-w2c.ch"
+
+typedef bool boolean;
+#define HAVE_BOOLEAN
+#include <kpathsea/kpathsea.h>  
+#include <w2c/config.h>  
+#include <lib/lib.h>  
+
+#define CWEB
 #include "help.h"
 
-/*:22*/
+/*:90*/
 #line 59 "cwebdir/common.w"
 
 #define ctangle 0
-#define cweave 1 \
+#define cweave 1
+#define ctwill 2 \
 
 #define and_and 04
 #define lt_lt 020
@@ -35,7 +72,7 @@
 #define plus_plus 013
 #define minus_minus 01
 #define minus_gt 031
-#define not_eq 032
+#define non_eq 032
 #define lt_eq 034
 #define gt_eq 035
 #define eq_eq 036
@@ -48,8 +85,8 @@
 #define buf_size 1000
 #define longest_name 10000
 #define long_buf_size (buf_size+longest_name) 
-#define xisspace(c) (isspace((unsigned char) c) &&((unsigned char) c<0200) ) 
-#define xisupper(c) (isupper((unsigned char) c) &&((unsigned char) c<0200) )  \
+#define xisspace(c) (isspace((eight_bits) c) &&((eight_bits) c<0200) ) 
+#define xisupper(c) (isupper((eight_bits) c) &&((eight_bits) c<0200) )  \
 
 #define max_include_depth 10 \
 
@@ -61,7 +98,7 @@
 #define web_file_name file_name[0] \
 
 #define lines_dont_match (change_limit-change_buffer!=limit-buffer|| \
-strncmp(buffer,change_buffer,limit-buffer) )  \
+strncmp(buffer,change_buffer,(size_t) (limit-buffer) ) )  \
 
 #define if_section_start_make_pending(b) {*limit= '!'; \
 for(loc= buffer;xisspace(*loc) ;loc++) ; \
@@ -73,16 +110,14 @@ if(*loc=='@'&&(xisspace(*(loc+1) ) ||*(loc+1) =='*') ) change_pending= b; \
  \
 
 #define too_long() {include_depth--; \
-err_print("! Include file name too long") ;goto restart;} \
-
-#define kpse_find_cweb(name) kpse_find_file(name,kpse_cweb_format,true)  \
+err_print(_("! Include file name too long") ) ;goto restart;} \
 
 #define max_bytes 1000000 \
 
 #define max_names 10239 \
  \
 
-#define length(c) (c+1) ->byte_start-(c) ->byte_start
+#define length(c) (size_t) ((c+1) ->byte_start-(c) ->byte_start) 
 #define print_id(c) term_write((c) ->byte_start,length((c) ) )  \
 
 #define hash_size 8501 \
@@ -113,16 +148,21 @@ err_print("! Include file name too long") ;goto restart;} \
 #define mark_harmless {if(history==spotless) history= harmless_message;}
 #define mark_error history= error_message \
 
-#define confusion(s) fatal("! This can't happen: ",s)  \
+#define RETURN_OK 0
+#define RETURN_WARN 5
+#define RETURN_ERROR 10
+#define RETURN_FAIL 20 \
+
+#define confusion(s) fatal(_("! This can't happen: ") ,s)  \
  \
 
 #define show_banner flags['b']
 #define show_progress flags['p']
 #define show_stats flags['s']
 #define show_happiness flags['h']
-#define show_kpathsea_debug flags['d'] \
- \
+#define make_xrefs flags['x'] \
 
+#define flag_change (**argv!='-') 
 #define update_terminal fflush(stdout)  \
 
 #define new_line putchar('\n') 
@@ -131,8 +171,15 @@ err_print("! Include file name too long") ;goto restart;} \
 #define C_printf(c,a) fprintf(C_file,c,a) 
 #define C_putc(c) putc(c,C_file)  \
 
-#define ctangle_banner "This is CTANGLE, Version 3.64"
-#define cweave_banner "This is CWEAVE, Version 3.64" \
+#define max_banner 50 \
+
+#define PATH_SEPARATOR separators[0]
+#define DIR_SEPARATOR separators[1]
+#define DEVICE_SEPARATOR separators[2] \
+
+#define _(STRING) gettext(STRING)  \
+
+#define kpse_find_cweb(name) kpse_find_file(name,kpse_cweb_format,true)  \
 
 
 #line 60 "cwebdir/common.w"
@@ -140,8 +187,9 @@ err_print("! Include file name too long") ;goto restart;} \
 /*2:*/
 #line 73 "cwebdir/common.w"
 
-#line 75 "cwebdir/common.w"
-boolean program;
+#line 56 "cwebdir/comm-w2c.ch"
+int program;
+#line 76 "cwebdir/common.w"
 
 /*:2*//*7:*/
 #line 159 "cwebdir/common.w"
@@ -171,24 +219,27 @@ boolean web_file_open= 0;
 /*:10*//*20:*/
 #line 418 "cwebdir/common.w"
 
-typedef unsigned short sixteen_bits;
+#line 264 "cwebdir/comm-w2c.ch"
+typedef uint8_t eight_bits;
+typedef uint16_t sixteen_bits;
+#line 420 "cwebdir/common.w"
 sixteen_bits section_count;
 boolean changed_section[max_sections];
 boolean change_pending;
 
 boolean print_where= 0;
 
-/*:20*//*29:*/
+/*:20*//*27:*/
 #line 594 "cwebdir/common.w"
 
 typedef struct name_info{
 char*byte_start;
-/*33:*/
+/*31:*/
 #line 631 "cwebdir/common.w"
 
 struct name_info*link;
 
-/*:33*//*42:*/
+/*:31*//*40:*/
 #line 730 "cwebdir/common.w"
 
 union{
@@ -197,12 +248,13 @@ struct name_info*Rlink;
 char Ilk;
 }dummy;
 
-/*:42*//*57:*/
-#line 1062 "cwebdir/common.w"
+/*:40*//*55:*/
+#line 703 "cwebdir/comm-w2c.ch"
 
-char*equiv_or_xref;
+void*equiv_or_xref;
+#line 1064 "cwebdir/common.w"
 
-/*:57*/
+/*:55*/
 #line 597 "cwebdir/common.w"
 
 }name_info;
@@ -212,13 +264,13 @@ char*byte_mem_end= byte_mem+max_bytes-1;
 name_info name_dir[max_names];
 name_pointer name_dir_end= name_dir+max_names-1;
 
-/*:29*//*31:*/
+/*:27*//*29:*/
 #line 617 "cwebdir/common.w"
 
 name_pointer name_ptr;
 char*byte_ptr;
 
-/*:31*//*34:*/
+/*:29*//*32:*/
 #line 644 "cwebdir/common.w"
 
 typedef name_pointer*hash_pointer;
@@ -226,13 +278,12 @@ name_pointer hash[hash_size];
 hash_pointer hash_end= hash+hash_size-1;
 hash_pointer h;
 
-#line 344 "cwebdir/comm-w2c.ch"
-/*:34*//*58:*/
+/*:32*//*56:*/
 #line 1082 "cwebdir/common.w"
 
 int history= spotless;
 
-/*:58*//*69:*/
+/*:56*//*67:*/
 #line 1220 "cwebdir/common.w"
 
 int argc;
@@ -240,22 +291,30 @@ char**argv;
 char C_file_name[max_file_name_length];
 char tex_file_name[max_file_name_length];
 char idx_file_name[max_file_name_length];
+#line 863 "cwebdir/comm-w2c.ch"
 char scn_file_name[max_file_name_length];
+char check_file_name[max_file_name_length];
+#line 870 "cwebdir/comm-w2c.ch"
 boolean flags[128];
+const char*use_language= "";
+#line 1228 "cwebdir/common.w"
 
-/*:69*//*79:*/
+/*:67*//*77:*/
 #line 1370 "cwebdir/common.w"
 
 FILE*C_file;
 FILE*tex_file;
 FILE*idx_file;
+#line 1056 "cwebdir/comm-w2c.ch"
 FILE*scn_file;
-#line 736 "cwebdir/comm-w2c.ch"
+FILE*check_file;
+#line 1063 "cwebdir/comm-w2c.ch"
 FILE*active_file;
 char*found_filename;
 #line 1376 "cwebdir/common.w"
 
-/*:79*/
+#line 1080 "cwebdir/comm-w2c.ch"
+/*:77*/
 #line 61 "cwebdir/common.w"
 
 /*3:*/
@@ -268,107 +327,215 @@ int phase;
 char change_buffer[buf_size];
 char*change_limit;
 
-/*:11*/
+/*:11*//*86:*/
+#line 1185 "cwebdir/comm-w2c.ch"
+
+char cb_banner[max_banner];
+string texmf_locale;
+#ifndef SEPARATORS
+#define SEPARATORS "://"
+#endif
+char separators[]= SEPARATORS;
+
+/*:86*/
 #line 62 "cwebdir/common.w"
 
-#line 37 "cwebdir/comm-w2c.ch"
-#include "cwebboot.h"
-/*55:*/
+/*33:*/
+#line 650 "cwebdir/common.w"
+
+#line 432 "cwebdir/comm-w2c.ch"
+extern boolean names_match(name_pointer,const char*,size_t,eight_bits);
+#line 652 "cwebdir/common.w"
+
+/*:33*//*38:*/
+#line 703 "cwebdir/common.w"
+
+#line 462 "cwebdir/comm-w2c.ch"
+extern void init_p(name_pointer,eight_bits);
+#line 705 "cwebdir/common.w"
+
+/*:38*//*46:*/
+#line 852 "cwebdir/common.w"
+
+#line 542 "cwebdir/comm-w2c.ch"
+extern void init_node(name_pointer);
+#line 854 "cwebdir/common.w"
+
+/*:46*//*53:*/
 #line 1017 "cwebdir/common.w"
 
-#line 518 "cwebdir/comm-w2c.ch"
+#line 668 "cwebdir/comm-w2c.ch"
 static int section_name_cmp(char**,int,name_pointer);
 #line 1019 "cwebdir/common.w"
 
-/*:55*//*71:*/
+/*:53*//*57:*/
+#line 1092 "cwebdir/common.w"
+
+#line 710 "cwebdir/comm-w2c.ch"
+extern void err_print(const char*);
+#line 1094 "cwebdir/common.w"
+
+/*:57*//*60:*/
+#line 1140 "cwebdir/common.w"
+
+#line 737 "cwebdir/comm-w2c.ch"
+extern int wrap_up(void);
+extern void print_stats(void);
+#line 1143 "cwebdir/common.w"
+
+#line 748 "cwebdir/comm-w2c.ch"
+/*:60*//*63:*/
+#line 1173 "cwebdir/common.w"
+
+#line 811 "cwebdir/comm-w2c.ch"
+extern void fatal(const char*,const char*);
+extern void overflow(const char*);
+#line 1175 "cwebdir/common.w"
+
+/*:63*//*69:*/
 #line 1251 "cwebdir/common.w"
 
-#line 653 "cwebdir/comm-w2c.ch"
+#line 891 "cwebdir/comm-w2c.ch"
 static void scan_args(void);
 #line 1253 "cwebdir/common.w"
 
-/*:71*/
-#line 38 "cwebdir/comm-w2c.ch"
+/*:69*//*83:*/
+#line 1145 "cwebdir/comm-w2c.ch"
+
+boolean get_line(void);
+name_pointer id_lookup(const char*,const char*,char);
+name_pointer section_lookup(char*,char*,int);
+void check_complete(void);
+void common_init(void);
+void print_prefix_name(name_pointer);
+void print_section_name(name_pointer);
+void reset_input(void);
+void sprint_section_name(char*,name_pointer);
+
+/*:83*//*84:*/
+#line 1158 "cwebdir/comm-w2c.ch"
+
+static boolean input_ln(FILE*);
+static int web_strcmp(char*,int,char*,int);
+static name_pointer add_section_name(name_pointer,int,char*,char*,int);
+static void extend_section_name(name_pointer,char*,char*,int);
+static void check_change(void);
+static void prime_the_change_buffer(void);
+
+/*:84*//*98:*/
+#line 1402 "cwebdir/comm-w2c.ch"
+
+static void cb_usage(const_string str);
+static void cb_usagehelp(const_string*message,const_string bug_email);
+void cb_show_banner(void);
+
+/*:98*/
+#line 63 "cwebdir/common.w"
 
-#line 64 "cwebdir/common.w"
 
 /*:1*//*4:*/
 #line 89 "cwebdir/common.w"
 
+#line 63 "cwebdir/comm-w2c.ch"
 void
-#line 58 "cwebdir/comm-w2c.ch"
- common_init(void)
+common_init(void)
 #line 92 "cwebdir/common.w"
 {
-#line 64 "cwebdir/comm-w2c.ch"
-/*32:*/
+#line 72 "cwebdir/comm-w2c.ch"
+/*30:*/
 #line 621 "cwebdir/common.w"
 
 name_dir->byte_start= byte_ptr= byte_mem;
 name_ptr= name_dir+1;
 name_ptr->byte_start= byte_mem;
 
-/*:32*//*36:*/
+/*:30*//*34:*/
 #line 655 "cwebdir/common.w"
 
 for(h= hash;h<=hash_end;*h++= NULL);
 
-/*:36*//*43:*/
+/*:34*//*41:*/
 #line 737 "cwebdir/common.w"
 
 root= NULL;
 
-/*:43*/
-#line 64 "cwebdir/comm-w2c.ch"
-;
-/*24:*/
-#line 247 "cwebdir/comm-w2c.ch"
+/*:41*/
+#line 72 "cwebdir/comm-w2c.ch"
+
+/*91:*/
+#line 1316 "cwebdir/comm-w2c.ch"
 
 kpse_set_program_name(argv[0],"cweb");
-#line 473 "cwebdir/common.w"
 
-/*:24*/
-#line 65 "cwebdir/comm-w2c.ch"
-;
-#line 94 "cwebdir/common.w"
-/*70:*/
+/*:91*/
+#line 73 "cwebdir/comm-w2c.ch"
+
+/*89:*/
+#line 1267 "cwebdir/comm-w2c.ch"
+
+setlocale(LC_MESSAGES,setlocale(LC_CTYPE,""));
+texmf_locale= kpse_var_expand("${TEXMFLOCALEDIR}");
+
+bindtextdomain("cweb",
+bindtextdomain("cweb-tl",
+bindtextdomain("web2c-help",
+strcmp(texmf_locale,"")?
+texmf_locale:"/usr/share/locale")));
+
+free(texmf_locale);
+textdomain("cweb");
+
+
+/*:89*/
+#line 74 "cwebdir/comm-w2c.ch"
+
+/*68:*/
 #line 1233 "cwebdir/common.w"
 
-#line 645 "cwebdir/comm-w2c.ch"
-show_banner= show_happiness= show_progress= 1;
 #line 1235 "cwebdir/common.w"
 
-/*:70*/
-#line 94 "cwebdir/common.w"
-;
-/*80:*/
-#line 1377 "cwebdir/common.w"
+/*:68*/
+#line 75 "cwebdir/comm-w2c.ch"
+
+/*78:*/
+#line 1080 "cwebdir/comm-w2c.ch"
 
 scan_args();
 if(program==ctangle){
-#line 745 "cwebdir/comm-w2c.ch"
-if((C_file= fopen(C_file_name,"wb"))==NULL)
-#line 1381 "cwebdir/common.w"
-fatal("! Cannot open output file ",C_file_name);
+strcpy(check_file_name,C_file_name);
+if(check_file_name[0]!='\0'){
+char*dot_pos= strrchr(check_file_name,'.');
+if(dot_pos==NULL)strcat(check_file_name,".ttp");
+else strcpy(dot_pos,".ttp");
+}
+if((C_file= fopen(check_file_name,"wb"))==NULL)
+fatal(_("! Cannot open output file "),check_file_name);
 
 }
 else{
-#line 751 "cwebdir/comm-w2c.ch"
-if((tex_file= fopen(tex_file_name,"wb"))==NULL)
-#line 1386 "cwebdir/common.w"
-fatal("! Cannot open output file ",tex_file_name);
+strcpy(check_file_name,tex_file_name);
+if(check_file_name[0]!='\0'){
+char*dot_pos= strrchr(check_file_name,'.');
+if(dot_pos==NULL)strcat(check_file_name,".wtp");
+else strcpy(dot_pos,".wtp");
+}
+if((tex_file= fopen(check_file_name,"wb"))==NULL)
+fatal(_("! Cannot open output file "),check_file_name);
 }
+#line 1388 "cwebdir/common.w"
 
-/*:80*/
-#line 95 "cwebdir/common.w"
-;
+/*:78*/
+#line 76 "cwebdir/comm-w2c.ch"
+
+#line 96 "cwebdir/common.w"
 }
 
 /*:4*//*9:*/
 #line 172 "cwebdir/common.w"
 
-#line 100 "cwebdir/comm-w2c.ch"
-int input_ln(FILE*fp)
+#line 103 "cwebdir/comm-w2c.ch"
+static boolean input_ln(
+FILE*fp)
 #line 175 "cwebdir/common.w"
 {
 register int c= EOF;
@@ -376,12 +543,14 @@ register char*k;
 if(feof(fp))return(0);
 limit= k= buffer;
 while(k<=buffer_end&&(c= getc(fp))!=EOF&&c!='\n')
-#line 106 "cwebdir/comm-w2c.ch"
+#line 110 "cwebdir/comm-w2c.ch"
 if((*(k++)= c)!=' '&&c!='\r')limit= k;
 #line 182 "cwebdir/common.w"
 if(k> buffer_end)
 if((c= getc(fp))!=EOF&&c!='\n'){
-ungetc(c,fp);loc= buffer;err_print("! Input line too long");
+#line 116 "cwebdir/comm-w2c.ch"
+ungetc(c,fp);loc= buffer;err_print(_("! Input line too long"));
+#line 185 "cwebdir/common.w"
 
 }
 if(c==EOF&&limit==buffer)return(0);
@@ -392,7 +561,7 @@ return(1);
 /*:9*//*12:*/
 #line 251 "cwebdir/common.w"
 
-#line 128 "cwebdir/comm-w2c.ch"
+#line 142 "cwebdir/comm-w2c.ch"
 static void
 prime_the_change_buffer(void)
 #line 254 "cwebdir/common.w"
@@ -406,13 +575,15 @@ change_line++;
 if(!input_ln(change_file))return;
 if(limit<buffer+2)continue;
 if(buffer[0]!='@')continue;
-#line 135 "cwebdir/comm-w2c.ch"
-if(xisupper(buffer[1]))buffer[1]= tolower((unsigned char)buffer[1]);
+#line 149 "cwebdir/comm-w2c.ch"
+if(xisupper(buffer[1]))buffer[1]= tolower((eight_bits)buffer[1]);
 #line 272 "cwebdir/common.w"
 if(buffer[1]=='x')break;
 if(buffer[1]=='y'||buffer[1]=='z'||buffer[1]=='i'){
 loc= buffer+2;
-err_print("! Missing @x in change file");
+#line 155 "cwebdir/comm-w2c.ch"
+err_print(_("! Missing @x in change file"));
+#line 276 "cwebdir/common.w"
 
 }
 }
@@ -426,7 +597,9 @@ err_print("! Missing @x in change file");
 do{
 change_line++;
 if(!input_ln(change_file)){
-err_print("! Change file ended after @x");
+#line 161 "cwebdir/comm-w2c.ch"
+err_print(_("! Change file ended after @x"));
+#line 287 "cwebdir/common.w"
 
 return;
 }
@@ -439,8 +612,10 @@ return;
 #line 292 "cwebdir/common.w"
 
 {
-change_limit= change_buffer+(limit-buffer);
-strncpy(change_buffer,buffer,limit-buffer+1);
+#line 168 "cwebdir/comm-w2c.ch"
+change_limit= change_buffer+(ptrdiff_t)(limit-buffer);
+strncpy(change_buffer,buffer,(size_t)(limit-buffer+1));
+#line 296 "cwebdir/common.w"
 }
 
 /*:15*/
@@ -451,7 +626,7 @@ strncpy(change_buffer,buffer,limit-buffer+1);
 /*:12*//*16:*/
 #line 320 "cwebdir/common.w"
 
-#line 144 "cwebdir/comm-w2c.ch"
+#line 176 "cwebdir/comm-w2c.ch"
 static void
 check_change(void)
 #line 323 "cwebdir/common.w"
@@ -466,27 +641,33 @@ if(!change_pending)changed_section[section_count]= 1;
 while(1){
 changing= 1;print_where= 1;change_line++;
 if(!input_ln(change_file)){
-err_print("! Change file ended before @y");
+#line 183 "cwebdir/comm-w2c.ch"
+err_print(_("! Change file ended before @y"));
+#line 335 "cwebdir/common.w"
 
 change_limit= change_buffer;changing= 0;
 return;
 }
 if(limit> buffer+1&&buffer[0]=='@'){
-#line 151 "cwebdir/comm-w2c.ch"
-char xyz_code= xisupper(buffer[1])?tolower((unsigned char)buffer[1]):buffer[1];
+#line 189 "cwebdir/comm-w2c.ch"
+char xyz_code= xisupper(buffer[1])?tolower((eight_bits)buffer[1]):buffer[1];
 #line 341 "cwebdir/common.w"
 /*17:*/
 #line 358 "cwebdir/common.w"
 
 if(xyz_code=='x'||xyz_code=='z'){
-loc= buffer+2;err_print("! Where is the matching @y?");
+#line 201 "cwebdir/comm-w2c.ch"
+loc= buffer+2;err_print(_("! Where is the matching @y?"));
+#line 361 "cwebdir/common.w"
 
 }
 else if(xyz_code=='y'){
 if(n> 0){
 loc= buffer+2;
 printf("\n! Hmm... %d ",n);
-err_print("of the preceding lines failed to match");
+#line 207 "cwebdir/comm-w2c.ch"
+err_print(_("of the preceding lines failed to match"));
+#line 368 "cwebdir/common.w"
 
 }
 change_depth= include_depth;
@@ -501,8 +682,10 @@ return;
 #line 292 "cwebdir/common.w"
 
 {
-change_limit= change_buffer+(limit-buffer);
-strncpy(change_buffer,buffer,limit-buffer+1);
+#line 168 "cwebdir/comm-w2c.ch"
+change_limit= change_buffer+(ptrdiff_t)(limit-buffer);
+strncpy(change_buffer,buffer,(size_t)(limit-buffer+1));
+#line 296 "cwebdir/common.w"
 }
 
 /*:15*/
@@ -511,7 +694,9 @@ strncpy(change_buffer,buffer,limit-buffer+1);
 changing= 0;cur_line++;
 while(!input_ln(cur_file)){
 if(include_depth==0){
-err_print("! CWEB file ended during a change");
+#line 195 "cwebdir/comm-w2c.ch"
+err_print(_("! CWEB file ended during a change"));
+#line 349 "cwebdir/common.w"
 
 input_has_ended= 1;return;
 }
@@ -524,35 +709,41 @@ if(lines_dont_match)n++;
 /*:16*//*18:*/
 #line 378 "cwebdir/common.w"
 
+#line 214 "cwebdir/comm-w2c.ch"
 void
-#line 159 "cwebdir/comm-w2c.ch"
- reset_input(void)
+reset_input(void)
 #line 381 "cwebdir/common.w"
 {
 limit= buffer;loc= buffer+1;buffer[0]= ' ';
 /*19:*/
 #line 393 "cwebdir/common.w"
 
-#line 171 "cwebdir/comm-w2c.ch"
+#line 225 "cwebdir/comm-w2c.ch"
 if((found_filename= kpse_find_cweb(web_file_name))==NULL||
 (web_file= fopen(found_filename,"r"))==NULL){
-fatal("! Cannot open input file ",web_file_name);
+fatal(_("! Cannot open input file "),web_file_name);
 }else if(strlen(found_filename)<max_file_name_length){
-strcpy(web_file_name,found_filename);
+
+if(strcmp(web_file_name,found_filename))
+strcpy(web_file_name,found_filename+
+((strncmp(found_filename,"./",2)==0)?2:0));
 free(found_filename);
-}
+}else fatal(_("! Filename too long\n"),found_filename);
 #line 399 "cwebdir/common.w"
 
 
 web_file_open= 1;
-#line 184 "cwebdir/comm-w2c.ch"
+#line 241 "cwebdir/comm-w2c.ch"
 if((found_filename= kpse_find_cweb(change_file_name))==NULL||
 (change_file= fopen(found_filename,"r"))==NULL){
-fatal("! Cannot open change file ",change_file_name);
+fatal(_("! Cannot open change file "),change_file_name);
 }else if(strlen(found_filename)<max_file_name_length){
-strcpy(change_file_name,found_filename);
+
+if(strcmp(change_file_name,found_filename))
+strcpy(change_file_name,found_filename+
+((strncmp(found_filename,"./",2)==0)?2:0));
 free(found_filename);
-}
+}else fatal(_("! Filename too long\n"),found_filename);
 #line 404 "cwebdir/common.w"
 
 /*:19*/
@@ -567,18 +758,20 @@ limit= buffer;loc= buffer+1;buffer[0]= ' ';input_has_ended= 0;
 /*:18*//*21:*/
 #line 426 "cwebdir/common.w"
 
-#line 204 "cwebdir/comm-w2c.ch"
-int get_line(void)
+#line 271 "cwebdir/comm-w2c.ch"
+boolean get_line(void)
 #line 428 "cwebdir/common.w"
 {
 restart:
 if(changing&&include_depth==change_depth)
-/*27:*/
+/*25:*/
 #line 537 "cwebdir/common.w"
 {
 change_line++;
 if(!input_ln(change_file)){
-err_print("! Change file ended without @z");
+#line 370 "cwebdir/comm-w2c.ch"
+err_print(_("! Change file ended without @z"));
+#line 541 "cwebdir/common.w"
 
 buffer[0]= '@';buffer[1]= 'z';limit= buffer+2;
 }
@@ -591,12 +784,14 @@ changed_section[section_count]= 1;change_pending= 0;
 }
 *limit= ' ';
 if(buffer[0]=='@'){
-#line 311 "cwebdir/comm-w2c.ch"
-if(xisupper(buffer[1]))buffer[1]= tolower((unsigned char)buffer[1]);
+#line 376 "cwebdir/comm-w2c.ch"
+if(xisupper(buffer[1]))buffer[1]= tolower((eight_bits)buffer[1]);
 #line 554 "cwebdir/common.w"
 if(buffer[1]=='x'||buffer[1]=='y'){
 loc= buffer+2;
-err_print("! Where is the matching @z?");
+#line 382 "cwebdir/comm-w2c.ch"
+err_print(_("! Where is the matching @z?"));
+#line 557 "cwebdir/common.w"
 
 }
 else if(buffer[1]=='z'){
@@ -606,11 +801,11 @@ prime_the_change_buffer();changing= !changing;print_where= 1;
 }
 }
 
-/*:27*/
+/*:25*/
 #line 431 "cwebdir/common.w"
 ;
 if(!changing||include_depth> change_depth){
-/*26:*/
+/*24:*/
 #line 520 "cwebdir/common.w"
 {
 cur_line++;
@@ -629,7 +824,7 @@ if(buffer[0]==change_buffer[0])
 if(change_limit> change_buffer)check_change();
 }
 
-/*:26*/
+/*:24*/
 #line 433 "cwebdir/common.w"
 ;
 if(changing&&include_depth==change_depth)goto restart;
@@ -640,20 +835,24 @@ if(buffer[0]=='@'&&(buffer[1]=='i'||buffer[1]=='I')){
 loc= buffer+2;*limit= '"';
 while(*loc==' '||*loc=='\t')loc++;
 if(loc>=limit){
-err_print("! Include file name not given");
+#line 277 "cwebdir/comm-w2c.ch"
+err_print(_("! Include file name not given"));
+#line 443 "cwebdir/common.w"
 
 goto restart;
 }
 if(include_depth>=max_include_depth-1){
-err_print("! Too many nested includes");
+#line 283 "cwebdir/comm-w2c.ch"
+err_print(_("! Too many nested includes"));
+#line 448 "cwebdir/common.w"
 
 goto restart;
 }
 include_depth++;
-/*25:*/
+/*23:*/
 #line 474 "cwebdir/common.w"
 {
-#line 260 "cwebdir/comm-w2c.ch"
+#line 319 "cwebdir/comm-w2c.ch"
 char*cur_file_name_end= cur_file_name+max_file_name_length-1;
 char*k= cur_file_name;
 #line 479 "cwebdir/common.w"
@@ -667,114 +866,120 @@ while(*loc!=' '&&*loc!='\t'&&*loc!='"'&&k<=cur_file_name_end)*k++= *loc++;
 if(k> cur_file_name_end)too_long();
 
 *k= '\0';
-#line 267 "cwebdir/comm-w2c.ch"
+#line 326 "cwebdir/comm-w2c.ch"
 if((found_filename= kpse_find_cweb(cur_file_name))!=NULL&&
 (cur_file= fopen(found_filename,"r"))!=NULL){
 
 if(strlen(found_filename)<max_file_name_length){
-strcpy(cur_file_name,found_filename);
+if(strcmp(cur_file_name,found_filename))
+strcpy(cur_file_name,found_filename+
+((strncmp(found_filename,"./",2)==0)?2:0));
 free(found_filename);
-}
+}else fatal(_("! Filename too long\n"),found_filename);
 #line 490 "cwebdir/common.w"
 cur_line= 0;print_where= 1;
 goto restart;
 }
-#line 517 "cwebdir/common.w"
-include_depth--;err_print("! Cannot open include file");goto restart;
+#line 364 "cwebdir/comm-w2c.ch"
+include_depth--;err_print(_("! Cannot open include file"));goto restart;
+#line 518 "cwebdir/common.w"
 }
 
-/*:25*/
+/*:23*/
 #line 452 "cwebdir/common.w"
 ;
 }
 return 1;
 }
 
-/*:21*//*28:*/
+#line 298 "cwebdir/comm-w2c.ch"
+/*:21*//*26:*/
 #line 569 "cwebdir/common.w"
 
+#line 392 "cwebdir/comm-w2c.ch"
 void
-#line 317 "cwebdir/comm-w2c.ch"
- check_complete(void){
-#line 572 "cwebdir/common.w"
+check_complete(void){
 if(change_limit!=change_buffer){
-strncpy(buffer,change_buffer,change_limit-change_buffer+1);
-limit= buffer+(int)(change_limit-change_buffer);
+strncpy(buffer,change_buffer,(size_t)(change_limit-change_buffer+1));
+limit= buffer+(ptrdiff_t)(change_limit-change_buffer);
+#line 575 "cwebdir/common.w"
 changing= 1;change_depth= include_depth;loc= buffer;
-err_print("! Change file entry did not match");
+#line 402 "cwebdir/comm-w2c.ch"
+err_print(_("! Change file entry did not match"));
+#line 577 "cwebdir/common.w"
 
 }
 }
 
-/*:28*//*37:*/
+/*:26*//*35:*/
 #line 660 "cwebdir/common.w"
 
+#line 444 "cwebdir/comm-w2c.ch"
 name_pointer
-#line 356 "cwebdir/comm-w2c.ch"
-
-id_lookup(const char*first,const char*last,char t)
-#line 666 "cwebdir/common.w"
+id_lookup(
+const char*first,
+const char*last,
+char t)
 {
-#line 363 "cwebdir/comm-w2c.ch"
 const char*i= first;
-#line 369 "cwebdir/comm-w2c.ch"
+#line 668 "cwebdir/common.w"
 int h;
-#line 669 "cwebdir/common.w"
 int l;
 name_pointer p;
 if(last==NULL)for(last= first;*last!='\0';last++);
-l= last-first;
-/*38:*/
+#line 456 "cwebdir/comm-w2c.ch"
+l= (int)(last-first);
+#line 673 "cwebdir/common.w"
+/*36:*/
 #line 683 "cwebdir/common.w"
 
-#line 378 "cwebdir/comm-w2c.ch"
 h= (unsigned char)*i;
 while(++i<last)h= (h+h+(int)((unsigned char)*i))%hash_size;
-#line 686 "cwebdir/common.w"
 
 
-/*:38*/
+/*:36*/
 #line 673 "cwebdir/common.w"
 ;
-/*39:*/
+/*37:*/
 #line 691 "cwebdir/common.w"
 
-#line 387 "cwebdir/comm-w2c.ch"
 p= hash[h];
-#line 693 "cwebdir/common.w"
 while(p&&!names_match(p,first,l,t))p= p->link;
 if(p==NULL){
 p= name_ptr;
-#line 393 "cwebdir/comm-w2c.ch"
 p->link= hash[h];hash[h]= p;
-#line 697 "cwebdir/common.w"
 }
 
-/*:39*/
+/*:37*/
 #line 674 "cwebdir/common.w"
 ;
-if(p==name_ptr)/*41:*/
+if(p==name_ptr)/*39:*/
 #line 706 "cwebdir/common.w"
 {
-if(byte_ptr+l> byte_mem_end)overflow("byte memory");
-if(name_ptr>=name_dir_end)overflow("name");
+#line 469 "cwebdir/comm-w2c.ch"
+if(byte_ptr+l> byte_mem_end)overflow(_("byte memory"));
+if(name_ptr>=name_dir_end)overflow(_("name"));
+#line 709 "cwebdir/common.w"
 strncpy(byte_ptr,first,l);
 (++name_ptr)->byte_start= byte_ptr+= l;
-if(program==cweave)init_p(p,t);
+#line 476 "cwebdir/comm-w2c.ch"
+init_p(p,t);
+#line 712 "cwebdir/common.w"
 }
 
-/*:41*/
+/*:39*/
 #line 675 "cwebdir/common.w"
 ;
 return(p);
 }
 
-/*:37*//*44:*/
+/*:35*//*42:*/
 #line 764 "cwebdir/common.w"
 
+#line 484 "cwebdir/comm-w2c.ch"
 void
-#line 412 "cwebdir/comm-w2c.ch"
- print_section_name(name_pointer p)
+print_section_name(
+name_pointer p)
 #line 768 "cwebdir/common.w"
 {
 char*ss,*s= first_chunk(p);
@@ -782,21 +987,25 @@ name_pointer q= p+1;
 while(p!=name_dir){
 ss= (p+1)->byte_start-1;
 if(*ss==' '&&ss>=s){
-term_write(s,ss-s);p= q->link;q= p;
+#line 494 "cwebdir/comm-w2c.ch"
+term_write(s,(size_t)(ss-s));p= q->link;q= p;
 }else{
-term_write(s,ss+1-s);p= name_dir;q= NULL;
+term_write(s,(size_t)(ss+1-s));p= name_dir;q= NULL;
+#line 777 "cwebdir/common.w"
 }
 s= p->byte_start;
 }
 if(q)term_write("...",3);
 }
 
-/*:44*//*45:*/
+/*:42*//*43:*/
 #line 783 "cwebdir/common.w"
 
+#line 505 "cwebdir/comm-w2c.ch"
 void
-#line 422 "cwebdir/comm-w2c.ch"
- sprint_section_name(char*dest,name_pointer p)
+sprint_section_name(
+char*dest,
+name_pointer p)
 #line 788 "cwebdir/common.w"
 {
 char*ss,*s= first_chunk(p);
@@ -808,18 +1017,21 @@ p= q->link;q= p;
 }else{
 ss++;p= name_dir;
 }
-strncpy(dest,s,ss-s),dest+= ss-s;
+#line 514 "cwebdir/comm-w2c.ch"
+strncpy(dest,s,(size_t)(ss-s)),dest+= ss-s;
+#line 799 "cwebdir/common.w"
 s= p->byte_start;
 }
 *dest= '\0';
 }
 
-/*:45*//*46:*/
+/*:43*//*44:*/
 #line 804 "cwebdir/common.w"
 
-#line 432 "cwebdir/comm-w2c.ch"
-static void
-print_prefix_name(name_pointer p)
+#line 522 "cwebdir/comm-w2c.ch"
+void
+print_prefix_name(
+name_pointer p)
 #line 808 "cwebdir/common.w"
 {
 char*s= first_chunk(p);
@@ -828,40 +1040,47 @@ term_write(s,l);
 if(s+l<(p+1)->byte_start)term_write("...",3);
 }
 
-/*:46*//*47:*/
+/*:44*//*45:*/
 #line 825 "cwebdir/common.w"
 
-#line 443 "cwebdir/comm-w2c.ch"
-
-static int
-web_strcmp(char*j,int j_len,char*k,int k_len)
+#line 532 "cwebdir/comm-w2c.ch"
+static int web_strcmp(
+char*j,
+int j_len,
+char*k,
+int k_len)
 #line 829 "cwebdir/common.w"
 {
-#line 455 "cwebdir/comm-w2c.ch"
 char*j1= j+j_len,*k1= k+k_len;
 while(k<k1&&j<j1&&*j==*k)k++,j++;
 if(k==k1)if(j==j1)return equal;
 else return extension;
 else if(j==j1)return prefix;
-#line 835 "cwebdir/common.w"
 else if(*j<*k)return less;
 else return greater;
 }
 
-/*:47*//*49:*/
+/*:45*//*47:*/
 #line 855 "cwebdir/common.w"
 
-#line 483 "cwebdir/comm-w2c.ch"
+#line 554 "cwebdir/comm-w2c.ch"
 static name_pointer
-add_section_name(name_pointer par,int c,char*first,char*last,
+add_section_name(
+name_pointer par,
+int c,
+char*first,
+char*last,
 int ispref)
 #line 863 "cwebdir/common.w"
 {
 name_pointer p= name_ptr;
 char*s= first_chunk(p);
-int name_len= last-first+ispref;
-if(s+name_len> byte_mem_end)overflow("byte memory");
-if(name_ptr+1>=name_dir_end)overflow("name");
+#line 566 "cwebdir/comm-w2c.ch"
+int name_len= (int)(last-first)+ispref;
+#line 573 "cwebdir/comm-w2c.ch"
+if(s+name_len> byte_mem_end)overflow(_("byte memory"));
+if(name_ptr+1>=name_dir_end)overflow(_("name"));
+#line 869 "cwebdir/common.w"
 (++name_ptr)->byte_start= byte_ptr= s+name_len;
 if(ispref){
 *(byte_ptr-1)= ' ';
@@ -877,35 +1096,45 @@ init_node(p);
 return par==NULL?(root= p):c==less?(par->llink= p):(par->rlink= p);
 }
 
-/*:49*//*50:*/
+/*:47*//*48:*/
 #line 884 "cwebdir/common.w"
 
-#line 498 "cwebdir/comm-w2c.ch"
+#line 585 "cwebdir/comm-w2c.ch"
 static void
-extend_section_name(name_pointer p,char*first,char*last,int ispref)
+extend_section_name(
+name_pointer p,
+char*first,
+char*last,
+int ispref)
 #line 891 "cwebdir/common.w"
 {
 char*s;
 name_pointer q= p+1;
-int name_len= last-first+ispref;
-if(name_ptr>=name_dir_end)overflow("name");
+#line 596 "cwebdir/comm-w2c.ch"
+int name_len= (int)(last-first)+ispref;
+#line 602 "cwebdir/comm-w2c.ch"
+if(name_ptr>=name_dir_end)overflow(_("name"));
+#line 896 "cwebdir/common.w"
 while(q->link!=name_dir)q= q->link;
 q->link= name_ptr;
 s= name_ptr->byte_start;
 name_ptr->link= name_dir;
-if(s+name_len> byte_mem_end)overflow("byte memory");
+#line 608 "cwebdir/comm-w2c.ch"
+if(s+name_len> byte_mem_end)overflow(_("byte memory"));
+#line 901 "cwebdir/common.w"
 (++name_ptr)->byte_start= byte_ptr= s+name_len;
 strncpy(s,first,name_len);
 if(ispref)*(byte_ptr-1)= ' ';
 }
 
-/*:50*//*51:*/
+/*:48*//*49:*/
 #line 912 "cwebdir/common.w"
 
+#line 617 "cwebdir/comm-w2c.ch"
 name_pointer
-#line 509 "cwebdir/comm-w2c.ch"
-
-section_lookup(char*first,char*last,int ispref)
+section_lookup(
+char*first,char*last,
+int ispref)
 #line 917 "cwebdir/common.w"
 {
 int c= 0;
@@ -914,8 +1143,10 @@ name_pointer q= NULL;
 name_pointer r= NULL;
 name_pointer par= NULL;
 
-int name_len= last-first+1;
-/*52:*/
+#line 626 "cwebdir/comm-w2c.ch"
+int name_len= (int)(last-first)+1;
+#line 925 "cwebdir/common.w"
+/*50:*/
 #line 936 "cwebdir/common.w"
 
 while(p){
@@ -926,10 +1157,14 @@ par= p;
 p= (c==less?p->llink:p->rlink);
 }else{
 if(r!=NULL){
-printf("\n! Ambiguous prefix: matches <");
+#line 632 "cwebdir/comm-w2c.ch"
+fputs(_("\n! Ambiguous prefix: matches <"),stdout);
+#line 946 "cwebdir/common.w"
 
 print_prefix_name(p);
-printf(">\n and <");
+#line 638 "cwebdir/comm-w2c.ch"
+fputs(_(">\n and <"),stdout);
+#line 949 "cwebdir/common.w"
 print_prefix_name(r);
 err_print(">");
 return name_dir;
@@ -942,26 +1177,28 @@ if(p==NULL)
 p= q,q= NULL;
 }
 
-/*:52*/
+/*:50*/
 #line 926 "cwebdir/common.w"
 ;
-/*53:*/
+/*51:*/
 #line 961 "cwebdir/common.w"
 
 if(r==NULL)
 return add_section_name(par,c,first,last+1,ispref);
 
-/*:53*/
+/*:51*/
 #line 927 "cwebdir/common.w"
 ;
-/*54:*/
+/*52:*/
 #line 969 "cwebdir/common.w"
 
 switch(section_name_cmp(&first,name_len,r)){
 
 case prefix:
 if(!ispref){
-printf("\n! New name is a prefix of <");
+#line 644 "cwebdir/comm-w2c.ch"
+fputs(_("\n! New name is a prefix of <"),stdout);
+#line 975 "cwebdir/common.w"
 
 print_section_name(r);
 err_print(">");
@@ -973,32 +1210,40 @@ case extension:if(!ispref||first<=last)
 extend_section_name(r,first,last+1,ispref);
 return r;
 case bad_extension:
-printf("\n! New name extends <");
+#line 650 "cwebdir/comm-w2c.ch"
+fputs(_("\n! New name extends <"),stdout);
+#line 987 "cwebdir/common.w"
 
 print_section_name(r);
 err_print(">");
 return r;
 default:
-printf("\n! Section name incompatible with <");
+#line 656 "cwebdir/comm-w2c.ch"
+fputs(_("\n! Section name incompatible with <"),stdout);
+#line 993 "cwebdir/common.w"
 
 print_prefix_name(r);
-printf(">,\n which abbreviates <");
+#line 662 "cwebdir/comm-w2c.ch"
+fputs(_(">,\n which abbreviates <"),stdout);
+#line 996 "cwebdir/common.w"
 print_section_name(r);
 err_print(">");
 return r;
 }
 
-/*:54*/
+/*:52*/
 #line 928 "cwebdir/common.w"
 ;
 }
 
-/*:51*//*56:*/
+/*:49*//*54:*/
 #line 1020 "cwebdir/common.w"
 
-#line 529 "cwebdir/comm-w2c.ch"
-static int
-section_name_cmp(char**pfirst,int len,name_pointer r)
+#line 677 "cwebdir/comm-w2c.ch"
+static int section_name_cmp(
+char**pfirst,
+int len,
+name_pointer r)
 #line 1025 "cwebdir/common.w"
 {
 char*first= *pfirst;
@@ -1013,37 +1258,44 @@ else ispref= 0,ss++,q= name_dir;
 switch(c= web_strcmp(first,len,s,ss-s)){
 case equal:if(q==name_dir)
 if(ispref){
-*pfirst= first+(ss-s);
+#line 686 "cwebdir/comm-w2c.ch"
+*pfirst= first+(ptrdiff_t)(ss-s);
+#line 1039 "cwebdir/common.w"
 return extension;
 }else return equal;
 else return(q->byte_start==(q+1)->byte_start)?equal:prefix;
 case extension:
 if(!ispref)return bad_extension;
 first+= ss-s;
-if(q!=name_dir){len-= ss-s;s= q->byte_start;r= q;continue;}
+#line 692 "cwebdir/comm-w2c.ch"
+if(q!=name_dir){len-= (int)(ss-s);s= q->byte_start;r= q;continue;}
+#line 1046 "cwebdir/common.w"
 *pfirst= first;return extension;
 default:return c;
 }
 }
 }
 
-/*:56*//*60:*/
+/*:54*//*58:*/
 #line 1095 "cwebdir/common.w"
 
+#line 718 "cwebdir/comm-w2c.ch"
 void
-#line 549 "cwebdir/comm-w2c.ch"
- err_print(const char*s)
+err_print(
+const char*s)
 #line 1099 "cwebdir/common.w"
 {
 char*k,*l;
 printf(*s=='!'?"\n%s":"%s",s);
-if(web_file_open)/*61:*/
+if(web_file_open)/*59:*/
 #line 1115 "cwebdir/common.w"
 
 {if(changing&&include_depth==change_depth)
-printf(". (l. %d of change file)\n",change_line);
-else if(include_depth==0)printf(". (l. %d)\n",cur_line);
-else printf(". (l. %d of include file %s)\n",cur_line,cur_file_name);
+#line 728 "cwebdir/comm-w2c.ch"
+printf(_(". (l. %d of change file)\n"),change_line);
+else if(include_depth==0)printf(_(". (l. %d)\n"),cur_line);
+else printf(_(". (l. %d of include file %s)\n"),cur_line,cur_file_name);
+#line 1120 "cwebdir/common.w"
 l= (loc>=limit?limit:loc);
 if(l> buffer){
 for(k= buffer;k<l;k++)
@@ -1057,69 +1309,94 @@ if(*limit=='|')putchar('|');
 putchar(' ');
 }
 
-/*:61*/
+/*:59*/
 #line 1102 "cwebdir/common.w"
 ;
 update_terminal;mark_error;
 }
 
-/*:60*//*63:*/
+/*:58*//*61:*/
 #line 1150 "cwebdir/common.w"
 
-#line 569 "cwebdir/comm-w2c.ch"
+#line 767 "cwebdir/comm-w2c.ch"
 int wrap_up(void){
-#line 1152 "cwebdir/common.w"
-putchar('\n');
+if(show_progress)new_line;
+#line 1153 "cwebdir/common.w"
 if(show_stats)
 print_stats();
-/*64:*/
+#line 774 "cwebdir/comm-w2c.ch"
+/*62:*/
 #line 1160 "cwebdir/common.w"
 
 switch(history){
-case spotless:if(show_happiness)printf("(No errors were found.)\n");break;
+#line 798 "cwebdir/comm-w2c.ch"
+case spotless:
+if(show_happiness)puts(_("(No errors were found.)"));break;
 case harmless_message:
-printf("(Did you see the warning message above?)\n");break;
+puts(_("(Did you see the warning message above?)"));break;
 case error_message:
-printf("(Pardon me, but I think I spotted something wrong.)\n");break;
-case fatal_message:printf("(That was a fatal error, my friend.)\n");
+puts(_("(Pardon me, but I think I spotted something wrong.)"));break;
+case fatal_message:
+puts(_("(That was a fatal error, my friend.)"));
+#line 1168 "cwebdir/common.w"
 }
 
-/*:64*/
-#line 1155 "cwebdir/common.w"
-;
-if(history> harmless_message)return(1);
-else return(0);
+/*:62*/
+#line 774 "cwebdir/comm-w2c.ch"
+
+/*87:*/
+#line 1196 "cwebdir/comm-w2c.ch"
+
+if(C_file)fclose(C_file);
+if(tex_file)fclose(tex_file);
+if(check_file)fclose(check_file);
+if(strlen(check_file_name))
+remove(check_file_name);
+
+/*:87*/
+#line 775 "cwebdir/comm-w2c.ch"
+
+#line 782 "cwebdir/comm-w2c.ch"
+switch(history){
+case harmless_message:return RETURN_WARN;
+case error_message:return RETURN_ERROR;
+case fatal_message:return RETURN_FAIL;
+default:return RETURN_OK;
+}
+#line 1158 "cwebdir/common.w"
 }
 
-/*:63*//*66:*/
-#line 1179 "cwebdir/common.w"
+/*:61*//*64:*/
+#line 820 "cwebdir/comm-w2c.ch"
 void
-#line 589 "cwebdir/comm-w2c.ch"
- fatal(const char*s,const char*t)
+fatal(
+const char*s,const char*t)
 #line 1182 "cwebdir/common.w"
 {
-#line 595 "cwebdir/comm-w2c.ch"
-if(*s)printf("%s",s);
+#line 828 "cwebdir/comm-w2c.ch"
+if(*s)fputs(s,stdout);
 #line 1184 "cwebdir/common.w"
 err_print(t);
 history= fatal_message;exit(wrap_up());
 }
 
-/*:66*//*67:*/
-#line 1190 "cwebdir/common.w"
+/*:64*//*65:*/
+#line 836 "cwebdir/comm-w2c.ch"
 void
-#line 604 "cwebdir/comm-w2c.ch"
- overflow(const char*t)
+overflow(
+const char*t)
 #line 1193 "cwebdir/common.w"
 {
-printf("\n! Sorry, %s capacity exceeded",t);fatal("","");
+#line 844 "cwebdir/comm-w2c.ch"
+printf(_("\n! Sorry, %s capacity exceeded"),t);fatal("","");
+#line 1195 "cwebdir/common.w"
 }
 
 
-/*:67*//*72:*/
+/*:65*//*70:*/
 #line 1254 "cwebdir/common.w"
 
-#line 663 "cwebdir/comm-w2c.ch"
+#line 898 "cwebdir/comm-w2c.ch"
 static void
 scan_args(void)
 #line 1257 "cwebdir/common.w"
@@ -1129,85 +1406,115 @@ char*name_pos;
 register char*s;
 boolean found_web= 0,found_change= 0,found_out= 0;
 
-boolean flag_change;
+#line 1264 "cwebdir/common.w"
+
+#line 910 "cwebdir/comm-w2c.ch"
+
+#if defined DEV_NULL
+strncpy(change_file_name,DEV_NULL,max_file_name_length-2);
+change_file_name[max_file_name_length-2]= '\0';
+#elif defined _DEV_NULL
+strncpy(change_file_name,_DEV_NULL,max_file_name_length-2);
+change_file_name[max_file_name_length-2]= '\0';
+#else
+strcpy(change_file_name,"/dev/null");
+#endif
 
 while(--argc> 0){
-if((**(++argv)=='-'||**argv=='+')&&*(*argv+1))/*76:*/
-#line 688 "cwebdir/comm-w2c.ch"
+#line 1266 "cwebdir/common.w"
+if((**(++argv)=='-'||**argv=='+')&&*(*argv+1))/*74:*/
+#line 993 "cwebdir/comm-w2c.ch"
 
 {
 if(strcmp("-help",*argv)==0||strcmp("--help",*argv)==0)
-/*86:*/
-#line 803 "cwebdir/comm-w2c.ch"
 
-usagehelp(program==ctangle?CTANGLEHELP:CWEAVEHELP,NULL);
+/*94:*/
+#line 1341 "cwebdir/comm-w2c.ch"
 
+cb_usagehelp(program==ctangle?CTANGLEHELP:
+program==cweave?CWEAVEHELP:CTWILLHELP,NULL);
+
+
+/*:94*/
+#line 997 "cwebdir/comm-w2c.ch"
 
-/*:86*/
-#line 691 "cwebdir/comm-w2c.ch"
-;
 if(strcmp("-version",*argv)==0||strcmp("--version",*argv)==0)
-/*87:*/
-#line 812 "cwebdir/comm-w2c.ch"
 
-printversionandexit((program==ctangle?ctangle_banner:cweave_banner),
-"Silvio Levy and Donald E. Knuth",NULL,NULL);
+/*96:*/
+#line 1383 "cwebdir/comm-w2c.ch"
 
+printversionandexit(cb_banner,
+program==ctwill?"Donald E. Knuth":"Silvio Levy and Donald E. Knuth",
+NULL,NULL);
 
-/*:87*/
-#line 693 "cwebdir/comm-w2c.ch"
-;
-#line 1346 "cwebdir/common.w"
-if(**argv=='-')flag_change= 0;
-#line 699 "cwebdir/comm-w2c.ch"
-else flag_change= 1;
-if(*(*argv+1)=='d')
-if(sscanf(*argv+2,"%u",&kpathsea_debug)!=1)/*77:*/
-#line 1352 "cwebdir/common.w"
 
-{
-#line 722 "cwebdir/comm-w2c.ch"
-if(program==ctangle){
-fprintf(stderr,"ctangle: Need one to three file arguments.\n");
-usage("ctangle");
-}else{
-fprintf(stderr,"cweave: Need one to three file arguments.\n");
-usage("cweave");
-}
-#line 1362 "cwebdir/common.w"
-}
+/*:96*/
+#line 1000 "cwebdir/comm-w2c.ch"
 
-/*:77*/
-#line 701 "cwebdir/comm-w2c.ch"
-;
-#line 1348 "cwebdir/common.w"
+if(strcmp("-verbose",*argv)==0||strcmp("--verbose",*argv)==0)
+
+{show_banner= show_progress= show_happiness= 1;continue;}
+if(strcmp("-quiet",*argv)==0||strcmp("--quiet",*argv)==0)
+
+{show_banner= show_progress= show_happiness= 0;continue;}
 for(dot_pos= *argv+1;*dot_pos> '\0';dot_pos++)
-#line 707 "cwebdir/comm-w2c.ch"
-flags[(unsigned char)*dot_pos]= flag_change;
+if(*dot_pos=='v'){
+show_banner= show_progress= show_happiness= 1;
+}else
+if(*dot_pos=='q'){
+show_banner= show_progress= show_happiness= 0;
+}else
+if(*dot_pos=='d'){
+if(sscanf(++dot_pos,"%u",&kpathsea_debug)!=1)/*75:*/
+#line 1352 "cwebdir/common.w"
+
+#line 1043 "cwebdir/comm-w2c.ch"
+cb_usage(program==ctangle?"ctangle":program==cweave?"cweave":"ctwill");
+
+#line 1363 "cwebdir/common.w"
+
+#line 1050 "cwebdir/comm-w2c.ch"
+/*:75*/
+#line 1015 "cwebdir/comm-w2c.ch"
+
+while(isdigit(*dot_pos))dot_pos++;
+dot_pos--;
+}else
+if(*dot_pos=='l'){
+use_language= ++dot_pos;
+break;
+}else
+#line 1028 "cwebdir/comm-w2c.ch"
+ flags[(eight_bits)*dot_pos]= flag_change;
 #line 1350 "cwebdir/common.w"
 }
 
-/*:76*/
+/*:74*/
 #line 1266 "cwebdir/common.w"
 
 else{
 s= name_pos= *argv;dot_pos= NULL;
+#line 931 "cwebdir/comm-w2c.ch"
 while(*s){
 if(*s=='.')dot_pos= s++;
-else if(*s=='/')dot_pos= NULL,name_pos= ++s;
+else if(*s==DIR_SEPARATOR||*s==DEVICE_SEPARATOR||*s=='/')
+dot_pos= NULL,name_pos= ++s;
 else s++;
 }
-if(!found_web)/*73:*/
+
+#line 1274 "cwebdir/common.w"
+if(!found_web)/*71:*/
 #line 1292 "cwebdir/common.w"
 
 {
 if(s-*argv> max_file_name_length-5)
-/*78:*/
-#line 1364 "cwebdir/common.w"
-fatal("! Filename too long\n",*argv);
+/*76:*/
+#line 1050 "cwebdir/comm-w2c.ch"
+fatal(_("! Filename too long\n"),*argv);
+#line 1365 "cwebdir/common.w"
 
 
-/*:78*/
+/*:76*/
 #line 1295 "cwebdir/common.w"
 ;
 if(dot_pos==NULL)
@@ -1224,45 +1531,50 @@ sprintf(C_file_name,"%s.c",name_pos);
 found_web= 1;
 }
 
-/*:73*/
+/*:71*/
 #line 1275 "cwebdir/common.w"
 
-else if(!found_change)/*74:*/
+else if(!found_change)/*72:*/
 #line 1310 "cwebdir/common.w"
 
 {
-if(strcmp(*argv,"-")==0)found_change= -1;
-else{
+#line 968 "cwebdir/comm-w2c.ch"
+if(strcmp(*argv,"-")!=0){
+#line 1314 "cwebdir/common.w"
 if(s-*argv> max_file_name_length-4)
-/*78:*/
-#line 1364 "cwebdir/common.w"
-fatal("! Filename too long\n",*argv);
+/*76:*/
+#line 1050 "cwebdir/comm-w2c.ch"
+fatal(_("! Filename too long\n"),*argv);
+#line 1365 "cwebdir/common.w"
 
 
-/*:78*/
+/*:76*/
 #line 1315 "cwebdir/common.w"
 ;
 if(dot_pos==NULL)
 sprintf(change_file_name,"%s.ch",*argv);
 else strcpy(change_file_name,*argv);
-found_change= 1;
+#line 975 "cwebdir/comm-w2c.ch"
 }
+found_change= 1;
+#line 1321 "cwebdir/common.w"
 }
 
-/*:74*/
+/*:72*/
 #line 1276 "cwebdir/common.w"
 
-else if(!found_out)/*75:*/
+else if(!found_out)/*73:*/
 #line 1323 "cwebdir/common.w"
 
 {
 if(s-*argv> max_file_name_length-5)
-/*78:*/
-#line 1364 "cwebdir/common.w"
-fatal("! Filename too long\n",*argv);
+/*76:*/
+#line 1050 "cwebdir/comm-w2c.ch"
+fatal(_("! Filename too long\n"),*argv);
+#line 1365 "cwebdir/common.w"
 
 
-/*:78*/
+/*:76*/
 #line 1326 "cwebdir/common.w"
 ;
 if(dot_pos==NULL){
@@ -1273,7 +1585,9 @@ sprintf(C_file_name,"%s.c",*argv);
 }else{
 strcpy(tex_file_name,*argv);
 strcpy(C_file_name,*argv);
-if(flags['x']){
+#line 982 "cwebdir/comm-w2c.ch"
+if(make_xrefs){
+#line 1336 "cwebdir/common.w"
 *dot_pos= 0;
 sprintf(idx_file_name,"%s.idx",*argv);
 sprintf(scn_file_name,"%s.scn",*argv);
@@ -1282,51 +1596,84 @@ sprintf(scn_file_name,"%s.scn",*argv);
 found_out= 1;
 }
 
-#line 688 "cwebdir/comm-w2c.ch"
-/*:75*/
+#line 992 "cwebdir/comm-w2c.ch"
+/*:73*/
 #line 1277 "cwebdir/common.w"
 
-else/*77:*/
+else/*75:*/
 #line 1352 "cwebdir/common.w"
 
-{
-#line 722 "cwebdir/comm-w2c.ch"
-if(program==ctangle){
-fprintf(stderr,"ctangle: Need one to three file arguments.\n");
-usage("ctangle");
-}else{
-fprintf(stderr,"cweave: Need one to three file arguments.\n");
-usage("cweave");
-}
-#line 1362 "cwebdir/common.w"
-}
+#line 1043 "cwebdir/comm-w2c.ch"
+ cb_usage(program==ctangle?"ctangle":program==cweave?"cweave":"ctwill");
 
-/*:77*/
+#line 1363 "cwebdir/common.w"
+
+#line 1050 "cwebdir/comm-w2c.ch"
+/*:75*/
 #line 1278 "cwebdir/common.w"
 ;
 }
 }
-if(!found_web)/*77:*/
+if(!found_web)/*75:*/
 #line 1352 "cwebdir/common.w"
 
-{
-#line 722 "cwebdir/comm-w2c.ch"
-if(program==ctangle){
-fprintf(stderr,"ctangle: Need one to three file arguments.\n");
-usage("ctangle");
-}else{
-fprintf(stderr,"cweave: Need one to three file arguments.\n");
-usage("cweave");
-}
-#line 1362 "cwebdir/common.w"
-}
+#line 1043 "cwebdir/comm-w2c.ch"
+cb_usage(program==ctangle?"ctangle":program==cweave?"cweave":"ctwill");
 
-/*:77*/
+#line 1363 "cwebdir/common.w"
+
+#line 1050 "cwebdir/comm-w2c.ch"
+/*:75*/
 #line 1281 "cwebdir/common.w"
 ;
-#line 673 "cwebdir/comm-w2c.ch"
-if(found_change<=0)strcpy(change_file_name,DEV_NULL);
 #line 1283 "cwebdir/common.w"
 }
 
-/*:72*/
+#line 953 "cwebdir/comm-w2c.ch"
+/*:70*//*95:*/
+#line 1349 "cwebdir/comm-w2c.ch"
+
+static void cb_usage(const_string str)
+{
+textdomain("cweb-tl");
+
+fprintf(stderr,_("%s: Need one to three file arguments.\n"),str);
+fprintf(stderr,_("Try `%s --help' for more information.\n"),str);
+
+textdomain("cweb");
+
+history= fatal_message;exit(wrap_up());
+}
+
+static void cb_usagehelp(const_string*message,const_string bug_email)
+{
+if(!bug_email)
+bug_email= "tex-k@tug.org";
+textdomain("web2c-help");
+
+while(*message){
+printf("%s\n",strcmp("",*message)?_(*message):*message);
+++message;
+}
+textdomain("cweb-tl");
+
+printf(_("\nEmail bug reports to %s.\n"),bug_email);
+textdomain("cweb");
+
+history= spotless;exit(wrap_up());
+}
+
+/*:95*//*97:*/
+#line 1391 "cwebdir/comm-w2c.ch"
+
+void cb_show_banner(void)
+{
+assert(cb_banner[0]!='\0');
+textdomain("cweb-tl");
+
+printf("%s%s\n",_(cb_banner),versionstring);
+textdomain("cweb");
+
+}
+
+/*:97*/
diff --git a/source/texk/web2c/cwebdir/ChangeLog b/source/texk/web2c/cwebdir/ChangeLog
index e982318a2f45de5b1b558d876949376790c50f90..bdc4333fb259e9d4b40d37cc8b19054f7d4756d8 100644
--- a/source/texk/web2c/cwebdir/ChangeLog
+++ b/source/texk/web2c/cwebdir/ChangeLog
@@ -1,3 +1,61 @@
+2019-01-20  Andreas Scherer  <https://ascherer.github.io>
+
+	* comm-w2c.ch: Use braced evaluation and save a macro variable.
+
+2019-01-19  Andreas Scherer  <https://ascherer.github.io>
+
+	* comm-w2c.ch: Extended notes about NLS activation.
+	* po/web2c-help.pot, po/de/web2c-help.po: Fix typos.
+
+2019-01-18  Andreas Scherer  <https://ascherer.github.io>
+
+	* po/cweb.pot, po/de/cweb.po, po/it/cweb.po:
+	Update NLS references for TP notification.
+
+2019-01-17  Andreas Scherer  <https://ascherer.github.io>
+
+	* comm-w2c.ch, comm-w2c.h,
+	* ctang-w2c.ch, ctwill-w2c.ch, cweav-w2c.ch:
+	Translate 'banner' if HAVE_GETTEXT set and cweb-tl.mo available.
+
+2019-01-16  Andreas Scherer  <https://ascherer.github.io>
+
+	* comm-w2c.ch: Correct usage of 'kpse_var_expand';
+	skip numeric argument of '-d' flag.
+
+2019-01-15  Andreas Scherer  <https://ascherer.github.io>
+
+	* comm-w2c.ch: Provisional 'bindtextdomain' lookup in TDS.
+	* cwebinputs/texinputs: Add prefix 'cweb_' to TeX macros
+	and transliteration files.
+	* po/cweb-tl.pot: Realign NLS modules with texlive changes.
+
+2019-01-05  Andreas Scherer  <https://ascherer.github.io>
+
+	Integration of CWEBbin as the new CWEB in TeX Live,
+	https://github.com/ascherer/cwebbin.
+	
+	Purge cwebboot.h[in] from CWEB build process;
+	see ../ChangeLog for more changes in ../am/, etc.
+	
+	* comm-w2c.h: new file.
+	* ctang-w2c.ch,
+	* cweav-w2c.ch: cwebbin changes for translations and everything else.
+	
+	* ctproofmac.tex,
+	* cttwinxmac.tex,
+	* ctwimac.tex: new macro files.
+	
+	* po/: new subdirectory for translations.
+	* cwebinputs,
+	* texinputs: new subdirs to include entire original cweb distribution.
+	
+	Add CTWILL material on top of CWEAVE.
+	* prod-twill.w,
+	* refsort.w,
+	* twinx.w,
+	* ctwill-w2c.ch: new files.
+
 2018-12-30  Andreas Scherer  <https://ascherer.github.io>
 
 	* cweave.w,
diff --git a/source/texk/web2c/cwebdir/comm-w2c.ch b/source/texk/web2c/cwebdir/comm-w2c.ch
index d1ed2df5b18b9a315c52baeab23319508efa57c3..0d770b574227e03ced3932c237ce23d36035e1f7 100644
--- a/source/texk/web2c/cwebdir/comm-w2c.ch
+++ b/source/texk/web2c/cwebdir/comm-w2c.ch
@@ -1,257 +1,316 @@
-% Original Kpathsea changes for CWEB by Wlodek Bzyl and Olaf Weber
-% This file is in the Public Domain.
+@q Changes for CWEB in TeX Live from numerous contributors. @>
+@q This file is in the Public Domain. @>
 
-@x l.20
+@q Most of the original Kpathsea changes by Wlodek Bzyl and Olaf Weber @>
+@q were merged with the set of change files of the CWEBbin project; @>
+@q see https://github.com/ascherer/cwebbin for the original parts. @>
+
+@q This stripped change file {comm,ctang,cweav,ctwill}-w2c.ch has been @>
+@q created from the set of change files {comm,ctang,cweav}-patch.ch, @>
+@q {comm,ctang,cweav}-ansi.ch, {comm,ctang,cweav}-extensions.ch, @>
+@q {comm,ctang,cweav}-output.ch, {comm,ctang,cweav}-i18n.ch, and @>
+@q cweav-twill.ch for CTWILL, and {comm,ctang,cweav,ctwill}-texlive.ch @>
+@q with the 'tie' processor and is used as a monolithic changefile for @>
+@q {common,ctangle,cweave}.w in TeX Live. @>
+
+@q Please send comments, suggestions, etc. to tex-k@@tug.org. @>
+
+@x
 \def\title{Common code for CTANGLE and CWEAVE (Version 3.64)}
-\def\topofcontents{\null\vfill
-  \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and
-    {\ttitlefont CWEAVE}}
-  \vskip 15pt
-  \centerline{(Version 3.64)}
-  \vfill}
 @y
 \def\Kpathsea/{{\mc KPATHSEA\spacefactor1000}}
-\def\title{Common code for CTANGLE and CWEAVE (Version 3.64k)}
-\def\topofcontents{\null\vfill
-  \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and
-    {\ttitlefont CWEAVE}}
-  \vskip 15pt
-  \centerline{(Version 3.64k)}
-  \vfill}
+\def\title{Common code for CTANGLE and CWEAVE (\TeX~Live)}
 @z
 
-This change can not be applied when `tie' is  used
-(TOC file can not be typeset).
-
-%@x l.42
-%\let\maybe=\iftrue
-%@y
-%\let\maybe=\iffalse % print only changed modules
-%@z
-
-Section 1.
+@x
+  \centerline{(Version 3.64)}
+@y
+  \centerline{(Version 3.64 [\TeX~Live])}
+@z
 
-@x l.63
-@<Predeclaration of procedures@>@/
+@x
+@s not_eq normal @q unreserve a C++ keyword @>
 @y
-#include "cweb.h"
-@<Predeclaration of procedures@>@/
+@s boolean int
+@s uint8_t int
+@s uint16_t int
 @z
 
-Section 2. 
-We use the definition from `kpathsea/types.h':
+@x
+|program|.
 
-  typedef enum { false = 0, true = 1 } boolean;
+@d ctangle 0
+@d cweave 1
+@y
+|program|. And \.{CTWILL} adds some extra twists.
 
-Note that this definition also occurs in common.h.
-@x l.74
+@d ctangle 0
+@d cweave 1
+@d ctwill 2
+@z
+
+@x
 typedef short boolean;
+boolean program; /* \.{CWEAVE} or \.{CTANGLE}? */
 @y
+int program; /* \.{CWEAVE} or \.{CTANGLE} or \.{CTWILL}? */
 @z
 
-
-Section 4.
-
-@x l.91
+@x
+void
 common_init()
 @y
-common_init (void)
+void
+common_init(void)
 @z
 
-@x l.93
+@x
   @<Initialize pointers@>;
+  @<Set the default options common to \.{CTANGLE} and \.{CWEAVE}@>;
+  @<Scan arguments and open output files@>;
 @y
-  @<Initialize pointers@>;
-  @<Set up |PROGNAME| feature and initialize the search path mechanism@>;
+  @<Initialize pointers@>@;
+  @<Set up |PROGNAME| feature and initialize the search path mechanism@>@;
+  @<Set locale and bind language catalogs@>@;
+  @<Set the default options common to \.{CTANGLE} and \.{CWEAVE}@>@;
+  @<Scan arguments and open output files@>@;
 @z
 
-Section 5.
-
-@x l.103
-#include <ctype.h>
+@x
+@d not_eq 032 /* `\.{!=}'\,;  corresponds to MIT's {\tentex\char'32} */
 @y
-#define CWEB
-#include "cpascal.h"
-#include <ctype.h>
+@d non_eq 032 /* `\.{!=}'\,;  corresponds to MIT's {\tentex\char'32} */
 @z
 
-Section 7.
-
-@x l.153
+@x
 @d buf_size 100 /* for \.{CWEAVE} and \.{CTANGLE} */
 @y
 @d buf_size 1000 /* for \.{CWEAVE} and \.{CTANGLE} */
 @z
 
-@x l.156
+@x
 @d xisspace(c) (isspace(c)&&((unsigned char)c<0200))
 @d xisupper(c) (isupper(c)&&((unsigned char)c<0200))
 @y
-@d xisspace(c) (isspace((unsigned char)c)&&((unsigned char)c<0200))
-@d xisupper(c) (isupper((unsigned char)c)&&((unsigned char)c<0200))
+@d xisspace(c) (isspace((eight_bits)c)&&((eight_bits)c<0200))
+@d xisupper(c) (isupper((eight_bits)c)&&((eight_bits)c<0200))
 @z
 
-Section 9.
-
-@x l.173
+@x
 int input_ln(fp) /* copies a line into |buffer| or returns 0 */
 FILE *fp; /* what file to read from */
 @y
-int input_ln (FILE *fp) /* copies a line into |buffer| or returns 0 */
+static boolean input_ln(@t\1\1@> /* copies a line into |buffer| or returns 0 */
+FILE *fp@t\2\2@>) /* what file to read from */
 @z
 
-@x l.181
+@x
     if ((*(k++) = c) != ' ') limit = k;
 @y
-    if ((*(k++) = c) != ' ' && c!='\r') limit = k;
+    if ((*(k++) = c) != ' ' && c != '\r') limit = k;
 @z
 
-Section 10.
+@x
+      ungetc(c,fp); loc=buffer; err_print("! Input line too long");
+@y
+      ungetc(c,fp); loc=buffer; err_print(_("! Input line too long"));
+@z
 
-@x l.207 - max_file_name_length is way too small.
+@x
 @d max_file_name_length 60
 @y
 @d max_file_name_length 1024
 @z
 
-@x l.221 - no alt_web_file_name needed.
+@x
 char alt_web_file_name[max_file_name_length]; /* alternate name to try */
 @y
 @z
 
-Section 12.
+@x
+@d lines_dont_match (change_limit-change_buffer != limit-buffer ||
+  strncmp(buffer, change_buffer, limit-buffer))
+@y
+@d lines_dont_match (change_limit-change_buffer != limit-buffer || @|
+  strncmp(buffer, change_buffer, (size_t)(limit-buffer)))
+@z
 
-@x l.252
+@x
 void
 prime_the_change_buffer()
 @y
 static void
-prime_the_change_buffer (void)
+prime_the_change_buffer(void)
 @z
 
-@x l.271
+@x
   if (xisupper(buffer[1])) buffer[1]=tolower(buffer[1]);
 @y
-  if (xisupper(buffer[1])) buffer[1]=tolower((unsigned char)buffer[1]);
+  if (xisupper(buffer[1])) buffer[1]=tolower((eight_bits)buffer[1]);
 @z
 
-Section 16.
+@x
+    err_print("! Missing @@x in change file");
+@y
+    err_print(_("! Missing @@x in change file"));
+@z
 
-@x l.321
+@x
+    err_print("! Change file ended after @@x");
+@y
+    err_print(_("! Change file ended after @@x"));
+@z
+
+@x
+  change_limit=change_buffer+(limit-buffer);
+  strncpy(change_buffer,buffer,limit-buffer+1);
+@y
+  change_limit=change_buffer+(ptrdiff_t)(limit-buffer);
+  strncpy(change_buffer,buffer,(size_t)(limit-buffer+1));
+@z
+
+@x
 void
 check_change() /* switches to |change_file| if the buffers match */
 @y
 static void
-check_change (void) /* switches to |change_file| if the buffers match */
+check_change(void) /* switches to |change_file| if the buffers match */
 @z
 
-@x l.340
+@x
+      err_print("! Change file ended before @@y");
+@y
+      err_print(_("! Change file ended before @@y"));
+@z
+
+@x
       char xyz_code=xisupper(buffer[1])? tolower(buffer[1]): buffer[1];
 @y
-      char xyz_code=xisupper(buffer[1])? tolower((unsigned char)buffer[1]): buffer[1];
+      char xyz_code=xisupper(buffer[1])? tolower((eight_bits)buffer[1]): buffer[1];
 @z
 
-Section 18.
+@x
+        err_print("! CWEB file ended during a change");
+@y
+        err_print(_("! CWEB file ended during a change"));
+@z
 
-@x l.380
-reset_input()
+@x
+  loc=buffer+2; err_print("! Where is the matching @@y?");
+@y
+  loc=buffer+2; err_print(_("! Where is the matching @@y?"));
+@z
+
+@x
+    err_print("of the preceding lines failed to match");
 @y
-reset_input (void)
+    err_print(_("of the preceding lines failed to match"));
 @z
 
-Section 19.
+@x
+void
+reset_input()
+@y
+void
+reset_input(void)
+@z
 
-@x l.394
+@x
 if ((web_file=fopen(web_file_name,"r"))==NULL) {
   strcpy(web_file_name,alt_web_file_name);
   if ((web_file=fopen(web_file_name,"r"))==NULL)
        fatal("! Cannot open input file ", web_file_name);
 }
 @y
-if ((found_filename=kpse_find_cweb(web_file_name))==NULL ||
+if ((found_filename=kpse_find_cweb(web_file_name))==NULL || @|
     (web_file=fopen(found_filename,"r"))==NULL) {
-  fatal("! Cannot open input file ", web_file_name);
+  fatal(_("! Cannot open input file "), web_file_name);
 } else if (strlen(found_filename) < max_file_name_length) {
-  strcpy(web_file_name, found_filename);
+  /* Copy name for |#line| directives. */
+  if (strcmp(web_file_name, found_filename))
+    strcpy(web_file_name, found_filename +
+      ((strncmp(found_filename,"./",2)==0) ? 2 : 0));
   free(found_filename);
-}
+} else fatal(_("! Filename too long\n"), found_filename);
 @z
 
-@x l.402
+@x
 if ((change_file=fopen(change_file_name,"r"))==NULL)
        fatal("! Cannot open change file ", change_file_name);
 @y
-if ((found_filename=kpse_find_cweb(change_file_name))==NULL ||
+if ((found_filename=kpse_find_cweb(change_file_name))==NULL || @|
     (change_file=fopen(found_filename,"r"))==NULL) {
-  fatal("! Cannot open change file ", change_file_name);
+  fatal(_("! Cannot open change file "), change_file_name);
 } else if (strlen(found_filename) < max_file_name_length) {
-  strcpy(change_file_name, found_filename);
+  /* Copy name for |#line| directives. */
+  if (strcmp(change_file_name, found_filename))
+    strcpy(change_file_name, found_filename +
+      ((strncmp(found_filename,"./",2)==0) ? 2 : 0));
   free(found_filename);
-}
+} else fatal(_("! Filename too long\n"), found_filename);
 @z
 
-@x l.415
+@x
 @d max_sections 2000 /* number of identifiers, strings, section names;
+  must be less than 10240 */
 @y
 @d max_sections 10239 /* number of identifiers, strings, section names;
+  must be less than 10240 */
 @z
 
-Section 21.
+@x
+typedef unsigned short sixteen_bits;
+@y
+typedef uint8_t eight_bits;
+typedef uint16_t sixteen_bits;
+@z
 
-@x l.427
+@x
 int get_line() /* inputs the next line */
 @y
-int get_line (void) /* inputs the next line */
+boolean get_line(void) /* inputs the next line */
 @z
 
-Section 22.
-
-@x l.472
-#include <stdlib.h> /* declaration of |getenv| and |exit| */
+@x
+      err_print("! Include file name not given");
 @y
-#include <kpathsea/kpathsea.h> /* include every \Kpathsea/ header */
-#include <stdlib.h> /* declaration of |getenv| and |exit| */
-#include "help.h"
-
-@ The \.{ctangle} and \.{cweave} programs from the original \.{CWEB}
-package use the compile-time default directory or the value of the
-environment variable \.{CWEBINPUTS} as an alternative place to be
-searched for files, if they could not be found in the current
-directory.
-
-This version uses the \Kpathsea/ mechanism for searching files. 
-The directories to be searched for come from three sources:
-
- (a)~a user-set environment variable \.{CWEBINPUTS}
-    (overriden by \.{CWEBINPUTS\_cweb});\par
- (b)~a line in \Kpathsea/ configuration file \.{texmf.cnf},\hfil\break
-    e.g. \.{CWEBINPUTS=.:$TEXMF/texmf/cweb//}
-    or \.{CWEBINPUTS.cweb=.:$TEXMF/texmf/cweb//};\hangindent=2\parindent\par
- (c)~compile-time default directories \.{.:$TEXMF/texmf/cweb//}
-    (specified in \.{texmf.in}).
-
-
-@d kpse_find_cweb(name) kpse_find_file(name,kpse_cweb_format,true)
-
-@ The simple file searching is replaced by `path searching' mechanism
-that \Kpathsea/ library provides.
-
-We set |kpse_program_name| to a |"cweb"|.  This means if the
-variable |CWEBINPUTS.cweb| is present in \.{texmf.cnf} (or |CWEBINPUTS_cweb|
-in the environment) its value will be used as the search path for
-filenames.  This allows different flavors of \.{CWEB} to have
-different search paths.
-
-FIXME: Not sure this is the best way to go about this.
+      err_print(_("! Include file name not given"));
+@z
 
-@<Set up |PROGNAME| feature and initialize the search path mechanism@>=
-kpse_set_program_name(argv[0], "cweb"); 
+@x
+      err_print("! Too many nested includes");
+@y
+      err_print(_("! Too many nested includes"));
 @z
 
+@x
+@ When an \.{@@i} line is found in the |cur_file|, we must temporarily
+stop reading it and start reading from the named include file.  The
+\.{@@i} line should give a complete file name with or without
+double quotes.
+If the environment variable \.{CWEBINPUTS} is set, or if the compiler flag
+of the same name was defined at compile time,
+\.{CWEB} will look for include files in the directory thus named, if
+it cannot find them in the current directory.
+(Colon-separated paths are not supported.)
+The remainder of the \.{@@i} line after the file name is ignored.
+@y
+@ When an \.{@@i} line is found in the |cur_file|, we must temporarily
+stop reading it and start reading from the named include file.  The
+\.{@@i} line should give a complete file name with or without
+double quotes.
+The actual file lookup is done with the help of the \Kpathsea/ library;
+see section~\X90:File lookup with \Kpathsea/\X~for details. % FIXME
+The remainder of the \.{@@i} line after the file name is ignored.
+@z
 
-Section 23.
+@x
+        err_print("! Include file name too long"); goto restart;}
+@y
+        err_print(_("! Include file name too long")); goto restart;}
+@z
 
-@x l.475
+@x
   char temp_file_name[max_file_name_length];
   char *cur_file_name_end=cur_file_name+max_file_name_length-1;
   char *k=cur_file_name, *kk;
@@ -261,21 +320,21 @@ Section 23.
   char *k=cur_file_name;
 @z
 
-@x l.489
+@x
   if ((cur_file=fopen(cur_file_name,"r"))!=NULL) {
 @y
-  if ((found_filename=kpse_find_cweb(cur_file_name))!=NULL &&
+  if ((found_filename=kpse_find_cweb(cur_file_name))!=NULL && @|
       (cur_file=fopen(found_filename,"r"))!=NULL) {
-    /* Copy name for #line directives. */
+    /* Copy name for |#line| directives. */
     if (strlen(found_filename) < max_file_name_length) {
-      strcpy(cur_file_name, found_filename);
+      if (strcmp(cur_file_name, found_filename))
+        strcpy(cur_file_name, found_filename +
+          ((strncmp(found_filename,"./",2)==0) ? 2 : 0));
       free(found_filename);
-    }
+    } else fatal(_("! Filename too long\n"), found_filename);
 @z
 
-Replaced by Kpathsea `kpse_find_file'
-
-@x l.493
+@x
   kk=getenv("CWEBINPUTS");
   if (kk!=NULL) {
     if ((l=strlen(kk))>max_file_name_length-2) too_long();
@@ -300,178 +359,190 @@ Replaced by Kpathsea `kpse_find_file'
       goto restart; /* success */
     }
   }
+  include_depth--; err_print("! Cannot open include file"); goto restart;
 @y
+  include_depth--; err_print(_("! Cannot open include file")); goto restart;
 @z
 
-Section 26.
+@x
+    err_print("! Change file ended without @@z");
+@y
+    err_print(_("! Change file ended without @@z"));
+@z
 
-@x l.553
+@x
       if (xisupper(buffer[1])) buffer[1]=tolower(buffer[1]);
 @y
-      if (xisupper(buffer[1])) buffer[1]=tolower((unsigned char)buffer[1]);
+      if (xisupper(buffer[1])) buffer[1]=tolower((eight_bits)buffer[1]);
+@z
+
+@x
+        err_print("! Where is the matching @@z?");
+@y
+        err_print(_("! Where is the matching @@z?"));
 @z
 
-@x l.571
+@x
+void
 check_complete(){
+  if (change_limit!=change_buffer) { /* |changing| is 0 */
+    strncpy(buffer,change_buffer,change_limit-change_buffer+1);
+    limit=buffer+(int)(change_limit-change_buffer);
 @y
-check_complete (void) {
+void
+check_complete(void) {
+  if (change_limit!=change_buffer) { /* |changing| is 0 */
+    strncpy(buffer,change_buffer,(size_t)(change_limit-change_buffer+1));
+    limit=buffer+(ptrdiff_t)(change_limit-change_buffer);
 @z
 
-@x l.589
-@d max_bytes 90000 /* the number of bytes in identifiers,
+@x
+    err_print("! Change file entry did not match");
 @y
-@d max_bytes 1000000 /* the number of bytes in identifiers,
+    err_print(_("! Change file entry did not match"));
 @z
 
-@x l.591
+@x
+@d max_bytes 90000 /* the number of bytes in identifiers,
+  index entries, and section names; must be less than $2^{24}$ */
 @d max_names 4000 /* number of identifiers, strings, section names;
+  must be less than 10240 */
 @y
+@d max_bytes 1000000 /* the number of bytes in identifiers,
+  index entries, and section names; must be less than $2^{24}$ */
 @d max_names 10239 /* number of identifiers, strings, section names;
+  must be less than 10240 */
+@z
+
+@x
+@d length(c) (c+1)->byte_start-(c)->byte_start /* the length of a name */
+@y
+@d length(c) (size_t)((c+1)->byte_start-(c)->byte_start) /* the length of a name */
 @z
 
-@x l.642
+@x
 @d hash_size 353 /* should be prime */
 @y
 @d hash_size 8501 /* should be prime */
 @z
 
-Section 33.
-
-@x l.650
-@ @<Predec...@>=
+@x
 extern int names_match();
 @y
-@ @<External functions@>=
-extern int names_match (name_pointer, const char*, int, char);
+extern boolean names_match(name_pointer,const char *,size_t,eight_bits);@/
 @z
 
-Section 35.
-
-@x l.661
+@x
+name_pointer
 id_lookup(first,last,t) /* looks up a string in the identifier table */
 char *first; /* first character of string */
 char *last; /* last character of string plus one */
 char t; /* the |ilk|; used by \.{CWEAVE} only */
-@y
-/* looks up a string in the identifier table */
-id_lookup (const char *first, const char *last, char t)
-@z
-
-@x l.667
+{
   char *i=first; /* position in |buffer| */
 @y
+name_pointer
+id_lookup(@t\1\1@> /* looks up a string in the identifier table */
+const char *first, /* first character of string */
+const char *last, /* last character of string plus one */
+char t@t\2\2@>) /* the |ilk|; used by \.{CWEAVE} only */
+{
   const char *i=first; /* position in |buffer| */
 @z
 
-@x l.668 - rename local var, not to shadow global
-  int h; /* hash code */
-@y
-  int h; /* hash code */
-@z
-
-Section 36.
-
-@x l.684 - use renamed local var
-h=(unsigned char)*i;
-while (++i<last) h=(h+h+(int)((unsigned char)*i)) % hash_size;
+@x
+  l=last-first; /* compute the length */
 @y
-h=(unsigned char)*i;
-while (++i<last) h=(h+h+(int)((unsigned char)*i)) % hash_size;
+  l=(int)(last-first); /* compute the length */
 @z
 
-Section 37.
-
-@x l.692 - use renamed local var
-p=hash[h];
+@x
+void init_p();
 @y
-p=hash[h];
+extern void init_p(name_pointer,eight_bits);@/
 @z
 
-@x l.696 - use renamed local var
-  p->link=hash[h]; hash[h]=p; /* insert |p| at beginning of hash list */
+@x
+  if (byte_ptr+l>byte_mem_end) overflow("byte memory");
+  if (name_ptr>=name_dir_end) overflow("name");
 @y
-  p->link=hash[h]; hash[h]=p; /* insert |p| at beginning of hash list */
+  if (byte_ptr+l>byte_mem_end) overflow(_("byte memory"));
+  if (name_ptr>=name_dir_end) overflow(_("name"));
 @z
 
-Section 38.
-
-@x l.703
-@<Pred...@>=
-void init_p();
+@x
+  if (program==cweave) init_p(p,t);
 @y
-@<External functions@>=
-extern void init_p (name_pointer p, char t);
+  init_p(p,t);
 @z
 
-Section 42.
-
-@x l.766
+@x
+void
 print_section_name(p)
 name_pointer p;
 @y
-print_section_name (name_pointer p)
+void
+print_section_name(
+name_pointer p)
 @z
 
-Section 43.
+@x
+      term_write(s,ss-s); p=q->link; q=p;
+    } else {
+      term_write(s,ss+1-s); p=name_dir; q=NULL;
+@y
+      term_write(s,(size_t)(ss-s)); p=q->link; q=p;
+    } else {
+      term_write(s,(size_t)(ss+1-s)); p=name_dir; q=NULL;
+@z
 
-@x l.785
+@x
+void
 sprint_section_name(dest,p)
   char*dest;
   name_pointer p;
 @y
-sprint_section_name (char *dest, name_pointer p)
+void
+sprint_section_name(
+  char *dest,
+  name_pointer p)
 @z
 
-Section 44.
+@x
+    strncpy(dest,s,ss-s), dest+=ss-s;
+@y
+    strncpy(dest,s,(size_t)(ss-s)), dest+=ss-s;
+@z
 
-@x l.805
+@x
 void
 print_prefix_name(p)
 name_pointer p;
 @y
-static void
-print_prefix_name (name_pointer p)
+void
+print_prefix_name(
+name_pointer p)
 @z
 
-Section 45.
-
-@x l.826
+@x
 int web_strcmp(j,j_len,k,k_len) /* fuller comparison than |strcmp| */
   char *j, *k; /* beginning of first and second strings */
   int j_len, k_len; /* length of strings */
 @y
-/* fuller comparison than |strcmp| */
-static int
-web_strcmp (char *j, int j_len, char *k, int k_len)
+static int web_strcmp(@t\1\1@> /* fuller comparison than |strcmp| */
+  char *j, /* beginning of first string */
+  int j_len, /* length of first string */
+  char *k, /* beginning of second string */
+  int k_len@t\2\2@>) /* length of second string */
 @z
 
-@x l.830 -- rename local vars, not to shadow math function
-  char *j1=j+j_len, *k1=k+k_len;
-  while (k<k1 && j<j1 && *j==*k) k++, j++;
-  if (k==k1) if (j==j1) return equal;
-    else return extension;
-  else if (j==j1) return prefix;
-@y
-  char *j1=j+j_len, *k1=k+k_len;
-  while (k<k1 && j<j1 && *j==*k) k++, j++;
-  if (k==k1) if (j==j1) return equal;
-    else return extension;
-  else if (j==j1) return prefix;
-@z
-
-Section 46.
-
-@x l.852
-@<Prede...@>=
+@x
 extern void init_node();
 @y
-@<External functions@>=
-extern void init_node (name_pointer node);
+extern void init_node(name_pointer);@/
 @z
 
-Section 47.
-
-@x l.856
+@x
 name_pointer
 add_section_name(par,c,first,last,ispref) /* install a new node in the tree */
 name_pointer par; /* parent of new node */
@@ -481,13 +552,29 @@ char *last; /* last character of section name, plus one */
 int ispref; /* are we adding a prefix or a full name? */
 @y
 static name_pointer
-add_section_name (name_pointer par, int c, char *first, char *last,
-                  int ispref)  /* install a new node in the tree */
+add_section_name(@t\1\1@> /* install a new node in the tree */
+name_pointer par, /* parent of new node */
+int c, /* right or left? */
+char *first, /* first character of section name */
+char *last, /* last character of section name, plus one */
+int ispref@t\2\2@>) /* are we adding a prefix or a full name? */
+@z
+
+@x
+  int name_len=last-first+ispref; /* length of section name */
+@y
+  int name_len=(int)(last-first)+ispref; /* length of section name */
 @z
 
-Section 48.
+@x
+  if (s+name_len>byte_mem_end) overflow("byte memory");
+  if (name_ptr+1>=name_dir_end) overflow("name");
+@y
+  if (s+name_len>byte_mem_end) overflow(_("byte memory"));
+  if (name_ptr+1>=name_dir_end) overflow(_("name"));
+@z
 
-@x l.885
+@x
 void
 extend_section_name(p,first,last,ispref)
 name_pointer p; /* name to be extended */
@@ -496,220 +583,453 @@ char *last; /* one beyond end of extension text */
 int ispref; /* are we adding a prefix or a full name? */
 @y
 static void
-extend_section_name (name_pointer p, char *first, char *last, int ispref)
+extend_section_name(@t\1\1@>
+name_pointer p, /* name to be extended */
+char *first, /* beginning of extension text */
+char *last, /* one beyond end of extension text */
+int ispref@t\2\2@>) /* are we adding a prefix or a full name? */
+@z
+
+@x
+  int name_len=last-first+ispref;
+@y
+  int name_len=(int)(last-first)+ispref;
+@z
+
+@x
+  if (name_ptr>=name_dir_end) overflow("name");
+@y
+  if (name_ptr>=name_dir_end) overflow(_("name"));
 @z
 
-Section 49.
+@x
+  if (s+name_len>byte_mem_end) overflow("byte memory");
+@y
+  if (s+name_len>byte_mem_end) overflow(_("byte memory"));
+@z
 
-@x l.914
+@x
+name_pointer
 section_lookup(first,last,ispref) /* find or install section name in tree */
 char *first, *last; /* first and last characters of new name */
 int ispref; /* is the new name a prefix or a full name? */
 @y
-/* find or install section name in tree */
-section_lookup (char *first, char *last, int ispref)
+name_pointer
+section_lookup(@t\1\1@> /* find or install section name in tree */
+char *first,char *last, /* first and last characters of new name */
+int ispref@t\2\2@>) /* is the new name a prefix or a full name? */
 @z
 
-Section 53.
+@x
+  int name_len=last-first+1;
+@y
+  int name_len=(int)(last-first)+1;
+@z
 
-@x l.1018
-int section_name_cmp();
+@x
+      printf("\n! Ambiguous prefix: matches <");
 @y
-static int section_name_cmp (char**, int, name_pointer);
+      fputs(_("\n! Ambiguous prefix: matches <"),stdout);
 @z
 
-Section 54.
+@x
+      printf(">\n and <");
+@y
+      fputs(_(">\n and <"),stdout);
+@z
+
+@x
+      printf("\n! New name is a prefix of <");
+@y
+      fputs(_("\n! New name is a prefix of <"),stdout);
+@z
 
-@x l.1021
+@x
+      printf("\n! New name extends <");
+@y
+      fputs(_("\n! New name extends <"),stdout);
+@z
+
+@x
+    printf("\n! Section name incompatible with <");
+@y
+    fputs(_("\n! Section name incompatible with <"),stdout);
+@z
+
+@x
+    printf(">,\n which abbreviates <");
+@y
+    fputs(_(">,\n which abbreviates <"),stdout);
+@z
+
+@x
+int section_name_cmp();
+@y
+static int section_name_cmp(char **,int,name_pointer);@/
+@z
+
+@x
 int section_name_cmp(pfirst,len,r)
 char **pfirst; /* pointer to beginning of comparison string */
 int len; /* length of string */
 name_pointer r; /* section name being compared */
 @y
-static int
-section_name_cmp (char **pfirst, int len, name_pointer r)
+static int section_name_cmp(@t\1\1@>
+char **pfirst, /* pointer to beginning of comparison string */
+int len, /* length of string */
+name_pointer r@t\2\2@>) /* section name being compared */
 @z
 
-Section 57.
+@x
+          *pfirst=first+(ss-s);
+@y
+          *pfirst=first+(ptrdiff_t)(ss-s);
+@z
 
-@x l.1092
-@<Predecl...@>=
-void  err_print();
+@x
+      if (q!=name_dir) {len -= ss-s; s=q->byte_start; r=q; continue;}
 @y
-@<External functions@>=
-extern void  err_print (const char*);
+      if (q!=name_dir) {len -= (int)(ss-s); s=q->byte_start; r=q; continue;}
 @z
 
-Section 58.
+@x
+|equiv_or_xref| as a pointer to a |char|.
+
+@<More elements of |name...@>=
+char *equiv_or_xref; /* info corresponding to names */
+@y
+|equiv_or_xref| as a pointer to |void|.
+
+@<More elements of |name...@>=
+void *equiv_or_xref; /* info corresponding to names */
+@z
+
+@x
+void  err_print();
+@y
+extern void err_print(const char *);@/
+@z
 
-@x l.1098
+@x
+void
 err_print(s) /* prints `\..' and location of error message */
 char *s;
 @y
-err_print (const char *s) /* prints `\..' and location of error message */
+void
+err_print(@t\1\1@> /* prints `\..' and location of error message */
+const char *s@t\2\2@>)
 @z
 
-Section 60.
+@x
+  printf(". (l. %d of change file)\n", change_line);
+else if (include_depth==0) printf(". (l. %d)\n", cur_line);
+  else printf(". (l. %d of include file %s)\n", cur_line, cur_file_name);
+@y
+  printf(_(". (l. %d of change file)\n"), change_line);
+else if (include_depth==0) printf(_(". (l. %d)\n"), cur_line);
+  else printf(_(". (l. %d of include file %s)\n"), cur_line, cur_file_name);
+@z
 
-@x l.1140
-@<Prede...@>=
+@x
 int wrap_up();
 extern void print_stats();
 @y
-@<External functions@>=
-extern int wrap_up (void);
-extern void print_stats (void);
+extern int wrap_up(void);@/
+extern void print_stats(void);@/
 @z
 
-Section 61.
+@x
+@ Some implementations may wish to pass the |history| value to the
+operating system so that it can be used to govern whether or not other
+programs are started. Here, for instance, we pass the operating system
+a status of 0 if and only if only harmless messages were printed.
+@^system dependencies@>
+@y
+@ On multi-tasking systems like the {\mc AMIGA} it is very convenient to
+know a little bit more about the reasons why a program failed.  The four
+levels of return indicated by the |history| value are very suitable for
+this purpose.  Here, for instance, we pass the operating system a status
+of~0 if and only if the run was a complete success.  Any warning or error
+message will result in a higher return value, so that {\mc AREXX} scripts
+can be made sensitive to these conditions.
+@^system dependencies@>
+
+@d RETURN_OK     0 /* No problems, success */
+@d RETURN_WARN   5 /* A warning only */
+@d RETURN_ERROR 10 /* Something wrong */
+@d RETURN_FAIL  20 /* Complete or severe failure */
+@z
 
-@x l.1151
+@x
 int wrap_up() {
+  putchar('\n');
 @y
-int wrap_up (void) {
+int wrap_up(void) {
+  if (show_progress) new_line;
 @z
 
-Section 63.
+@x
+  @<Print the job |history|@>;
+@y
+  @<Print the job |history|@>@;
+  @<Remove the temporary file if not already done@>@;
+@z
 
-@x l.1173
-@<Predec...@>=
+@x
+  if (history > harmless_message) return(1);
+  else return(0);
+@y
+  switch(history) {
+  case harmless_message: return RETURN_WARN;
+  case error_message: return RETURN_ERROR;
+  case fatal_message: return RETURN_FAIL;
+  default: return RETURN_OK;
+  }
+@z
+
+@x
+case spotless: if (show_happiness) printf("(No errors were found.)\n"); break;
+case harmless_message:
+  printf("(Did you see the warning message above?)\n"); break;
+case error_message:
+  printf("(Pardon me, but I think I spotted something wrong.)\n"); break;
+case fatal_message: printf("(That was a fatal error, my friend.)\n");
+@y
+case spotless:
+  if (show_happiness) puts(_("(No errors were found.)")); break;
+case harmless_message:
+  puts(_("(Did you see the warning message above?)")); break;
+case error_message:
+  puts(_("(Pardon me, but I think I spotted something wrong.)")); break;
+case fatal_message:
+  puts(_("(That was a fatal error, my friend.)"));
+@z
+
+@x
 void fatal(), overflow();
 @y
-@<External functions@>=
-extern void fatal (const char*, const char*);
-extern void overflow (const char*);
+extern void fatal(const char *,const char *);@/
+extern void overflow(const char *);@/
 @z
 
-Section 64.
-
-@x l.1180
+@x
+@c void
 fatal(s,t)
   char *s,*t;
 @y
-fatal (const char *s, const char *t)
+@c void
+fatal(
+  const char *s,const char *t)
 @z
 
-@x l.1183
+@x
   if (*s) printf(s);
 @y
-  if (*s) printf("%s",s);
+  if (*s) fputs(s,stdout);
 @z
 
-Section 65.
-
-@x l.1191
+@x
+@c void
 overflow(t)
   char *t;
 @y
-overflow (const char *t)
+@c void
+overflow(
+  const char *t)
 @z
 
-Section 67.
-
-@x l.1212
-the names of those files. Most of the 128 flags are undefined but available
-for future extensions.
+@x
+  printf("\n! Sorry, %s capacity exceeded",t); fatal("","");
 @y
-the names of those files. Most of the 128 flags are undefined but available
-for future extensions.
+  printf(_("\n! Sorry, %s capacity exceeded"),t); fatal("","");
+@z
 
-We use `kpathsea' library functions to find literate sources and
-NLS configuration files. When the files you expect are not
-being found, the thing to do is to enable `kpathsea' runtime
-debugging by assigning to |kpathsea_debug| variable a small number
-via `\.{-d}' option. The meaning of number is shown below. To set
-more than one debugging options sum the corresponding numbers.
-$$\halign{\hskip5em\tt\hfil#&&\qquad\tt#\cr
- 1&report `\.{stat}' calls\cr
- 2&report lookups in all hash tables\cr
- 4&report file openings and closings\cr
- 8&report path information\cr
-16&report directory list\cr
-32&report on each file search\cr
-64&report values of variables being looked up\cr}$$
-Debugging output is always written to |stderr|, and begins with the string
-`\.{kdebug:}'.
+@x
+@d confusion(s) fatal("! This can't happen: ",s)
+@y
+@d confusion(s) fatal(_("! This can't happen: "),s)
 @z
 
-@x l.1218
+@x
 @d show_happiness flags['h'] /* should lack of errors be announced? */
 @y
 @d show_happiness flags['h'] /* should lack of errors be announced? */
-@d show_kpathsea_debug flags['d']
-  /* should results of file searching be shown? */
+@d make_xrefs flags['x'] /* should cross references be output? */
 @z
 
-@x l.1234
-show_banner=show_happiness=show_progress=1;
+@x
+char scn_file_name[max_file_name_length]; /* name of |scn_file| */
 @y
-show_banner=show_happiness=show_progress=1;
+char scn_file_name[max_file_name_length]; /* name of |scn_file| */
+char check_file_name[max_file_name_length]; /* name of |check_file| */
 @z
 
-Section 69.
+@x
+boolean flags[128]; /* an option for each 7-bit code */
+@y
+boolean flags[128]; /* an option for each 7-bit code */
+const char *use_language=""; /* prefix of \.{cwebmac.tex} in \TEX/ output */
+@z
 
-@x l.1252
-void scan_args();
+@x
+show_banner=show_happiness=show_progress=1;
 @y
-static void scan_args (void);
 @z
 
+@x
+An omitted change file argument means that |"/dev/null"| should be used,
+when no changes are desired.
+@y
+An omitted change file argument means that |"/dev/null"| or---on non-\UNIX/
+systems the contents of the compile-time variable |DEV_NULL| (\TeX~Live) or
+|_DEV_NULL| (Amiga)---should be used, when no changes are desired.
+@z
 
-Section 70.
+@x
+void scan_args();
+@y
+static void scan_args(void);@/
+@z
 
-@x l.1255
+@x
 void
 scan_args()
 @y
 static void
-scan_args (void)
+scan_args(void)
 @z
 
+@x
+  boolean flag_change;
+@y
+@z
 
-Section 71.
+@x
+  while (--argc > 0) {
+@y
+@#
+#if defined DEV_NULL
+  strncpy(change_file_name,DEV_NULL,max_file_name_length-2);
+  change_file_name[max_file_name_length-2]='\0';
+#elif defined _DEV_NULL
+  strncpy(change_file_name,_DEV_NULL,max_file_name_length-2);
+  change_file_name[max_file_name_length-2]='\0';
+#else
+  strcpy(change_file_name,"/dev/null");
+#endif
+@^system dependencies@>
+  while (--argc > 0) {
+@z
 
-@x l.1282 - use a define for /dev/null
+@x
+      while (*s) {
+        if (*s=='.') dot_pos=s++;
+        else if (*s=='/') dot_pos=NULL,name_pos=++s;
+        else s++;
+      }
+@y
+      while (*s) {
+        if (*s=='.') dot_pos=s++;
+        else if (*s==DIR_SEPARATOR || *s==DEVICE_SEPARATOR || *s=='/')
+          dot_pos=NULL,name_pos=++s;
+        else s++;
+      }
+@^system dependencies@>
+@z
+
+@x
   if (found_change<=0) strcpy(change_file_name,"/dev/null");
 @y
-  if (found_change<=0) strcpy(change_file_name,DEV_NULL);
 @z
 
-@x l.1302 - no alt_web_file_name
+@x
+@ We use all of |*argv| for the |web_file_name| if there is a |'.'| in it,
+otherwise we add |".w"|. If this file can't be opened, we prepare an
+|alt_web_file_name| by adding |"web"| after the dot.
+The other file names come from adding other things
+after the dot.  We must check that there is enough room in
+|web_file_name| and the other arrays for the argument.
+@y
+@ We use all of |*argv| for the |web_file_name| if there is a |'.'| in it,
+otherwise we add |".w"|.  The other file names come from adding other things
+after the dot.  We must check that there is enough room in |web_file_name| and
+the other arrays for the argument.
+@z
+
+@x
   sprintf(alt_web_file_name,"%s.web",*argv);
 @y
 @z
 
+@x
+  if (strcmp(*argv,"-")==0) found_change=-1;
+  else {
+@y
+  if (strcmp(*argv,"-")!=0) {
+@z
+
+@x
+    found_change=1;
+  }
+@y
+  }
+  found_change=1;
+@z
 
-Section 74.
+@x
+    if (flags['x']) { /* indexes will be generated */
+@y
+    if (make_xrefs) { /* indexes will be generated */
+@z
 
-@x l.1344
+@x
 @ @<Handle flag...@>=
 {
+  if (**argv=='-') flag_change=0;
+  else flag_change=1;
+  for(dot_pos=*argv+1;*dot_pos>'\0';dot_pos++)
 @y
-@ @<Handle flag...@>=
+@ @d flag_change (**argv!='-')
+@<Handle flag...@>=
 {
   if (strcmp("-help",*argv)==0 || strcmp("--help",*argv)==0)
-    @<Display help message and exit@>;
+@.--help@>
+    @<Display help message and |exit|@>@;
   if (strcmp("-version",*argv)==0 || strcmp("--version",*argv)==0)
-    @<Display version information and exit@>;
-@z
-
-@x l.1347
-  else flag_change=1;
-@y
-  else flag_change=1;
-  if (*(*argv+1)=='d')
-    if (sscanf(*argv+2,"%u",&kpathsea_debug)!=1) @<Print usage error...@>;
+@.--version@>
+    @<Display version information and |exit|@>@;
+  if (strcmp("-verbose",*argv)==0 || strcmp("--verbose",*argv)==0)
+@.--verbose@>
+  { show_banner=show_progress=show_happiness=1; continue; }
+  if (strcmp("-quiet",*argv)==0 || strcmp("--quiet",*argv)==0)
+@.--quiet@>
+  { show_banner=show_progress=show_happiness=0; continue; }
+  for(dot_pos=*argv+1;*dot_pos>'\0';dot_pos++)
+    if (*dot_pos=='v') {
+      show_banner=show_progress=show_happiness=1;
+    } else
+    if (*dot_pos=='q') {
+      show_banner=show_progress=show_happiness=0;
+    } else
+    if (*dot_pos=='d') {
+      if (sscanf(++dot_pos,"%u",&kpathsea_debug)!=1) @<Print usage error...@>@;
+      while (isdigit(*dot_pos)) dot_pos++; /* skip numeric part */
+      dot_pos--; /* reset to final digit */
+    } else
+    if(*dot_pos=='l') {
+       use_language=++dot_pos;
+       break;
+    } else
 @z
 
-@x l.1349
+@x
     flags[*dot_pos]=flag_change;
 @y
-    flags[(unsigned char)*dot_pos]=flag_change;
+    flags[(eight_bits)*dot_pos]=flag_change;
 @z
 
-Section 75.
-
-@x l.1354
+@x
+{
 if (program==ctangle)
   fatal(
 "! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
@@ -718,43 +1038,71 @@ if (program==ctangle)
 else fatal(
 "! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
    ,"");
-@y
-if (program==ctangle) {
-  fprintf(stderr, "ctangle: Need one to three file arguments.\n");
-  usage("ctangle");
-} else {
-  fprintf(stderr, "cweave: Need one to three file arguments.\n");
-  usage("cweave");
 }
+@y
+cb_usage(program==ctangle ? "ctangle" : program==cweave ? "cweave" : "ctwill");
+@.Usage:@>
 @z
 
-Section 77.
+@x
+@ @<Complain about arg...@>= fatal("! Filename too long\n", *argv);
+@y
+@ @<Complain about arg...@>= fatal(_("! Filename too long\n"), *argv);
+@z
 
-@x l.1375
+@x
+FILE *scn_file; /* where list of sections from \.{CWEAVE} goes */
+@y
+FILE *scn_file; /* where list of sections from \.{CWEAVE} goes */
+FILE *check_file; /* temporary output file */
+@z
+
+@x
 FILE *active_file; /* currently active file for \.{CWEAVE} output */
 @y
 FILE *active_file; /* currently active file for \.{CWEAVE} output */
 char *found_filename; /* filename found by |kpse_find_file| */
 @z
 
-Section 78.
-
-@x l.1380 Use binary mode for output files
+@x
+@ @<Scan arguments and open output files@>=
+scan_args();
+if (program==ctangle) {
   if ((C_file=fopen(C_file_name,"w"))==NULL)
-@y
-  if ((C_file=fopen(C_file_name,"wb"))==NULL)
-@z
-
-@x l.1386 Use binary mode for output files
+    fatal("! Cannot open output file ", C_file_name);
+@.Cannot open output file@>
+}
+else {
   if ((tex_file=fopen(tex_file_name,"w"))==NULL)
+    fatal("! Cannot open output file ", tex_file_name);
+}
 @y
-  if ((tex_file=fopen(tex_file_name,"wb"))==NULL)
+@ @<Scan arguments and open output files@>=
+scan_args();
+if (program==ctangle) {
+  strcpy(check_file_name,C_file_name);
+  if(check_file_name[0]!='\0') {
+    char *dot_pos=strrchr(check_file_name,'.');
+    if(dot_pos==NULL) strcat(check_file_name,".ttp");
+    else strcpy(dot_pos,".ttp");
+  }
+  if ((C_file=fopen(check_file_name,"wb"))==NULL)
+    fatal(_("! Cannot open output file "), check_file_name);
+@.Cannot open output file@>
+}
+else {
+  strcpy(check_file_name,tex_file_name);
+  if(check_file_name[0]!='\0') {
+    char *dot_pos=strrchr(check_file_name,'.');
+    if(dot_pos==NULL) strcat(check_file_name,".wtp");
+    else strcpy(dot_pos,".wtp");
+  }
+  if ((tex_file=fopen(check_file_name,"wb"))==NULL)
+    fatal(_("! Cannot open output file "), check_file_name);
+}
 @z
 
-
-Section 81. (reused)
-
-@x l.1403
+@x
 @ We predeclare several standard system functions here instead of including
 their system header files, because the names of the header files are not as
 standard as the names of the functions. (For example, some \CEE/ environments
@@ -767,52 +1115,294 @@ extern char* strcpy(); /* copy one string to another */
 extern int strncmp(); /* compare up to $n$ string characters */
 extern char* strncpy(); /* copy up to $n$ string characters */
 @y
-@ We declare some more prototypes for exported function in cases where this
-could not be done easily without changing section numbers.
+@ For string handling we include the {\mc ANSI C} system header file instead
+of predeclaring the standard system functions |strlen|, |strcmp|, |strcpy|,
+|strncmp|, and |strncpy|.
+@^system dependencies@>
 
-@<External functions@>=
-extern void common_init (void);
-extern int input_ln (FILE *fp);
-extern void reset_input (void);
-extern int get_line (void);
-extern void check_complete (void);
-extern name_pointer id_lookup (const char *first, const char *last, char t);
-extern void print_section_name (name_pointer p);
-extern void sprint_section_name (char *dest, name_pointer p);
-extern name_pointer section_lookup (char *first, char *last, int ispref);
+@<Include...@>=
+#include <string.h>
 @z
 
 @x
 @** Index.
 @y
-@** External functions.  In order to allow for type checking we create a
-header file \.{cweb.h} containing the declaration of all functions defined
-in \.{common.w} and used in \.{ctangle.w} and \.{cweave.w} or vice versa.
+@** Extensions for modern \.{CWEB}.
+
+The following sections introduce code changes and extensions that have been
+created by numerous contributors over the course of a quarter century. They
+make \.{CWEB} adhere to modern coding standards and introduce new or improved
+features.
+
+Care has been taken to keep the original section numbering intact, so this new
+section should have the same number as the original ``\&{82.~Index},'' and
+additional material follows below.
+
+@* Function declarations. Here are declarations---conforming to
+{\mc ANSI~C}---of all functions in this code that appear in |"common.h"|
+and thus should agree with \.{CTANGLE} and \.{CWEAVE}.
+
+@<Predecl...@>=
+boolean get_line(void);@/
+name_pointer id_lookup(const char *,const char *,char);@/
+name_pointer section_lookup(char *,char *,int);@/
+void check_complete(void);@/
+void common_init(void);@/
+void print_prefix_name(name_pointer);@/
+void print_section_name(name_pointer);@/
+void reset_input(void);@/
+void sprint_section_name(char *,name_pointer);@/
+
+@ The following functions are private to |"common.w"|.
+
+@<Predecl...@>=
+static boolean input_ln(FILE *);@/
+static int web_strcmp(char *,int,char *,int);@/
+static name_pointer add_section_name(name_pointer,int,char *,char *,int);@/
+static void extend_section_name(name_pointer,char *,char *,int);@/
+static void check_change(void);@/
+static void prime_the_change_buffer(void);@/
+
+@* Standard C library interfaces.  This updated version of \.{CWEB} uses
+standard C types for boolean values, pointers, and objects with fixed sizes.
+
+@<Include files@>=
+#include <stdbool.h> /* type definition of |bool| */
+#include <stddef.h> /* type definition of |ptrdiff_t| */
+#include <stdint.h> /* type definition of |uint8_t| et al. */
+
+@ The |scan_args| and |cb_show_banner| routines and the |bindtextdomain|
+argument string need a few extra variables.
+
+@s string int
+
+@d max_banner 50
+
+@d PATH_SEPARATOR   separators[0]
+@d DIR_SEPARATOR    separators[1]
+@d DEVICE_SEPARATOR separators[2]
+
+@<Other...@>=
+char cb_banner[max_banner];@/
+string texmf_locale;@/
+#ifndef SEPARATORS
+#define SEPARATORS "://"
+#endif
+char separators[]=SEPARATORS;
+
+@* Temporary file output.  Before we leave the program we have to make
+sure that the output files are correctly written.
+
+@<Remove the temporary file...@>=
+if(C_file) fclose(C_file);
+if(tex_file) fclose(tex_file);
+if(check_file) fclose(check_file);
+if(strlen(check_file_name)) /* Delete the temporary file in case of a break */
+   remove(check_file_name);
+
+@* Internationalization.  You may have noticed that almost all \.{"strings"}
+in the \.{CWEB} sources are placed in the context of the `|_|'~macro.
+This is just a shortcut for the `|gettext|' function from the ``GNU~gettext
+utilities.'' For systems that do not have this library installed, we wrap
+things for neutral behavior without internationalization.
+
+@d _(STRING) gettext(STRING)
+
+@<Include files@>=
+#include <locale.h>
+@#
+#ifndef HAVE_GETTEXT
+#define HAVE_GETTEXT 0
+#endif
+@#
+#if HAVE_GETTEXT
+#include <libintl.h>
+#else
+#define bindtextdomain(A,B) ""
+#define textdomain(A) ""
+#define gettext(A) A
+#endif
+
+@ If translation catalogs for your personal \.{LANGUAGE} are installed at the
+appropriate place, \.{CTANGLE} and \.{CWEAVE} will talk to you in your favorite
+language.  Catalog \.{cweb} contains all strings from ``plain \.{CWEB},''
+catalog \.{cweb-tl} contains a few extra strings specific to the \TeX~Live
+interface, and catalog \.{web2c-help} contains the ``\.{--help}'' texts for
+\.{CTANGLE} and \.{CWEAVE}.
+@.cweb.mo@>
+@.cweb-tl.mo@>
+@.web2c-help.mo@>
+@.--help@>
+
+If such translation files are not available, you may want to improve this
+system by checking out the sources and translating the strings in files
+\.{cweb.pot}, \.{cweb-tl.pot}, and \.{web2c-help.pot}, and submitting the
+resulting \.{*.po} files to the maintainers at \.{tex-k@@tug.org}.
+
+\medskip \noindent \&{Note to maintainers:} \.{CWEB} in \TeX~Live generally
+does \\{not} set |HAVE_GETTEXT| at build-time, so \.{i18n} is ``off'' by
+default.  If you want to create \.{CWEB} executables with NLS support, you
+have to recompile the \TeX~Live sources with a positive value for
+|HAVE_GETTEXT| both in \.{"comm-w2c.ch"} and \.{"comm-w2c.h"}.  Also you
+have to ``compile'' the NLS catalogs provided for \.{CWEB} in the source
+tree with \.{msgfmt} and store the resulting \.{.mo} files at an appropriate
+place in the file system.
+
+Plans for \TeX~Live are to store NLS catalogs inside the ``\TeX\ Directory
+Structure'' (TDS) and look them up with the help of the configuration variable
+``|TEXMFLOCALEDIR|,'' which should contain a single absolute path definition.
+Below we use the \Kpathsea/ function |kpse_var_expand| to evaluate this
+variable from various origins and redirect the ``GNU~gettext utilities''
+to a possibly different location than the canonical \.{/usr/share/locale}.
+
+There are several ways to set |TEXMFLOCALEDIR|:
+\smallskip
+{\parindent5em
+\item{(a)} a user-set environment variable \.{TEXMFLOCALEDIR}\hfil\break
+    (overridden by \.{TEXMFLOCALEDIR\_cweb});
+\item{(b)} a line in \Kpathsea/ configuration file \.{texmf.cnf},\hfil\break
+    e.g., \.{TEXMFLOCALEDIR=\$TEXMFMAIN/locale}\hfil\break
+    or \.{TEXMFLOCALEDIR.cweb=\$TEXMFMAIN/locale}.\par}
+
+@<Set locale...@>=
+setlocale(LC_MESSAGES, setlocale(LC_CTYPE, ""));
+texmf_locale = kpse_var_expand ("${TEXMFLOCALEDIR}");
+
+bindtextdomain("cweb",
+  bindtextdomain("cweb-tl",
+    bindtextdomain("web2c-help", @|
+      strcmp(texmf_locale, "") ?
+        texmf_locale : "/usr/share/locale")));
+
+free(texmf_locale);
+textdomain("cweb"); /* the majority of |"strings"| come from ``plain \.{CWEB}'' */
+@.cweb.mo@>
+
+@* File lookup with \Kpathsea/.  The \.{CTANGLE} and \.{CWEAVE} programs from
+the original \.{CWEB} package use the compile-time default directory or the
+value of the environment variable \.{CWEBINPUTS} as an alternative place to be
+searched for files, if they could not be found in the current directory.
+
+This version uses the \Kpathsea/ mechanism for searching files.
+The directories to be searched for come from three sources:
+\smallskip
+{\parindent5em
+\item{(a)} a user-set environment variable \.{CWEBINPUTS}
+    (overridden by \.{CWEBINPUTS\_cweb});
+\item{(b)} a line in \Kpathsea/ configuration file \.{texmf.cnf},\hfil\break
+    e.g., \.{CWEBINPUTS=\$TEXMFDOTDIR:\$TEXMF/texmf/cweb//}\hfil\break
+    or \.{CWEBINPUTS.cweb=\$TEXMFDOTDIR:\$TEXMF/texmf/cweb//};
+\item{(c)} compile-time default directories (specified in
+    \.{texmf.in}),\hfil\break
+    i.e., \.{\$TEXMFDOTDIR:\$TEXMF/texmf/cweb//}.\par}
+
+@d kpse_find_cweb(name) kpse_find_file(name,kpse_cweb_format,true)
+
+@<Include files@>=
+typedef bool boolean;
+#define HAVE_BOOLEAN
+#include <kpathsea/kpathsea.h> /* include every \Kpathsea/ header */
+#include <w2c/config.h> /* \&{integer} */
+#include <lib/lib.h> /* |versionstring| */
+@#
+#define CWEB
+#include "help.h"
+
+@ We set |kpse_program_name| to `\.{cweb}'.  This means if the variable
+\.{CWEBINPUTS.cweb} is present in \.{texmf.cnf} (or \.{CWEBINPUTS\_cweb}
+in the environment) its value will be used as the search path for filenames.
+This allows different flavors of \.{CWEB} to have different search paths.
 
-@(cweb.h@>=
-@=/* Prototypes for functions, either@>
-@= * declared in common.w and used in ctangle.w and cweave.w, or@>
-@= * used in common.w and declared in ctangle.w and cweave.w.  */@>
-@<External functions@>@;
-extern const char *versionstring;
+@<Set up |PROGNAME| feature and initialize the search path mechanism@>=
+kpse_set_program_name(argv[0], "cweb");
+
+@ When the files you expect are not found, the thing to do is to enable
+`kpathsea' runtime debugging by assigning to the |kpathsea_debug| variable a
+small number via the `\.{-d}' option. The meaning of this number is shown
+below. To set more than one debugging option, simply sum the corresponding
+numbers.
+\medskip
+\halign{\hskip5em\tt\hfil#&&\qquad\rm#\hfil\cr
+ 1&report `\.{stat}' calls\cr
+ 2&report lookups in all hash tables\cr
+ 4&report file openings and closings\cr
+ 8&report path information\cr
+16&report directory list\cr
+32&report on each file search\cr
+64&report values of variables being looked up\cr}
+\medskip
+Debugging output is always written to |stderr|, and begins with the string
+`\.{kdebug:}'.
 
-@** System dependent changes.
+@* System dependent changes. The most volatile stuff comes at the very end.
 
 @ Modules for dealing with help messages and version info.
 
-@<Display help message and exit@>=
-usagehelp(program==ctangle ? CTANGLEHELP : CWEAVEHELP, NULL);
+@<Display help message and |exit|@>=
+cb_usagehelp(program==ctangle ? CTANGLEHELP :
+  program==cweave ? CWEAVEHELP : CTWILLHELP, NULL);
 @.--help@>
 
-@ Will have to change these if the version numbers change (ouch).
+@ Special variants from \Kpathsea/ for i18n/t10n.
+We simply filter the strings through the catalogs (if available).
 
-@d ctangle_banner "This is CTANGLE, Version 3.64"
-@d cweave_banner "This is CWEAVE, Version 3.64"
+@c
+static void cb_usage (const_string str)
+{
+  textdomain("cweb-tl");
+@.cweb-tl.mo@>
+  fprintf(stderr, _("%s: Need one to three file arguments.\n"), str);
+  fprintf(stderr, _("Try `%s --help' for more information.\n"), str);
+@.--help@>
+  textdomain("cweb");
+@.cweb.mo@>
+  history=fatal_message; exit(wrap_up());
+}
+
+static void cb_usagehelp (const_string *message, const_string bug_email)
+{
+  if (!bug_email)
+    bug_email = "tex-k@@tug.org";
+  textdomain("web2c-help");
+@.web2c-help.mo@>
+  while (*message) {
+    printf("%s\n", strcmp("", *message) ? _(*message) : *message);
+    ++message;
+  }
+  textdomain("cweb-tl");
+@.cweb-tl.mo@>
+  printf(_("\nEmail bug reports to %s.\n"), bug_email);
+  textdomain("cweb");
+@.cweb.mo@>
+  history=spotless; exit(wrap_up());
+}
 
-@<Display version information and exit@>=
-printversionandexit((program==ctangle ? ctangle_banner : cweave_banner),
-  "Silvio Levy and Donald E. Knuth", NULL, NULL);
+@ The version information will not be translated, it uses a generic text
+template in English.
+
+@<Display version information and |exit|@>=
+printversionandexit(cb_banner,
+  program == ctwill ? "Donald E. Knuth" : "Silvio Levy and Donald E. Knuth",
+  NULL, NULL);
 @.--version@>
 
+@ But the ``banner'' is, at least the first part.
+
+@c
+void cb_show_banner (void)
+{
+  assert(cb_banner[0]!='\0');
+  textdomain("cweb-tl");
+@.cweb-tl.mo@>
+  printf("%s%s\n", _(cb_banner), versionstring);
+  textdomain("cweb");
+@.cweb.mo@>
+}
+
+@ @<Predecl...@>=
+static void cb_usage (const_string str);@/
+static void cb_usagehelp (const_string *message, const_string bug_email);@/
+void cb_show_banner (void); /* |extern| for option \.{+b} */
+
 @** Index.
 @z
diff --git a/source/texk/web2c/cwebdir/comm-w2c.h b/source/texk/web2c/cwebdir/comm-w2c.h
new file mode 100644
index 0000000000000000000000000000000000000000..2c8e2868a599b24682ae807788c5c3e7c388e12f
--- /dev/null
+++ b/source/texk/web2c/cwebdir/comm-w2c.h
@@ -0,0 +1,225 @@
+% This file is part of CWEB.
+% This program by Silvio Levy and Donald E. Knuth
+% is based on a program by Knuth.
+% It is distributed WITHOUT ANY WARRANTY, express or implied.
+% Version 3.64 --- February 2017 (works also with later versions)
+
+% Copyright (C) 1987,1990,1993 Silvio Levy and Donald E. Knuth
+
+% Permission is granted to make and distribute verbatim copies of this
+% document provided that the copyright notice and this permission notice
+% are preserved on all copies.
+
+% Permission is granted to copy and distribute modified versions of this
+% document under the conditions for verbatim copying, provided that the
+% entire resulting derived work is distributed under the terms of a
+% permission notice identical to this one.
+
+% Amendments to 'common.h' resulting in this extended 'comm-foo.h' were
+% created by numerous collaborators over the course of many years.
+
+% Please send comments, suggestions, etc. to tex-k@@tug.org.
+
+% The next few sections contain stuff from the file |"common.w"| that has
+% to be included in both |"ctangle.w"| and |"cweave.w"|. It appears in this
+% file |"common.h"|, which needs to be updated when |"common.w"| changes.
+
+First comes general stuff:
+
+@d ctangle 0
+@d cweave 1
+@d ctwill 2
+
+@s boolean int
+@s uint8_t int
+@s uint16_t int
+
+@<Common code for \.{CWEAVE} and \.{CTANGLE}@>=
+typedef bool boolean;
+typedef uint8_t eight_bits;
+typedef uint16_t sixteen_bits;
+extern int program; /* \.{CWEAVE} or \.{CTANGLE} or \.{CTWILL}? */
+extern int phase; /* which phase are we in? */
+
+@ @d _(STRING) gettext(STRING)
+@<Include files@>=
+#ifndef HAVE_GETTEXT
+#define HAVE_GETTEXT 0
+#endif
+@#
+#if HAVE_GETTEXT
+#include <libintl.h>
+#else
+#define gettext(A) A
+#endif
+@#
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+
+@ Code related to the character set:
+@^ASCII code dependencies@>
+
+@d and_and 04 /* `\.{\&\&}'\,; corresponds to MIT's {\tentex\char'4} */
+@d lt_lt 020 /* `\.{<<}'\,;  corresponds to MIT's {\tentex\char'20} */
+@d gt_gt 021 /* `\.{>>}'\,;  corresponds to MIT's {\tentex\char'21} */
+@d plus_plus 013 /* `\.{++}'\,;  corresponds to MIT's {\tentex\char'13} */
+@d minus_minus 01 /* `\.{--}'\,;  corresponds to MIT's {\tentex\char'1} */
+@d minus_gt 031 /* `\.{->}'\,;  corresponds to MIT's {\tentex\char'31} */
+@d non_eq 032 /* `\.{!=}'\,;  corresponds to MIT's {\tentex\char'32} */
+@d lt_eq 034 /* `\.{<=}'\,;  corresponds to MIT's {\tentex\char'34} */
+@d gt_eq 035 /* `\.{>=}'\,;  corresponds to MIT's {\tentex\char'35} */
+@d eq_eq 036 /* `\.{==}'\,;  corresponds to MIT's {\tentex\char'36} */
+@d or_or 037 /* `\.{\v\v}'\,;  corresponds to MIT's {\tentex\char'37} */
+@d dot_dot_dot 016 /* `\.{...}'\,;  corresponds to MIT's {\tentex\char'16} */
+@d colon_colon 06 /* `\.{::}'\,;  corresponds to MIT's {\tentex\char'6} */
+@d period_ast 026 /* `\.{.*}'\,;  corresponds to MIT's {\tentex\char'26} */
+@d minus_gt_ast 027 /* `\.{->*}'\,;  corresponds to MIT's {\tentex\char'27} */
+
+@<Common code...@>=
+char section_text[longest_name+1]; /* name being sought for */
+char *section_text_end = section_text+longest_name; /* end of |section_text| */
+char *id_first; /* where the current identifier begins in the buffer */
+char *id_loc; /* just after the current identifier in the buffer */
+
+@ Code related to input routines:
+
+@d xisalpha(c) (isalpha((eight_bits)c)&&((eight_bits)c<0200))
+@d xisdigit(c) (isdigit((eight_bits)c)&&((eight_bits)c<0200))
+@d xisspace(c) (isspace((eight_bits)c)&&((eight_bits)c<0200))
+@d xislower(c) (islower((eight_bits)c)&&((eight_bits)c<0200))
+@d xisupper(c) (isupper((eight_bits)c)&&((eight_bits)c<0200))
+@d xisxdigit(c) (isxdigit((eight_bits)c)&&((eight_bits)c<0200))
+
+@<Common code...@>=
+extern char buffer[]; /* where each line of input goes */
+extern char *buffer_end; /* end of |buffer| */
+extern char *loc; /* points to the next character to be read from the buffer*/
+extern char *limit; /* points to the last character in the buffer */
+
+@ Code related to identifier and section name storage:
+@d length(c) (size_t)((c+1)->byte_start-(c)->byte_start) /* the length of a name */
+@d print_id(c) term_write((c)->byte_start,length((c))) /* print identifier */
+@d llink link /* left link in binary search tree for section names */
+@d rlink dummy.Rlink /* right link in binary search tree for section names */
+@d root name_dir->rlink /* the root of the binary search tree
+  for section names */
+@d chunk_marker 0
+
+@<Common code...@>=
+typedef struct name_info {
+  char *byte_start; /* beginning of the name in |byte_mem| */
+  struct name_info *link;
+  union {
+    struct name_info *Rlink; /* right link in binary search tree for section
+      names */
+    char Ilk; /* used by identifiers in \.{CWEAVE} only */
+  } dummy;
+  void *equiv_or_xref; /* info corresponding to names */
+} name_info; /* contains information about an identifier or section name */
+typedef name_info *name_pointer; /* pointer into array of \&{name\_info}s */
+typedef name_pointer *hash_pointer;
+extern char byte_mem[]; /* characters of names */
+extern char *byte_mem_end; /* end of |byte_mem| */
+extern name_info name_dir[]; /* information about names */
+extern name_pointer name_dir_end; /* end of |name_dir| */
+extern name_pointer name_ptr; /* first unused position in |name_dir| */
+extern char *byte_ptr; /* first unused position in |byte_mem| */
+extern name_pointer hash[]; /* heads of hash lists */
+extern hash_pointer hash_end; /* end of |hash| */
+extern hash_pointer h; /* index into hash-head array */
+extern boolean names_match(name_pointer,const char *,size_t,eight_bits);@/
+extern name_pointer id_lookup(const char *,const char *,char);
+   /* looks up a string in the identifier table */
+extern name_pointer section_lookup(char *,char *,int); /* finds section name */
+extern void init_node(name_pointer);@/
+extern void init_p(name_pointer,eight_bits);@/
+extern void print_prefix_name(name_pointer);@/
+extern void print_section_name(name_pointer);@/
+extern void sprint_section_name(char *,name_pointer);@/
+
+@ Code related to error handling:
+@d spotless 0 /* |history| value for normal jobs */
+@d harmless_message 1 /* |history| value when non-serious info was printed */
+@d error_message 2 /* |history| value when an error was noted */
+@d fatal_message 3 /* |history| value when we had to stop prematurely */
+@d mark_harmless {if (history==spotless) history=harmless_message;}
+@d mark_error history=error_message
+@d confusion(s) fatal(_("! This can't happen: "),s)
+
+@<Common...@>=
+extern int history; /* indicates how bad this run was */
+extern int wrap_up(void); /* indicate |history| and exit */
+extern void err_print(const char *); /* print error message and context */
+extern void fatal(const char *,const char *); /* issue error message and die */
+extern void overflow(const char *); /* succumb because a table has overflowed */
+
+@ Code related to file handling:
+@f line x /* make |line| an unreserved word */
+@d max_file_name_length 1024
+@d cur_file file[include_depth] /* current file */
+@d cur_file_name file_name[include_depth] /* current file name */
+@d web_file_name file_name[0] /* main source file name */
+@d cur_line line[include_depth] /* number of current line in current file */
+
+@<Common code...@>=
+extern int include_depth; /* current level of nesting */
+extern FILE *file[]; /* stack of non-change files */
+extern FILE *change_file; /* change file */
+extern char C_file_name[]; /* name of |C_file| */
+extern char tex_file_name[]; /* name of |tex_file| */
+extern char idx_file_name[]; /* name of |idx_file| */
+extern char scn_file_name[]; /* name of |scn_file| */
+extern char check_file_name[]; /* name of |check_file| */
+extern char file_name[][max_file_name_length];
+  /* stack of non-change file names */
+extern char change_file_name[]; /* name of change file */
+extern int line[]; /* number of current line in the stacked files */
+extern int change_line; /* number of current line in change file */
+extern int change_depth; /* where \.{@@y} originated during a change */
+extern boolean input_has_ended; /* if there is no more input */
+extern boolean changing; /* if the current line is from |change_file| */
+extern boolean web_file_open; /* if the web file is being read */
+extern boolean get_line(void); /* inputs the next line */
+extern void check_complete(void); /* checks that all changes were picked up */
+extern void reset_input(void); /* initialize to read the web file and change file */
+
+@ Code related to section numbers:
+@<Common code...@>=
+extern sixteen_bits section_count; /* the current section number */
+extern boolean changed_section[]; /* is the section changed? */
+extern boolean change_pending; /* is a decision about change still unclear? */
+extern boolean print_where; /* tells \.{CTANGLE} to print line and file info */
+
+@ Code related to command line arguments:
+@d show_banner flags['b'] /* should the banner line be printed? */
+@d show_progress flags['p'] /* should progress reports be printed? */
+@d show_happiness flags['h'] /* should lack of errors be announced? */
+@d make_xrefs flags['x'] /* should cross references be output? */
+
+@<Common code...@>=
+extern int argc; /* copy of |ac| parameter to |main| */
+extern char **argv; /* copy of |av| parameter to |main| */
+extern boolean flags[]; /* an option for each 7-bit code */
+
+@ Code relating to output:
+@d update_terminal fflush(stdout) /* empty the terminal output buffer */
+@d new_line putchar('\n') @d putxchar putchar
+@d term_write(a,b) fflush(stdout),fwrite(a,sizeof(char),b,stdout)
+@d C_printf(c,a) fprintf(C_file,c,a)
+@d C_putc(c) putc(c,C_file)
+
+@<Common code...@>=
+extern FILE *C_file; /* where output of \.{CTANGLE} goes */
+extern FILE *tex_file; /* where output of \.{CWEAVE} goes */
+extern FILE *idx_file; /* where index from \.{CWEAVE} goes */
+extern FILE *scn_file; /* where list of sections from \.{CWEAVE} goes */
+extern FILE *check_file; /* temporary output file */
+extern FILE *active_file; /* currently active file for \.{CWEAVE} output */
+
+@ The procedure that gets everything rolling:
+
+@<Common code...@>=
+extern void common_init(void);@/
+extern void print_stats(void);@/
+extern void cb_show_banner(void);@/
diff --git a/source/texk/web2c/cwebdir/ctang-w2c.ch b/source/texk/web2c/cwebdir/ctang-w2c.ch
index 133509afb3700e5a6828d284349b9506abc07a21..c525c88bd37ea1bb3d433d6074464839e4d58e53 100644
--- a/source/texk/web2c/cwebdir/ctang-w2c.ch
+++ b/source/texk/web2c/cwebdir/ctang-w2c.ch
@@ -1,50 +1,45 @@
-% Original Kpathsea changes for CWEB by Wlodek Bzyl and Olaf Weber
-% This file is in the Public Domain.
+@q Changes for CWEB in TeX Live from numerous contributors. @>
+@q This file is in the Public Domain. @>
 
-@x l.27
-\def\title{CTANGLE (Version 3.64)}
-\def\topofcontents{\null\vfill
-  \centerline{\titlefont The {\ttitlefont CTANGLE} processor}
-  \vskip 15pt
-  \centerline{(Version 3.64)}
-  \vfill}
-@y
-\def\title{CTANGLE (Version 3.64k)}
-\def\topofcontents{\null\vfill
-  \centerline{\titlefont The {\ttitlefont CTANGLE} processor}
-  \vskip 15pt
-  \centerline{(Version 3.64k)}
-  \vfill}
-@z
+@q Most of the original Kpathsea changes by Wlodek Bzyl and Olaf Weber @>
+@q were merged with the set of change files of the CWEBbin project; @>
+@q see https://github.com/ascherer/cwebbin for the original parts. @>
 
-This change can not be applied when `tie' is  used
-(TOC file can not be typeset).
+@q This stripped change file {comm,ctang,cweav,ctwill}-w2c.ch has been @>
+@q created from the set of change files {comm,ctang,cweav}-patch.ch, @>
+@q {comm,ctang,cweav}-ansi.ch, {comm,ctang,cweav}-extensions.ch, @>
+@q {comm,ctang,cweav}-output.ch, {comm,ctang,cweav}-i18n.ch, and @>
+@q cweav-twill.ch for CTWILL, and {comm,ctang,cweav,ctwill}-texlive.ch @>
+@q with the 'tie' processor and is used as a monolithic changefile for @>
+@q {common,ctangle,cweave}.w in TeX Live. @>
 
-%@x l.48
-%\let\maybe=\iftrue
-%@y
-%\let\maybe=\iffalse % print only sections that change
-%@z
+@q Please send comments, suggestions, etc. to tex-k@@tug.org. @>
 
+@x
+\def\title{CTANGLE (Version 3.64)}
+@y
+\def\title{CTANGLE (Version 3.64 [\TeX~Live])}
+@z
 
-Section 1.
+@x
+  \centerline{(Version 3.64)}
+@y
+  \centerline{(Version 3.64 [\TeX~Live])}
+@z
 
-@x l.49
-The ``banner line'' defined here should be changed whenever \.{CTANGLE}
-is modified.
+@x
+@s not_eq normal @q unreserve a C++ keyword @>
+@y
+@z
 
+@x
 @d banner "This is CTANGLE (Version 3.64)\n"
 @y
-The ``banner line'' defined here should be changed whenever \.{CTANGLE}
-is modified.
-
 @d banner "This is CTANGLE, Version 3.64"
+  /* will be extended by the \TeX~Live |versionstring| */
 @z
 
-
-Section 2.
-
-@x l.72
+@x
 @ We predeclare several standard system functions here instead of including
 their system header files, because the names of the header files are not as
 standard as the names of the functions. (For example, some \CEE/ environments
@@ -57,33 +52,38 @@ extern char* strcpy(); /* copy one string to another */
 extern int strncmp(); /* compare up to $n$ string characters */
 extern char* strncpy(); /* copy up to $n$ string characters */
 @y
-@z
+@ For string handling we include the {\mc ANSI C} system header file instead
+of predeclaring the standard system functions |strlen|, |strcmp|, |strcpy|,
+|strncmp|, and |strncpy|.
+@^system dependencies@>
 
-Section 3.
+@<Include files@>=
+#include <string.h>
+@z
 
-@x l.92
+@x
 int main (ac, av)
 int ac;
 char **av;
 @y
-int main (int ac, char **av)
+int main (
+int ac,
+char **av)
 @z
 
-@x l.100 - Add Web2C version to banner.
+@x
   if (show_banner) printf(banner); /* print a ``banner line'' */
 @y
-  if (show_banner) {
-    printf("%s%s\n", banner, versionstring); /* print a ``banner line'' */
-  }
+  if (show_banner) cb_show_banner(); /* print a ``banner line'' */
 @z
 
-@x l.112
+@x
 @d max_bytes 90000 /* the number of bytes in identifiers,
 @y
 @d max_bytes 1000000 /* the number of bytes in identifiers,
 @z
 
-@x l.114
+@x
 @d max_toks 270000 /* number of bytes in compressed \CEE/ code */
 @d max_names 4000 /* number of identifiers, strings, section names;
 @y
@@ -91,7 +91,7 @@ int main (int ac, char **av)
 @d max_names 10239 /* number of identifiers, strings, section names;
 @z
 
-@x l.117
+@x
 @d max_texts 2500 /* number of replacement texts, must be less than 10240 */
 @d hash_size 353 /* should be prime; used in |"common.w"| */
 @y
@@ -99,194 +99,159 @@ int main (int ac, char **av)
 @d hash_size 8501 /* should be prime; used in |"common.w"| */
 @z
 
-@x l.121
+@x
 @d buf_size 100 /* for \.{CWEAVE} and \.{CTANGLE} */
 @y
 @d buf_size 1000 /* for \.{CWEAVE} and \.{CTANGLE} */
 @z
 
-Section 5.
-
-@x common.h l.30 - boolean comes from kpathsea.
-typedef short boolean;
+@x
+@i common.h
 @y
+@i comm-w2c.h
 @z
 
-Section 6.
-
-@x common.h l.36
-#include <stdio.h>
+@x
+the array |text_info|, and we use a |text_pointer| variable to refer
 @y
-#include <kpathsea/kpathsea.h>
-#include <stdio.h>
+the array |text_info|, and we use a \&{text\_pointer} variable to refer
 @z
 
-@x common.h l.65
-@d xisalpha(c) (isalpha(c)&&((eight_bits)c<0200))
-@d xisdigit(c) (isdigit(c)&&((eight_bits)c<0200))
-@d xisspace(c) (isspace(c)&&((eight_bits)c<0200))
-@d xislower(c) (islower(c)&&((eight_bits)c<0200))
-@d xisupper(c) (isupper(c)&&((eight_bits)c<0200))
-@d xisxdigit(c) (isxdigit(c)&&((eight_bits)c<0200))
+@x
+If your machine does not support |unsigned char| you should change
+the definition of \&{eight\_bits} to |unsigned short|.
+@^system dependencies@>
 @y
-@d xisalpha(c) (isalpha((eight_bits)c)&&((eight_bits)c<0200))
-@d xisdigit(c) (isdigit((eight_bits)c)&&((eight_bits)c<0200))
-@d xisspace(c) (isspace((eight_bits)c)&&((eight_bits)c<0200))
-@d xislower(c) (islower((eight_bits)c)&&((eight_bits)c<0200))
-@d xisupper(c) (isupper((eight_bits)c)&&((eight_bits)c<0200))
-@d xisxdigit(c) (isxdigit((eight_bits)c)&&((eight_bits)c<0200))
 @z
 
-Section 9.
-
-@x common.h l.109 - protos now all in cweb.h.
-extern name_pointer id_lookup(); /* looks up a string in the identifier table */
-extern name_pointer section_lookup(); /* finds section name */
-extern void print_section_name(), sprint_section_name();
+@x
+name_dir->equiv=(char *)text_info; /* the undefined section has no replacement text */
 @y
-#include "cweb.h"
+init_node(name_dir); /* the undefined section has no replacement text */
 @z
 
-Section 10.
-
-@x common.h l.123 - explicit types, protos now all in cweb.h.
-extern history; /* indicates how bad this run was */
-extern err_print(); /* print error message and context */
-extern wrap_up(); /* indicate |history| and exit */
-extern void fatal(); /* issue error message and die */
-extern void overflow(); /* succumb because a table has overflowed */
-@y
-extern int history; /* indicates how bad this run was */
-@z
-
-Section 11.
-
-@x common.h l.131 - max_file_name_length is way too small.
-@d max_file_name_length 60
-@y
-@d max_file_name_length 1024
-@z
-
-@x common.h l.138 - explicit types.
-extern include_depth; /* current level of nesting */
-@y
-extern int include_depth; /* current level of nesting */
-@z
-
-@x common.h l.148 - explicit types.
-extern line[]; /* number of current line in the stacked files */
-extern change_line; /* number of current line in change file */
-extern change_depth; /* where \.{@@y} originated during a change */
-@y
-extern int line[]; /* number of current line in the stacked files */
-extern int change_line; /* number of current line in change file */
-extern int change_depth; /* where \.{@@y} originated during a change */
-@z
-
-@x common.h l.153 - protos now all in cweb.h.
-extern reset_input(); /* initialize to read the web file and change file */
-extern get_line(); /* inputs the next line */
-extern check_complete(); /* checks that all changes were picked up */
-@y
-@z
-
-Section 15.
-
-@x common.h l.192 - protos now all in cweb.h.
-extern void common_init();
-@y
-@z
-
-Section 21.
-
-@x l.184
+@x
 int names_match(p,first,l)
 name_pointer p; /* points to the proposed match */
 char *first; /* position of first character of string */
 int l; /* length of identifier */
+{
 @y
-int names_match (name_pointer p, const char *first, int l, char t)
+boolean names_match(@t\1\1@>
+name_pointer p, /* points to the proposed match */
+const char *first, /* position of first character of string */
+size_t l, /* length of identifier */
+eight_bits t@t\2\2@>) /* not used by \.{TANGLE} */
+{@+(void)t;
 @z
 
-Section 22.
-
-@x l.200
+@x
+void
 init_node(node)
 name_pointer node;
 @y
-init_node (name_pointer node)
+void
+init_node(
+name_pointer node)
 @z
 
-@x l.207
-init_p() {}
+@x
+    node->equiv=(char *)text_info;
 @y
-init_p (name_pointer p, char t) {}
+    node->equiv=(void *)text_info;
 @z
 
-Section 26.
+@x
+void
+init_p() {}
+@y
+void
+init_p(name_pointer p,eight_bits t) {@+(void)p;@+(void)t;@+}
+@z
 
-@x l.261
+@x
 void
 store_two_bytes(x)
 sixteen_bits x;
 @y
 static void
-store_two_bytes (sixteen_bits x)
+store_two_bytes(
+sixteen_bits x)
 @z
 
-Section 30.
+@x
+  if (tok_ptr+2>tok_mem_end) overflow("token");
+@y
+  if (tok_ptr+2>tok_mem_end) overflow(_("token"));
+@z
 
-@x l.337
+@x
 void
 push_level(p) /* suspends the current level */
 name_pointer p;
 @y
 static void
-push_level (name_pointer p) /* suspends the current level */
+push_level(@t\1\1@> /* suspends the current level */
+name_pointer p@t\2\2@>)
 @z
 
-Section 31.
+@x
+  if (stack_ptr==stack_end) overflow("stack");
+@y
+  if (stack_ptr==stack_end) overflow(_("stack"));
+@z
 
-@x l.356
+@x
 void
 pop_level(flag) /* do this when |cur_byte| reaches |cur_end| */
 int flag; /* |flag==0| means we are in |output_defs| */
 @y
 static void
-pop_level (int flag) /* do this when |cur_byte| reaches |cur_end| */
+pop_level(@t\1\1@> /* do this when |cur_byte| reaches |cur_end| */
+int flag@t\2\2@>) /* |flag==0| means we are in |output_defs| */
 @z
 
-Section 33.
-
-@x l.392
+@x
 void
 get_output() /* sends next token to |out_char| */
 @y
 static void
-get_output (void) /* sends next token to |out_char| */
+get_output(void) /* sends next token to |out_char| */
+@z
+
+@x
+  if ((a+name_dir)->equiv!=(char *)text_info) push_level(a+name_dir);
+@y
+  if ((a+name_dir)->equiv!=(void *)text_info) push_level(a+name_dir);
 @z
 
-Section 37.
+@x
+    printf("\n! Not present: <");
+@y
+    fputs(_("\n! Not present: <"),stdout);
+@z
 
-@x l.482
+@x
 void
 flush_buffer() /* writes one line to output file */
 @y
 static void
-flush_buffer (void) /* writes one line to output file */
+flush_buffer(void) /* writes one line to output file */
 @z
 
-Section 41.
+@x
+      overflow("output files");
+@y
+      overflow(_("output files"));
+@z
 
-@x l.534
+@x
 void phase_two();
 @y
-static void phase_two (void);
+static void phase_two(void);@/
 @z
 
-Section 42.
-
-@x l.537
+@x
 void
 phase_two () {
 @y
@@ -294,116 +259,323 @@ static void
 phase_two (void) {
 @z
 
-Section 43.
+@x
+    printf("\n! No program text was specified."); mark_harmless;
+@y
+    fputs(_("\n! No program text was specified."),stdout); mark_harmless;
+@z
 
-@x l.577 Use binary mode for output files
-    C_file=fopen(output_file_name,"w");
+@x
+        printf("\nWriting the output file (%s):",C_file_name);
 @y
-    C_file=fopen(output_file_name,"wb");
+        printf(_("\nWriting the output file (%s):"),C_file_name);
 @z
 
-Section 46.
+@x
+        printf("\nWriting the output files:");
+@y
+        fputs(_("\nWriting the output files:"),stdout);
+@z
 
-@x l.603
-void output_defs();
+@x
+    if(show_happiness) printf("\nDone.");
 @y
-static void output_defs (void);
+    if (show_happiness) {
+      if (show_progress) new_line;
+      fputs(_("Done."),stdout);
+    }
 @z
 
-Section 47.
+@x
+@<Write all the named output files@>=
+for (an_output_file=end_output_files; an_output_file>cur_out_file;) {
+    an_output_file--;
+    sprint_section_name(output_file_name,*an_output_file);
+    fclose(C_file);
+    C_file=fopen(output_file_name,"w");
+    if (C_file ==0) fatal("! Cannot open output file:",output_file_name);
+@.Cannot open output file@>
+    printf("\n(%s)",output_file_name); update_terminal;
+    cur_line=1;
+    stack_ptr=stack+1;
+    cur_name= (*an_output_file);
+    cur_repl= (text_pointer)cur_name->equiv;
+    cur_byte=cur_repl->tok_start;
+    cur_end=(cur_repl+1)->tok_start;
+    while (stack_ptr > stack) get_output();
+    flush_buffer();
+}
+@y
+@<Write all the named output files@>=
+fclose(C_file); C_file=NULL;
+@<Update the primary result when it has changed@>@;
+for (an_output_file=end_output_files; an_output_file>cur_out_file;) {
+    an_output_file--;
+    sprint_section_name(output_file_name,*an_output_file);
+    if((C_file=fopen(check_file_name,"wb"))==NULL)
+      fatal(_("! Cannot open output file "),check_file_name);
+@.Cannot open output file@>
+    printf("\n(%s)",output_file_name); update_terminal;
+    cur_line=1;
+    stack_ptr=stack+1;
+    cur_name= (*an_output_file);
+    cur_repl= (text_pointer)cur_name->equiv;
+    cur_byte=cur_repl->tok_start;
+    cur_end=(cur_repl+1)->tok_start;
+    while (stack_ptr > stack) get_output();
+    flush_buffer(); fclose(C_file); C_file=NULL;
+    @<Update the secondary results when they have changed@>@;
+}
+strcpy(check_file_name,""); /* We want to get rid of the temporary file */
+@z
+
+@x
+void output_defs();
+@y
+static void output_defs(void);@/
+@z
 
-@x l.606
+@x
 void
 output_defs()
 @y
 static void
-output_defs (void)
+output_defs(void)
 @z
 
-Section 48.
+@x
+          else if (a<050000) { confusion("macro defs have strange char");}
+@y
+          else if (a<050000) { confusion(_("macro defs have strange char"));}
+@z
 
-@x l.649
+@x
 static void out_char();
 @y
-static void out_char (eight_bits);
+static void out_char(eight_bits);@/
 @z
 
-Section 49.
-
-@x l.653
+@x
+static void
 out_char(cur_char)
 eight_bits cur_char;
 @y
-out_char (eight_bits cur_char)
-@z
-
-Section 58.
-
-@x l.814
+static void
+out_char(
+eight_bits cur_char)
+@z
+
+@x
+@ @<Cases like \.{!=}@>=
+case plus_plus: C_putc('+'); C_putc('+'); out_state=normal; break;
+case minus_minus: C_putc('-'); C_putc('-'); out_state=normal; break;
+case minus_gt: C_putc('-'); C_putc('>'); out_state=normal; break;
+case gt_gt: C_putc('>'); C_putc('>'); out_state=normal; break;
+case eq_eq: C_putc('='); C_putc('='); out_state=normal; break;
+case lt_lt: C_putc('<'); C_putc('<'); out_state=normal; break;
+case gt_eq: C_putc('>'); C_putc('='); out_state=normal; break;
+case lt_eq: C_putc('<'); C_putc('='); out_state=normal; break;
+case not_eq: C_putc('!'); C_putc('='); out_state=normal; break;
+case and_and: C_putc('&'); C_putc('&'); out_state=normal; break;
+case or_or: C_putc('|'); C_putc('|'); out_state=normal; break;
+case dot_dot_dot: C_putc('.'); C_putc('.'); C_putc('.'); out_state=normal;
+    break;
+case colon_colon: C_putc(':'); C_putc(':'); out_state=normal; break;
+case period_ast: C_putc('.'); C_putc('*'); out_state=normal; break;
+case minus_gt_ast: C_putc('-'); C_putc('>'); C_putc('*'); out_state=normal;
+    break;
+@y
+@ @<Cases like \.{!=}@>=
+case plus_plus: C_putc('+');@+C_putc('+'); out_state=normal; break;
+case minus_minus: C_putc('-');@+C_putc('-'); out_state=normal; break;
+case minus_gt: C_putc('-');@+C_putc('>'); out_state=normal; break;
+case gt_gt: C_putc('>');@+C_putc('>'); out_state=normal; break;
+case eq_eq: C_putc('=');@+C_putc('='); out_state=normal; break;
+case lt_lt: C_putc('<');@+C_putc('<'); out_state=normal; break;
+case gt_eq: C_putc('>');@+C_putc('='); out_state=normal; break;
+case lt_eq: C_putc('<');@+C_putc('='); out_state=normal; break;
+case non_eq: C_putc('!');@+C_putc('='); out_state=normal; break;
+case and_and: C_putc('&');@+C_putc('&'); out_state=normal; break;
+case or_or: C_putc('|');@+C_putc('|'); out_state=normal; break;
+case dot_dot_dot: C_putc('.');@+C_putc('.');@+C_putc('.'); out_state=normal;
+    break;
+case colon_colon: C_putc(':');@+C_putc(':'); out_state=normal; break;
+case period_ast: C_putc('.');@+C_putc('*'); out_state=normal; break;
+case minus_gt_ast: C_putc('-');@+C_putc('>');@+C_putc('*'); out_state=normal;
+    break;
+@z
+
+@x
 eight_bits
 skip_ahead() /* skip to next control code */
 @y
 static eight_bits
-skip_ahead (void) /* skip to next control code */
+skip_ahead(void) /* skip to next control code */
 @z
 
-Section 60.
-
-@x l.849
+@x
 int skip_comment(is_long_comment) /* skips over comments */
 boolean is_long_comment;
 @y
-static int
-skip_comment (boolean is_long_comment) /* skips over comments */
+static boolean skip_comment(@t\1\1@> /* skips over comments */
+boolean is_long_comment@t\2\2@>)
 @z
 
-Section 62
-
-@x l.889 - add declaration of versionstring.
-#include <ctype.h> /* definition of |isalpha|, |isdigit| and so on */
+@x
+          err_print("! Input ended in mid-comment");
 @y
+          err_print(_("! Input ended in mid-comment"));
 @z
 
-Section 63.
+@x
+        err_print("! Section name ended in mid-comment"); loc--;
+@y
+        err_print(_("! Section name ended in mid-comment")); loc--;
+@z
 
-@x l.901
+@x
 eight_bits
 get_next() /* produces the next input token */
 @y
 static eight_bits
-get_next (void) /* produces the next input token */
+get_next(void) /* produces the next input token */
 @z
 
-Section 63.
+@x
+    else if (c=='\'' || c=='"' || (c=='L'&&(*loc=='\'' || *loc=='"')))
+@y
+    else if (c=='\'' || c=='"'@|
+           || ((c=='L' || c=='u' || c=='U')&&(*loc=='\'' || *loc=='"'))@|
+           || ((c=='u' && *loc=='8')&&(*(loc+1)=='\'' || *(loc+1)=='"')))
+@z
 
-@x l.954
+@x
     else if (*loc=='>') if (*(loc+1)=='*') {loc++; compress(minus_gt_ast);}
                         else compress(minus_gt); break;
 @y
-    else if (*loc=='>') {if (*(loc+1)=='*') {loc++; compress(minus_gt_ast);}
-                         else compress(minus_gt);} break;
+    else { if (*loc=='>') { if (*(loc+1)=='*') {loc++; compress(minus_gt_ast);}
+                        else compress(minus_gt); } } break;
 @z
 
-@x l.974
+@x
+  case '!': if (*loc=='=') compress(not_eq); break;
+@y
+  case '!': if (*loc=='=') compress(non_eq); break;
+@z
+
+@x
   while (isalpha(*++loc) || isdigit(*loc) || isxalpha(*loc) || ishigh(*loc));
 @y
-  while (isalpha((unsigned char)*++loc) || isdigit((unsigned char)*loc) || isxalpha(*loc) || ishigh(*loc));
+  while (isalpha((eight_bits)*++loc) || isdigit((eight_bits)*loc) @|
+      || isxalpha((eight_bits)*loc) || ishigh((eight_bits)*loc));
 @z
 
-Section 76.
+@x
+  if (delim=='L') { /* wide character constant */
+    delim=*loc++; *++id_loc=delim;
+  }
+@y
+  if (delim=='L' || delim=='u' || delim=='U') { /* wide character constant */
+    if (delim=='u' && *loc=='8') { *++id_loc=*loc++; }
+    delim=*loc++; *++id_loc=delim;
+  }
+@z
+
+@x
+        err_print("! String didn't end"); loc=limit; break;
+@y
+        err_print(_("! String didn't end")); loc=limit; break;
+@z
+
+@x
+        err_print("! Input ended in middle of string"); loc=buffer; break;
+@y
+        err_print(_("! Input ended in middle of string")); loc=buffer; break;
+@z
+
+@x
+    printf("\n! String too long: ");
+@y
+    fputs(_("\n! String too long: "),stdout);
+@z
+
+@x
+    case translit_code: err_print("! Use @@l in limbo only"); continue;
+@y
+    case translit_code: err_print(_("! Use @@l in limbo only")); continue;
+@z
+
+@x
+        err_print("! Double @@ should be used in control text");
+@y
+        err_print(_("! Double @@ should be used in control text"));
+@z
+
+@x
+        err_print("! Double @@ should be used in ASCII constant");
+@y
+        err_print(_("! Double @@ should be used in ASCII constant"));
+@z
+
+@x
+        err_print("! String didn't end"); loc=limit-1; break;
+@y
+        err_print(_("! String didn't end")); loc=limit-1; break;
+@z
 
-@x l.1200
+@x
+    err_print("! Input ended in section name");
+@y
+    err_print(_("! Input ended in section name"));
+@z
+
+@x
+  printf("\n! Section name too long: ");
+@y
+  fputs(_("\n! Section name too long: "),stdout);
+@z
+
+@x
+    err_print("! Section name didn't end"); break;
+@y
+    err_print(_("! Section name didn't end")); break;
+@z
+
+@x
+    err_print("! Nesting of section names not allowed"); break;
+@y
+    err_print(_("! Nesting of section names not allowed")); break;
+@z
+
+@x
+  if (loc>=limit) err_print("! Verbatim string didn't end");
+@y
+  if (loc>=limit) err_print(_("! Verbatim string didn't end"));
+@z
+
+@x
+@d app_repl(c)  {if (tok_ptr==tok_mem_end) overflow("token"); *tok_ptr++=c;}
+@y
+@d app_repl(c) {if (tok_ptr==tok_mem_end) overflow(_("token")); *tok_ptr++=c;}
+@z
+
+@x
 void
 scan_repl(t) /* creates a replacement text */
 eight_bits t;
 @y
 static void
-scan_repl (eight_bits t) /* creates a replacement text */
+scan_repl(@t\1\1@> /* creates a replacement text */
+eight_bits t@t\2\2@>)
 @z
 
-Section 77.
+@x
+  if (text_ptr>text_info_end) overflow("text");
+@y
+  if (text_ptr>text_info_end) overflow(_("text"));
+@z
 
-@x l.1232 -- rename local var, not to shadow previous local
+@x
 {int a=id_lookup(id_first,id_loc,0)-name_dir; app_repl((a / 0400)+0200);
   app_repl(a % 0400);}
 @y
@@ -411,69 +583,262 @@ Section 77.
   app_repl(a_l % 0400);}
 @z
 
-Section 82.
+@x
+case output_defs_code: if (t!=section_name) err_print("! Misplaced @@h");
+@y
+case output_defs_code: if (t!=section_name) err_print(_("! Misplaced @@h"));
+@z
 
-@x l.1320
+@x
+    err_print("! @@d, @@f and @@c are ignored in C text"); continue;
+@y
+    err_print(_("! @@d, @@f and @@c are ignored in C text")); continue;
+@z
+
+@x
+  if (*try_loc=='=') err_print ("! Missing `@@ ' before a named section");
+@y
+  if (*try_loc=='=') err_print (_("! Missing `@@ ' before a named section"));
+@z
+
+@x
+      else err_print("! Double @@ should be used in string");
+@y
+      else err_print(_("! Double @@ should be used in string"));
+@z
+
+@x
         c=toupper(*id_first)-'A'+10;
 @y
-        c=toupper((unsigned char)*id_first)-'A'+10;
+        c=toupper((eight_bits)*id_first)-'A'+10;
 @z
-@x l.1325
+
+@x
         c=16*c+toupper(*id_first)-'A'+10;
 @y
-        c=16*c+toupper((unsigned char)*id_first)-'A'+10;
+        c=16*c+toupper((eight_bits)*id_first)-'A'+10;
 @z
 
-Section 83.
+@x
+    default: err_print("! Unrecognized escape sequence");
+@y
+    default: err_print(_("! Unrecognized escape sequence"));
+@z
 
-@x l.1358
+@x
 void
 scan_section()
 @y
 static void
-scan_section (void)
+scan_section(void)
 @z
 
-Section 90.
+@x
+    err_print("! Definition flushed, must start with identifier");
+@y
+    err_print(_("! Definition flushed, must start with identifier"));
+@z
 
-@x l.1458
-void phase_one();
+@x
+else if (p->equiv==(char *)text_info) p->equiv=(char *)cur_text;
 @y
-static void phase_one (void);
+else if (p->equiv==(void *)text_info) p->equiv=(void *)cur_text;
 @z
 
-Section 91.
+@x
+void phase_one();
+@y
+static void phase_one(void);@/
+@z
 
-@x l.1461
+@x
 void
 phase_one() {
 @y
 static void
-phase_one (void) {
+phase_one(void) {
 @z
 
-Section 92.
-
-@x l.1476
+@x
 void skip_limbo();
 @y
-static void skip_limbo (void);
+static void skip_limbo(void);@/
 @z
 
-Section 93.
-
-@x l.1479
+@x
 void
 skip_limbo()
 @y
 static void
-skip_limbo (void)
+skip_limbo(void)
+@z
+
+@x
+            err_print("! Double @@ should be used in control text");
+@y
+            err_print(_("! Double @@ should be used in control text"));
+@z
+
+@x
+        default: err_print("! Double @@ should be used in limbo");
+@y
+        default: err_print(_("! Double @@ should be used in limbo"));
+@z
+
+@x
+    err_print("! Improper hex number following @@l");
+@y
+    err_print(_("! Improper hex number following @@l"));
+@z
+
+@x
+      err_print("! Replacement string in @@l too long");
+@y
+      err_print(_("! Replacement string in @@l too long"));
 @z
 
-Section 95.
+@x
+      strncpy(translit[i-0200],beg,loc-beg);
+@y
+      strncpy(translit[i-0200],beg,(size_t)(loc-beg));
+@z
 
-@x l.1535
+@x
+void
 print_stats() {
 @y
-print_stats (void) {
+void
+print_stats(void) {
 @z
+
+@x
+  printf("\nMemory usage statistics:\n");
+  printf("%ld names (out of %ld)\n",
+          (long)(name_ptr-name_dir),(long)max_names);
+  printf("%ld replacement texts (out of %ld)\n",
+          (long)(text_ptr-text_info),(long)max_texts);
+  printf("%ld bytes (out of %ld)\n",
+          (long)(byte_ptr-byte_mem),(long)max_bytes);
+  printf("%ld tokens (out of %ld)\n",
+@y
+  puts(_("\nMemory usage statistics:"));
+  printf(_("%ld names (out of %ld)\n"),
+          (long)(name_ptr-name_dir),(long)max_names);
+  printf(_("%ld replacement texts (out of %ld)\n"),
+          (long)(text_ptr-text_info),(long)max_texts);
+  printf(_("%ld bytes (out of %ld)\n"),
+          (long)(byte_ptr-byte_mem),(long)max_bytes);
+  printf(_("%ld tokens (out of %ld)\n"),
+@z
+
+@x
+@** Index.
+@y
+@** Extensions for modern \.{CWEB}.
+
+The following sections introduce code changes and extensions that have been
+created by numerous contributors over the course of a quarter century. They
+make \.{CWEB} adhere to modern coding standards and introduce new or improved
+features.
+
+Care has been taken to keep the original section numbering intact, so this new
+section should have the same number as the original ``\&{96.~Index},'' and
+additional material follows below.
+
+@* Function declarations.  Here are declarations---conforming to
+{\mc ANSI~C}---of all functions in this code, as far as they are
+not already in |"common.h"|.  These are private to \.{CTANGLE}.
+
+@<Predecl...@>=
+static eight_bits get_next(void);@/
+static eight_bits skip_ahead(void);@/
+static boolean skip_comment(boolean);@/
+static void flush_buffer(void);@/
+static void get_output(void);@/
+static void pop_level(int);@/
+static void push_level(name_pointer);@/
+static void scan_repl(eight_bits);@/
+static void scan_section(void);@/
+static void store_two_bytes(sixteen_bits);@/
+
+@* Output file update.  Most \CEE/ projects are controlled by a
+\.{Makefile} that automatically takes care of the temporal dependecies
+between the different source modules.  It is suitable that \.{CWEB} doesn't
+create new output for all existing files, when there are only changes to
+some of them. Thus the \.{make} process will only recompile those modules
+where necessary. The idea and basic implementation of this mechanism can
+be found in the program \.{NUWEB} by Preston Briggs, to whom credit is due.
+
+@<Update the primary result...@>=
+if((C_file=fopen(C_file_name,"r"))!=NULL) {
+  @<Set up the comparison of temporary output@>@;
+  @<Create the primary output depending on the comparison@>@;
+} else
+  rename(check_file_name,C_file_name); /* This was the first run */
+
+@ @<Set up the comparison of temporary output@>=
+  char x[BUFSIZ],y[BUFSIZ];
+  int x_size,y_size,comparison;
+
+  if((check_file=fopen(check_file_name,"r"))==NULL)
+    fatal(_("! Cannot open output file "),check_file_name);
+@.Cannot open output file@>
+
+  @<Compare the temporary output to the previous output@>@;
+
+  fclose(C_file); C_file=NULL;
+  fclose(check_file); check_file=NULL;
+
+@ We hope that this runs fast on most systems.
+
+@<Compare the temp...@>=
+do {
+  x_size = fread(x,1,BUFSIZ,C_file);
+  y_size = fread(y,1,BUFSIZ,check_file);
+  comparison = (x_size == y_size); /* Do not merge these statements! */
+  if(comparison) comparison = !memcmp(x,y,x_size);
+} while(comparison && !feof(C_file) && !feof(check_file));
+
+@ Note the superfluous call to |remove| before |rename|.  We're using it to
+get around a bug in some implementations of |rename|.
+
+@<Create the primary output...@>=
+if(comparison)
+  remove(check_file_name); /* The output remains untouched */
+else {
+  remove(C_file_name);
+  rename(check_file_name,C_file_name);
+}
+
+@ @<Update the secondary results...@>=
+if((C_file=fopen(output_file_name,"r"))!=NULL) {
+  @<Set up the comparison of temporary output@>@;
+  @<Create the secondary output depending on the comparison@>@;
+} else
+  rename(check_file_name,output_file_name); /* This was the first run */
+
+@ Again, we use a call to |remove| before |rename|.
+
+@<Create the secondary output...@>=
+if(comparison)
+  remove(check_file_name); /* The output remains untouched */
+else {
+  remove(output_file_name);
+  rename(check_file_name,output_file_name);
+}
+
+@* Put ``version'' information in a single spot.
+Don't do this at home, kids! Push our local macro to the variable in \.{COMMON}
+for printing the |banner| and the |versionstring| from there.
+
+@d max_banner 50
+
+@<Common code...@>=
+extern char cb_banner[];
+
+@ @<Set init...@>=
+  strncpy(cb_banner,banner,max_banner-1);
+
+@** Index.
+@z
+
diff --git a/source/texk/web2c/cwebdir/cweav-w2c.ch b/source/texk/web2c/cwebdir/cweav-w2c.ch
index 193bda51b48c38d731b7caf26a374af5d9f346ab..795b5fcb6db0620c33a7f3752aea699d3f14b2ac 100644
--- a/source/texk/web2c/cwebdir/cweav-w2c.ch
+++ b/source/texk/web2c/cwebdir/cweav-w2c.ch
@@ -1,55 +1,45 @@
-% Original Kpathsea changes for CWEB by Wlodek Bzyl and Olaf Weber
-% This file is in the Public Domain.
+@q Changes for CWEB in TeX Live from numerous contributors. @>
+@q This file is in the Public Domain. @>
 
+@q Most of the original Kpathsea changes by Wlodek Bzyl and Olaf Weber @>
+@q were merged with the set of change files of the CWEBbin project; @>
+@q see https://github.com/ascherer/cwebbin for the original parts. @>
 
-@x l.32
+@q This stripped change file {comm,ctang,cweav,ctwill}-w2c.ch has been @>
+@q created from the set of change files {comm,ctang,cweav}-patch.ch, @>
+@q {comm,ctang,cweav}-ansi.ch, {comm,ctang,cweav}-extensions.ch, @>
+@q {comm,ctang,cweav}-output.ch, {comm,ctang,cweav}-i18n.ch, and @>
+@q cweav-twill.ch for CTWILL, and {comm,ctang,cweav,ctwill}-texlive.ch @>
+@q with the 'tie' processor and is used as a monolithic changefile for @>
+@q {common,ctangle,cweave}.w in TeX Live. @>
+
+@q Please send comments, suggestions, etc. to tex-k@@tug.org. @>
+
+@x
 \def\title{CWEAVE (Version 3.64)}
-\def\topofcontents{\null\vfill
-  \centerline{\titlefont The {\ttitlefont CWEAVE} processor}
-  \vskip 15pt
-  \centerline{(Version 3.64)}
-  \vfill}
 @y
-\def\Kpathsea/{{\mc KPATHSEA\spacefactor1000}}
-\def\SQUARE{\vrule width 2pt depth -1pt height 3pt}
-\def\sqitem{\item{\SQUARE}}
-
-\def\title{CWEAVE (Version 3.64k)}
-\def\topofcontents{\null\vfill
-  \centerline{\titlefont The {\ttitlefont CWEAVE} processor}
-  \vskip 15pt
-  \centerline{(Version 3.64k)}
-  \vfill}
+\def\title{CWEAVE (Version 3.64 [\TeX~Live])}
 @z
 
-This change cannot be applied when `tie' is  used
-(TOC file can not be typeset).
-
-%@x l.51
-%\let\maybe=\iftrue
-%@y
-%\let\maybe=\iffalse % print only changed modules
-%@z
-
-
-Section 1.
+@x
+  \centerline{(Version 3.64)}
+@y
+  \centerline{(Version 3.64 [\TeX~Live])}
+@z
 
-@x l.65
-The ``banner line'' defined here should be changed whenever \.{CWEAVE}
-is modified.
+@x
+@s not_eq normal @q unreserve a C++ keyword @>
+@y
+@z
 
+@x
 @d banner "This is CWEAVE (Version 3.64)\n"
-@y 
-The ``banner line'' defined here should be changed whenever \.{CWEAVE}
-is modified.
-
+@y
 @d banner "This is CWEAVE, Version 3.64"
+  /* will be extended by the \TeX~Live |versionstring| */
 @z
 
-
-Section 2.
-
-@x l.77
+@x
 @ We predeclare several standard system functions here instead of including
 their system header files, because the names of the header files are not as
 standard as the names of the functions. (For example, some \CEE/ environments
@@ -62,46 +52,61 @@ extern char* strcpy(); /* copy one string to another */
 extern int strncmp(); /* compare up to $n$ string characters */
 extern char* strncpy(); /* copy up to $n$ string characters */
 @y
-@z
+@ For string handling we include the {\mc ANSI C} system header file instead
+of predeclaring the standard system functions |strlen|, |strcmp|, |strcpy|,
+|strncmp|, and |strncpy|.
+@^system dependencies@>
 
-Section 3.
+@<Include files@>=
+#include <string.h>
+@z
 
-@x l.98
+@x
 int main (ac, av)
 int ac; /* argument count */
 char **av; /* argument values */
 @y
-int main (int ac, char **av)
+int main (@t\1\1@>
+int ac, /* argument count */
+char **av@t\2\2@>) /* argument values */
 @z
 
-@x l.107 - Add Web2C version to banner.
-  if (show_banner) printf(banner); /* print a ``banner line'' */
+@x
+  argc=ac; argv=av;
 @y
-  if (show_banner) {
-     printf("%s%s\n", banner, versionstring); /* print a ``banner line'' */
-  }
+  extern const char *use_language; /* prefix to \.{cwebmac.tex} in \TEX/ output */
+  argc=ac; argv=av;
+@z
+
+@x
+  make_xrefs=force_lines=make_pb=1; /* controlled by command-line options */
+  common_init();
+  @<Set initial values@>;
+@y
+  @<Set initial values@>;
+  common_init();
+  @<Start \TEX/ output@>;
 @z
 
-@x l.112 - 'use' print_text(), used nowhere else
-  return wrap_up(); /* and exit gracefully */
+@x
+  if (show_banner) printf(banner); /* print a ``banner line'' */
 @y
-  if (0) print_text(text_ptr);
-  return wrap_up(); /* and exit gracefully */
+  if (show_banner) cb_show_banner(); /* print a ``banner line'' */
 @z
 
-@x l.120
+@x
 @d max_bytes 90000 /* the number of bytes in identifiers,
 @y
 @d max_bytes 1000000 /* the number of bytes in identifiers,
 @z
 
-@x l.112
+@x
 @d max_names 4000 /* number of identifiers, strings, section names;
 @y
 @d max_names 10239 /* number of identifiers, strings, section names;
 @z
 
-@x l.124
+@x
 @d max_sections 2000 /* greater than the total number of sections */
 @d hash_size 353 /* should be prime */
 @d buf_size 100 /* maximum length of input line, plus one */
@@ -111,7 +116,7 @@ int main (int ac, char **av)
 @d buf_size 1000 /* maximum length of input line, plus one */
 @z
 
-@x l.131
+@x
 @d max_refs 20000 /* number of cross-references; must be less than 65536 */
 @d max_toks 20000 /* number of symbols in \CEE/ texts being parsed;
 @y
@@ -119,588 +124,935 @@ int main (int ac, char **av)
 @d max_toks 65535 /* number of symbols in \CEE/ texts being parsed;
 @z
 
-@x l.134
+@x
 @d max_texts 4000 /* number of phrases in \CEE/ texts being parsed;
 @y
 @d max_texts 10239 /* number of phrases in \CEE/ texts being parsed;
 @z
 
-@x l.136
+@x
 @d max_scraps 2000 /* number of tokens in \CEE/ texts being parsed */
 @y
 @d max_scraps 10000 /* number of tokens in \CEE/ texts being parsed */
 @z
 
-Section 5.
-
-@x common.h l.30 - boolean comes from kpathsea.
-typedef short boolean;
+@x
+@i common.h
 @y
+@i comm-w2c.h
 @z
 
-Section 6.
-
-@x common.h l.36
-#include <stdio.h>
-@y
-#include <kpathsea/kpathsea.h>
-#include <stdio.h>
-@z
-
-@x common.h l.65
-@d xisalpha(c) (isalpha(c)&&((eight_bits)c<0200))
-@d xisdigit(c) (isdigit(c)&&((eight_bits)c<0200))
-@d xisspace(c) (isspace(c)&&((eight_bits)c<0200))
-@d xislower(c) (islower(c)&&((eight_bits)c<0200))
-@d xisupper(c) (isupper(c)&&((eight_bits)c<0200))
-@d xisxdigit(c) (isxdigit(c)&&((eight_bits)c<0200))
-@y
-@d xisalpha(c) (isalpha((eight_bits)c)&&((eight_bits)c<0200))
-@d xisdigit(c) (isdigit((eight_bits)c)&&((eight_bits)c<0200))
-@d xisspace(c) (isspace((eight_bits)c)&&((eight_bits)c<0200))
-@d xislower(c) (islower((eight_bits)c)&&((eight_bits)c<0200))
-@d xisupper(c) (isupper((eight_bits)c)&&((eight_bits)c<0200))
-@d xisxdigit(c) (isxdigit((eight_bits)c)&&((eight_bits)c<0200))
-@z
-
-Section 9.
-
-@x common.h l.109 - protos now all in cweb.h.
-extern name_pointer id_lookup(); /* looks up a string in the identifier table */
-extern name_pointer section_lookup(); /* finds section name */
-extern void print_section_name(), sprint_section_name();
+@x
+xref_ptr=xmem; name_dir->xref=(char*)xmem; xref_switch=0; section_xref_switch=0;
 @y
-#include "cweb.h"
+xref_ptr=xmem; init_node(name_dir); xref_switch=0; section_xref_switch=0;
 @z
 
-Section 10.
-
-@x common.h l.123 - explicit types, protos now all in cweb.h.
-extern history; /* indicates how bad this run was */
-extern err_print(); /* print error message and context */
-extern wrap_up(); /* indicate |history| and exit */
-extern void fatal(); /* issue error message and die */
-extern void overflow(); /* succumb because a table has overflowed */
+@x
+@d append_xref(c) if (xref_ptr==xmem_end) overflow("cross-reference");
 @y
-extern int history; /* indicates how bad this run was */
+@d append_xref(c) if (xref_ptr==xmem_end) overflow(_("cross-reference"));
 @z
 
-Section 11.
-
-@x common.h l.131 - max_file_name_length is way too small.
-@d max_file_name_length 60
+@x
+@d no_xref (flags['x']==0)
+@d make_xrefs flags['x'] /* should cross references be output? */
 @y
-@d max_file_name_length 1024
+@d no_xref (!make_xrefs) /* should cross references be suppressed? */
 @z
 
-@x common.h l.138 - explicit types.
-extern include_depth; /* current level of nesting */
+@x
+void
+new_xref(p)
+name_pointer p;
 @y
-extern int include_depth; /* current level of nesting */
+static void
+new_xref(
+name_pointer p)
 @z
 
-@x common.h l.148 - explicit types.
-extern line[]; /* number of current line in the stacked files */
-extern change_line; /* number of current line in change file */
-extern change_depth; /* where \.{@@y} originated during a change */
+@x
+  append_xref(m); xref_ptr->xlink=q; p->xref=(char*)xref_ptr;
 @y
-extern int line[]; /* number of current line in the stacked files */
-extern int change_line; /* number of current line in change file */
-extern int change_depth; /* where \.{@@y} originated during a change */
+  append_xref(m); xref_ptr->xlink=q; update_node(p);
 @z
 
-@x common.h l.153 - protos now all in cweb.h.
-extern reset_input(); /* initialize to read the web file and change file */
-extern get_line(); /* inputs the next line */
-extern check_complete(); /* checks that all changes were picked up */
+@x
+void
+new_section_xref(p)
+name_pointer p;
 @y
+static void
+new_section_xref(
+name_pointer p)
 @z
 
-Section 15.
-
-@x common.h l.192 - protos now all in cweb.h.
-extern void common_init();
+@x
+  if (r==xmem) p->xref=(char*)xref_ptr;
 @y
+  if (r==xmem) update_node(p);
 @z
 
-Section 21.
-
-@x l.275
+@x
 void
-new_xref(p)
+set_file_flag(p)
 name_pointer p;
 @y
 static void
-new_xref (name_pointer p)
+set_file_flag(
+name_pointer p)
 @z
 
-Section 22.
-
-@x l.306
-void
-new_section_xref(p)
-name_pointer p;
+@x
+  p->xref = (char *)xref_ptr;
 @y
-static void
-new_section_xref (name_pointer p)
+  update_node(p);
 @z
 
-Section 23.
-
-@x l.326
-void
-set_file_flag(p)
-name_pointer p;
+@x
+further details about them will be explained later. A |text_pointer| variable
+is an index into |tok_start|.
 @y
-static void
-set_file_flag (name_pointer p)
+further details about them will be explained later. A \&{text\_pointer}
+variable is an index into |tok_start|.
 @z
 
-Section 27.
+@x
+tok_ptr=tok_mem+1; text_ptr=tok_start+1; tok_start[0]=tok_mem+1;
+tok_start[1]=tok_mem+1;
+max_tok_ptr=tok_mem+1; max_text_ptr=tok_start+1;
+@y
+tok_ptr=max_tok_ptr=tok_mem+1;@/
+tok_start[0]=tok_start[1]=tok_mem+1;@/
+text_ptr=max_text_ptr=tok_start+1;
+@z
 
-@x l.371
+@x
 int names_match(p,first,l,t)
 name_pointer p; /* points to the proposed match */
 char *first; /* position of first character of string */
 int l; /* length of identifier */
 eight_bits t; /* desired ilk */
 @y
-int
-names_match (name_pointer p, const char *first, int l, char t)
+boolean names_match(@t\1\1@>
+name_pointer p, /* points to the proposed match */
+const char *first, /* position of first character of string */
+size_t l, /* length of identifier */
+eight_bits t@t\2\2@>) /* desired |ilk| */
 @z
 
-@x l.383
+@x
+void
 init_p(p,t)
 name_pointer p;
 eight_bits t;
 @y
-init_p (name_pointer p, char t)
+void
+init_p(
+name_pointer p,
+eight_bits t)
 @z
 
-@x l.391
+@x
+  p->ilk=t; p->xref=(char*)xmem;
+@y
+  p->ilk=t; init_node(p);
+@z
+
+@x
+void
 init_node(p)
 name_pointer p;
 @y
-init_node (name_pointer p)
+void
+init_node(
+name_pointer p)
 @z
 
-Section 34.
+@x
+  p->xref=(char*)xmem;
+}
+@y
+  p->xref=(void *)xmem;
+}
+
+static void
+update_node(
+name_pointer p)
+{
+  p->xref=(void *)xref_ptr;
+}
+@z
 
-@x l.600
+@x
 void   skip_limbo();
 @y
-static void skip_limbo (void);
+static void skip_limbo(void);@/
 @z
 
-Section 35.
-
-@x l.603
+@x
 void
 skip_limbo() {
 @y
 static void
-skip_limbo (void) {
+skip_limbo(void) {
 @z
 
-Section 36.
-
-@x l.625
+@x
 unsigned
 skip_TeX() /* skip past pure \TEX/ code */
 @y
-static unsigned
-skip_TeX (void) /* skip past pure \TEX/ code */
-@z
-
-Section 38.
-
-@x l.682 - Add declaration for versionstring.
-#include <ctype.h> /* definition of |isalpha|, |isdigit| and so on */
-@y
+static eight_bits
+skip_TeX(void) /* skip past pure \TEX/ code */
 @z
 
-Section 39.
-
-@x l.696
+@x
 eight_bits get_next();
 @y
-static eight_bits get_next (void);
+static eight_bits get_next(void);@/
 @z
 
-Section 40.
-
-@x l.699
+@x
 eight_bits
 get_next() /* produces the next input token */
+{@+eight_bits c; /* the current character */
 @y
 static eight_bits
-get_next (void) /* produces the next input token */
+get_next(void) /* produces the next input token */
+{
+  eight_bits c; /* the current character */
 @z
 
-Section 45.
+@x
+    else if (c=='\'' || c=='"' || (c=='L'&&(*loc=='\'' || *loc=='"'))@|
+@y
+    else if (c=='\'' || c=='"'@|
+           || ((c=='L' || c=='u' || c=='U')&&(*loc=='\'' || *loc=='"'))@|
+           || ((c=='u' && *loc=='8')&&(*(loc+1)=='\'' || *(loc+1)=='"'))@|
+@z
 
-@x l.780
+@x
     else if (*loc=='>') if (*(loc+1)=='*') {loc++; compress(minus_gt_ast);}
                         else compress(minus_gt); break;
 @y
-    else if (*loc=='>') {if (*(loc+1)=='*') {loc++; compress(minus_gt_ast);}
-                         else compress(minus_gt);} break;
+    else { if (*loc=='>') { if (*(loc+1)=='*') {loc++; compress(minus_gt_ast);}
+                        else compress(minus_gt); } } break;
 @z
 
-@x l.800
+@x
+  case '!': if (*loc=='=') compress(not_eq); break;
+@y
+  case '!': if (*loc=='=') compress(non_eq); break;
+@z
+
+@x
   while (isalpha(*++loc) || isdigit(*loc) || isxalpha(*loc) || ishigh(*loc));
 @y
-  while (isalpha((unsigned char)*++loc) || isdigit((unsigned char)*loc) || isxalpha(*loc) || ishigh(*loc));
+  while (isalpha((eight_bits)*++loc) || isdigit((eight_bits)*loc) @|
+      || isxalpha((eight_bits)*loc) || ishigh((eight_bits)*loc));
 @z
 
-@x l.835
+@x
     *id_loc++='$'; *id_loc++=toupper(*loc); loc++;
 @y
-    *id_loc++='$'; *id_loc++=toupper((unsigned char)*loc); loc++;
+    *id_loc++='$'; *id_loc++=toupper((eight_bits)*loc); loc++;
 @z
 
-Section 48.
+@x
+  if (delim=='L') { /* wide character constant */
+    delim=*loc++; *++id_loc=delim;
+  }
+@y
+  if (delim=='L' || delim=='u' || delim=='U') { /* wide character constant */
+    if (delim=='u' && *loc=='8') { *++id_loc=*loc++; }
+    delim=*loc++; *++id_loc=delim;
+  }
+@z
 
-@x l.870
+@x
+        err_print("! String didn't end"); loc=limit; break;
+@y
+        err_print(_("! String didn't end")); loc=limit; break;
+@z
+
+@x
+        err_print("! Input ended in middle of string"); loc=buffer; break;
+@y
+        err_print(_("! Input ended in middle of string")); loc=buffer; break;
+@z
+
+@x
     if (c=='\\') if (loc>=limit) continue;
       else if (++id_loc<=section_text_end) {
         *id_loc = '\\'; c=*loc++;
       }
 @y
-    if (c=='\\') {
-      if (loc>=limit) continue;
-      else if (++id_loc<=section_text_end) {
+    if (c=='\\') { if (loc>=limit) continue;
+      else { if (++id_loc<=section_text_end) {
         *id_loc = '\\'; c=*loc++;
-      }
-    }
+      } } }
+@z
+
+@x
+    printf("\n! String too long: ");
+@y
+    fputs(_("\n! String too long: "),stdout);
 @z
 
-Section 55.
+@x
+    case translit_code: err_print("! Use @@l in limbo only"); continue;
+@y
+    case translit_code: err_print(_("! Use @@l in limbo only")); continue;
+@z
 
-@x l.971
-void skip_restricted();
+@x
+    case xref_roman: case xref_wildcard: case xref_typewriter:
+    case noop: case TeX_string: c=ccode[c]; skip_restricted(); return(c);
+@y
+    case xref_roman: case xref_wildcard: case xref_typewriter: case noop:
+    case TeX_string: c=ccode[(eight_bits)c]; skip_restricted(); return(c);
+@z
+
+@x
+    err_print("! Input ended in section name");
+@y
+    err_print(_("! Input ended in section name"));
+@z
+
+@x
+  printf("\n! Section name too long: ");
+@y
+  fputs(_("\n! Section name too long: "),stdout);
+@z
+
+@x
+    err_print("! Section name didn't end"); break;
 @y
-static void skip_restricted (void);
+    err_print(_("! Section name didn't end")); break;
 @z
 
-Section 56.
+@x
+    err_print("! Control codes are forbidden in section name"); break;
+@y
+    err_print(_("! Control codes are forbidden in section name")); break;
+@z
 
-@x l.974
+@x
+void skip_restricted();
+@y
+void skip_restricted(void);@/
+@z
+
+@x
 void
 skip_restricted()
 @y
-static void
-skip_restricted (void)
+void
+skip_restricted(void)
+@z
+
+@x
+    err_print("! Control text didn't end"); loc=limit;
+@y
+    err_print(_("! Control text didn't end")); loc=limit;
 @z
 
-Section 59.
+@x
+      err_print("! Control codes are forbidden in control text");
+@y
+      err_print(_("! Control codes are forbidden in control text"));
+@z
 
-@x l.1024
-void phase_one();
+@x
+  if (loc>=limit) err_print("! Verbatim string didn't end");
 @y
-static void phase_one (void);
+  if (loc>=limit) err_print(_("! Verbatim string didn't end"));
 @z
 
-Section 60.
+@x
+void phase_one();
+@y
+static void phase_one(void);@/
+@z
 
-@x l.1027
+@x
 void
 phase_one() {
 @y
 static void
-phase_one (void) {
+phase_one(void) {
 @z
 
-Section 62.
+@x
+  if (++section_count==max_sections) overflow("section number");
+@y
+  if (++section_count==max_sections) overflow(_("section number"));
+@z
 
-@x l.1076
+@x
 void C_xref();
 @y
-static void C_xref (eight_bits);
+static void C_xref(eight_bits);@/
 @z
 
-Section 63.
-
-@x l.1080
+@x
 void
 C_xref( spec_ctrl ) /* makes cross-references for \CEE/ identifiers */
   eight_bits spec_ctrl;
 @y
 static void
-C_xref (eight_bits spec_ctrl) /* makes cross-references for \CEE/ identifiers */
+C_xref(@t\1\1@> /* makes cross-references for \CEE/ identifiers */
+  eight_bits spec_ctrl@t\2\2@>)
 @z
 
-Section 64.
-
-@x l.1104
+@x
 void outer_xref();
 @y
-static void outer_xref (void);
+static void outer_xref(void);@/
 @z
 
-Section 65.
-
-@x l.1107
+@x
 void
 outer_xref() /* extension of |C_xref| */
 @y
 static void
-outer_xref (void) /* extension of |C_xref| */
+outer_xref(void) /* extension of |C_xref| */
 @z
 
-Section 74.
+@x
+    case translit_code: err_print("! Use @@l in limbo only"); continue;
+@y
+    case translit_code: err_print(_("! Use @@l in limbo only")); continue;
+@z
 
-@x l.1266
-void section_check();
+@x
+            else lhs->xref=(char*)q->xlink;
+@y
+            else lhs->xref=(void *)q->xlink;
+@z
+
+@x
+    err_print("! Missing left identifier of @@s");
+@y
+    err_print(_("! Missing left identifier of @@s"));
+@z
+
+@x
+      err_print("! Missing right identifier of @@s");
 @y
-static void section_check (name_pointer);
+      err_print(_("! Missing right identifier of @@s"));
 @z
 
-Section 75.
+@x
+void section_check();
+@y
+static void section_check(name_pointer);@/
+@z
 
-@x l.1269
+@x
 void
 section_check(p)
 name_pointer p; /* print anomalies in subtree |p| */
 @y
 static void
-section_check (name_pointer p) /* print anomalies in subtree |p| */
+section_check(
+name_pointer p) /* print anomalies in subtree |p| */
+@z
+
+@x
+      printf("\n! Never defined: <"); print_section_name(p); putchar('>'); mark_harmless;
+@y
+      fputs(_("\n! Never defined: <"),stdout);
+      print_section_name(p); putchar('>'); mark_harmless;
 @z
 
-Section 78.
+@x
+      printf("\n! Never used: <"); print_section_name(p); putchar('>'); mark_harmless;
+@y
+      fputs(_("\n! Never used: <"),stdout);
+      print_section_name(p); putchar('>'); mark_harmless;
+@z
+
+@x
+If the |per_cent| parameter is 1 a |'%'| is appended to the line
+@y
+If the |per_cent| parameter is 1, a |'%'| is appended to the line
+@z
 
-@x l.1322
+@x
+@d tex_printf(c) fprintf(active_file,c)
+@y
+@d tex_printf(c) fprintf(active_file,"%s",c)
+@d tex_puts(c) fputs(c,active_file)
+@z
+
+@x
 void
 flush_buffer(b,per_cent,carryover)
 char *b; /* outputs from |out_buf+1| to |b|,where |b<=out_ptr| */
 boolean per_cent,carryover;
 @y
 static void
-flush_buffer (char *b, boolean per_cent, boolean carryover)
+flush_buffer(@t\1\1@>
+char *b, /* outputs from |out_buf+1| to |b|, where |b<=out_ptr| */
+boolean per_cent,boolean carryover@t\2\2@>)
 @z
 
-Section 79.
+@x
+  if (b<out_ptr) strncpy(out_buf+1,b+1,out_ptr-b);
+@y
+  if (b<out_ptr) strncpy(out_buf+1,b+1,(size_t)(out_ptr-b));
+@z
 
-@x l.1351
+@x
 void
 finish_line() /* do this at the end of a line */
 @y
 static void
-finish_line (void) /* do this at the end of a line */
-@z
-
-Section 81.
-
-@x l.1383
+finish_line(void) /* do this at the end of a line */
+@z
+
+@x
+@ In particular, the |finish_line| procedure is called near the very
+beginning of phase two. We initialize the output variables in a slightly
+tricky way so that the first line of the output file will be
+`\.{\\input cwebmac}'.
+
+@<Set init...@>=
+out_ptr=out_buf+1; out_line=1; active_file=tex_file;
+*out_ptr='c'; tex_printf("\\input cwebma");
+@y
+@ In particular, the |finish_line| procedure is called near the very
+beginning of phase two. We initialize the output variables in a slightly
+tricky way so that the first line of the output file will be dependent of
+the user language set by the `\.{+l}' option and its argument.  If you call
+\.{CWEAVE} with `\.{+lX}' (or `\.{-lX}' as well), where `\.X' is the
+(possibly empty) string of characters to the right of~`\.l', `\.X'~will be
+prepended to `\.{cwebmac.tex}', e.g., if you call \.{CWEAVE} with
+`\.{+ldeutsch}', you will receive the line `\.{\\input deutschcwebmac}'.
+Without this option the first line of the output file will be
+`\.{\\input cwebmac}'.
+
+@<Start \TEX/...@>=
+out_ptr=out_buf+1; out_line=1; active_file=tex_file; *out_ptr='c';
+tex_puts("\\input ");
+tex_printf(use_language);
+tex_puts("cwebma");
+@z
+
+@x
 void
 out_str(s) /* output characters from |s| to end of string */
 char *s;
 @y
 static void
-out_str (const char *s) /* output characters from |s| to end of string */
+out_str(@t\1\1@> /* output characters from |s| to end of string */
+const char*s@t\2\2@>)
 @z
 
-Section 83.
-
-@x l.1402
+@x
 void break_out();
 @y
-static void break_out (void);
+static void break_out(void);@/
 @z
 
-Section 84.
-
-@x l.1405
+@x
 void
 break_out() /* finds a way to break the output line */
 @y
 static void
-break_out (void) /* finds a way to break the output line */
+break_out(void) /* finds a way to break the output line */
 @z
 
-Section 86.
+@x
+  printf("\n! Line had to be broken (output l. %d):\n",out_line);
+@y
+  printf(_("\n! Line had to be broken (output l. %d):\n"),out_line);
+@z
 
-@x l.1440
+@x
 void
 out_section(n)
 sixteen_bits n;
 @y
 static void
-out_section (sixteen_bits n)
+out_section(
+sixteen_bits n)
 @z
 
-Section 87.
-
-@x l.1454
+@x
 void
 out_name(p,quote_xalpha)
 name_pointer p;
 boolean quote_xalpha;
 @y
 static void
-out_name (name_pointer p, boolean quote_xalpha)
+out_name(
+name_pointer p,
+boolean quote_xalpha)
 @z
 
-Section 88.
-
-@x l.1484
+@x
 void
 copy_limbo()
 @y
 static void
-copy_limbo (void)
+copy_limbo(void)
 @z
 
-Section 90.
+@x
+        default: err_print("! Double @@ should be used in limbo");
+@y
+        default: err_print(_("! Double @@ should be used in limbo"));
+@z
 
-@x l.1519
+@x
 eight_bits
 copy_TeX()
 @y
 static eight_bits
-copy_TeX (void)
+copy_TeX(void)
 @z
 
-Section 91.
+@x
+@d app_tok(c) {if (tok_ptr+2>tok_mem_end) overflow("token"); *(tok_ptr++)=c;}
+@y
+@d app_tok(c) {if (tok_ptr+2>tok_mem_end) overflow(_("token")); *(tok_ptr++)=c;}
+@z
 
-@x l.1449
+@x
 int copy_comment();
 @y
-static int copy_comment (boolean, int);
+static int copy_comment(boolean,int);@/
 @z
 
-Section 92.
-
-@x l.1551
+@x
 int copy_comment(is_long_comment,bal) /* copies \TEX/ code in comments */
 boolean is_long_comment; /* is this a traditional \CEE/ comment? */
 int bal; /* brace balance */
 @y
-static int
-copy_comment (boolean is_long_comment, int bal)
+static int copy_comment(@t\1\1@> /* copies \TeX\ code in comments */
+boolean is_long_comment, /* is this a traditional \CEE/ comment? */
+int bal@t\2\2@>) /* brace balance */
 @z
 
-Section 93.
+@x
+          err_print("! Input ended in mid-comment");
+@y
+          err_print(_("! Input ended in mid-comment"));
+@z
 
-@x l.1608
+@x
+        if (bal>1) err_print("! Missing } in comment");
+@y
+        if (bal>1) err_print(_("! Missing } in comment"));
+@z
+
+@x
+      else {err_print("! Extra } in comment");
+@y
+      else {err_print(_("! Extra } in comment"));
+@z
+
+@x
+  if (bal>1) err_print("! Missing } in comment");
+@y
+  if (bal>1) err_print(_("! Missing } in comment"));
+@z
+
+@x
+    err_print("! Illegal use of @@ in comment");
+@y
+    err_print(_("! Illegal use of @@ in comment"));
+@z
+
+@x
+else if (c=='\\' && *loc!='@@')
   if (phase==2) app_tok(*(loc++))@; else loc++;
 @y
-  {if (phase==2) app_tok(*(loc++))@; else loc++;}
+else { if (c=='\\' && *loc!='@@') {
+  if (phase==2) app_tok(*(loc++))@; else loc++; } }
 @z
 
-Section 99.
+@x
+eight_bits cat_index;
+
+@ @<Set in...@>=
+    for (cat_index=0;cat_index<255;cat_index++)
+      strcpy(cat_name[cat_index],"UNKNOWN");
+@y
+
+@ @<Set in...@>=
+{int c; for (c=0;c<256;c++) strcpy(cat_name[c],"UNKNOWN");}
+@z
 
-@x l.1783
+@x
 void
 print_cat(c) /* symbolic printout of a category */
 eight_bits c;
 @y
 static void
-print_cat (eight_bits c)
+print_cat(@t\1\1@> /* symbolic printout of a category */
+eight_bits c@t\2\2@>)
 @z
 
-@x l.1788
+@x
   printf(cat_name[c]);
 @y
-  printf("%s",cat_name[c]);
+  fputs(cat_name[c],stdout);
 @z
 
-Section 106.
-
-@x l.2138
+@x
 void
 print_text(p) /* prints a token list for debugging; not used in |main| */
 text_pointer p;
 @y
+#ifdef DEAD_CODE /* not used in |main| */
 static void
-print_text (text_pointer p)
+print_text(@t\1\1@> /* prints a token list for debugging; not used in |main| */
+text_pointer p@t\2\2@>)
 @z
 
-Section 109.
+@x
+  fflush(stdout);
+}
+@y
+  update_terminal;
+}
+#endif /* |DEAD_CODE| */
+@z
+
+@x
+@d app(a) *(tok_ptr++)=a
+@d app1(a) *(tok_ptr++)=tok_flag+(int)((a)->trans-tok_start)
+@y
+@d app(a) *(tok_ptr++)=(token)(a)
+@d app1(a) *(tok_ptr++)=(token)(tok_flag+(int)((a)->trans-tok_start))
+@z
 
-@x l.2263
+@x
 void
 app_str(s)
 char *s;
 @y
 static void
-app_str (const char *s)
+app_str(
+const char *s)
 @z
 
-@x l.2270
+@x
 void
 big_app(a)
 token a;
 @y
 static void
-big_app (token a)
+big_app(
+token a)
 @z
 
-@x l.2287
+@x
 void
 big_app1(a)
 scrap_pointer a;
 @y
 static void
-big_app1 (scrap_pointer a)
+big_app1(
+scrap_pointer a)
 @z
 
-Section 111.
+@x
+        && pp->cat!=prerangle
+@y
+        && pp->cat!=prerangle @|
+@z
+
+@x
+        && pp->cat!=ftemplate
+@y
+        && pp->cat!=ftemplate @|
+@z
 
-@x l.2414
+@x
 token_pointer
 find_first_ident(p)
 text_pointer p;
 @y
 static token_pointer
-find_first_ident (text_pointer p)
+find_first_ident(
+text_pointer p)
 @z
 
-Section 112.
-
-@x l.2446
+@x
 void
 make_reserved(p) /* make the first identifier in |p->trans| like |int| */
 scrap_pointer p;
 @y
 static void
-make_reserved (scrap_pointer p)
+make_reserved(@t\1\1@> /* make the first identifier in |p->trans| like |int| */
+scrap_pointer p@t\2\2@>)
 @z
 
-Section 113.
-
-@x l.2477
+@x
 void
 make_underlined(p)
 /* underline the entry for the first identifier in |p->trans| */
 scrap_pointer p;
 @y
 static void
-make_underlined (scrap_pointer p)
+make_underlined(@t\1\1@>
+/* underline the entry for the first identifier in |p->trans| */
+scrap_pointer p@t\2\2@>)
 @z
 
-Section 114.
-
-@x l.2495
+@x
 void  underline_xref();
 @y
-static void underline_xref (name_pointer);
+static void underline_xref(name_pointer);@/
 @z
 
-Section 115.
-
-@x l.2498
+@x
 void
 underline_xref(p)
 name_pointer p;
 @y
 static void
-underline_xref (name_pointer p)
+underline_xref(
+name_pointer p)
+@z
+
+@x
+  p->xref=(char*)xref_ptr;
+@y
+  update_node(p);
 @z
 
-Section 164.
+@x
+@<Cases for |exp|@>=
+if (cat1==lbrace || cat1==int_like || cat1==decl) {
+  make_underlined(pp); big_app1(pp); big_app(indent); app(indent);
+  reduce(pp,1,fn_decl,0,1);
+}
+@y
+\.{CWEAVE} indents declarations after old-style function definitions.
+With the \.{-i} option they will come out flush left.  You won't see
+any difference if you use ANSI-style function definitions.
+
+@d indent_param_decl flags['i'] /* should formal parameter declarations be indented? */
 
-@x l.3003
+@<Cases for |exp|@>=
+if(cat1==lbrace || cat1==int_like || cat1==decl) {
+  make_underlined(pp); big_app1(pp);
+  if (indent_param_decl) {
+    big_app(indent); app(indent);
+  }
+  reduce(pp,1,fn_decl,0,1);
+}
+@z
+
+@x
+@ @<Cases for |decl_head|@>=
+if (cat1==comma) {
+  big_app2(pp); big_app(' '); reduce(pp,2,decl_head,-1,33);
+}
+else if (cat1==ubinop) {
+  big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
+  reduce(pp,2,decl_head,-1,34);
+}
+else if (cat1==exp && cat2!=lpar && cat2!=exp && cat2!=cast) {
+  make_underlined(pp+1); squash(pp,2,decl_head,-1,35);
+}
+else if ((cat1==binop||cat1==colon) && cat2==exp && (cat3==comma ||
+    cat3==semi || cat3==rpar))
+  squash(pp,3,decl_head,-1,36);
+else if (cat1==cast) squash(pp,2,decl_head,-1,37);
+else if (cat1==lbrace || cat1==int_like || cat1==decl) {
+  big_app1(pp); big_app(indent); app(indent); reduce(pp,1,fn_decl,0,38);
+}
+else if (cat1==semi) squash(pp,2,decl,-1,39);
+@y
+@ @<Cases for |decl_head|@>=
+if (cat1==comma) {
+  big_app2(pp); big_app(' '); reduce(pp,2,decl_head,-1,33);
+}
+else if (cat1==ubinop) {
+  big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
+  reduce(pp,2,decl_head,-1,34);
+}
+else if (cat1==exp && cat2!=lpar && cat2!=exp && cat2!=cast) {
+  make_underlined(pp+1); squash(pp,2,decl_head,-1,35);
+}
+else if ((cat1==binop||cat1==colon) && cat2==exp && (cat3==comma ||
+    cat3==semi || cat3==rpar))
+  squash(pp,3,decl_head,-1,36);
+else if (cat1==cast) squash(pp,2,decl_head,-1,37);
+else if (cat1==lbrace || cat1==int_like || cat1==decl) {
+  big_app1(pp);
+  if (indent_param_decl) {
+    big_app(indent); app(indent);
+  }
+  reduce(pp,1,fn_decl,0,38);
+}
+else if (cat1==semi) squash(pp,2,decl,-1,39);
+@z
+
+@x
+@ @<Cases for |decl|@>=
+if (cat1==decl) {
+  big_app1(pp); big_app(force); big_app1(pp+1);
+  reduce(pp,2,decl,-1,40);
+}
+else if (cat1==stmt || cat1==function) {
+  big_app1(pp); big_app(big_force);
+  big_app1(pp+1); reduce(pp,2,cat1,-1,41);
+}
+@y
+@ The original manual described the \.{-o} option for \.{CWEAVE}, but this was
+not yet present.  Here is a simple implementation.  The purpose is to suppress
+the extra space between local variable declarations and the first statement in
+a function block.
+
+@d order_decl_stmt flags['o'] /* should declarations and statements be separated? */
+
+@<Cases for |decl|@>=
+if (cat1==decl) {
+  big_app1(pp); big_app(force); big_app1(pp+1);
+  reduce(pp,2,decl,-1,40);
+}
+else if (cat1==stmt || cat1==function) {
+  big_app1(pp);
+  if(order_decl_stmt) big_app(big_force);
+  else big_app(force);
+  big_app1(pp+1); reduce(pp,2,cat1,-1,41);
+}
+@z
+
+@x
+@ @<Cases for |fn_decl|@>=
+if (cat1==decl) {
+  big_app1(pp); big_app(force); big_app1(pp+1); reduce(pp,2,fn_decl,0,51);
+}
+else if (cat1==stmt) {
+  big_app1(pp); app(outdent); app(outdent); big_app(force);
+  big_app1(pp+1); reduce(pp,2,function,-1,52);
+}
+@y
+@ Outdent after parameter declarations with option \.{-i}.
+
+@<Cases for |fn_decl|@>=
+if (cat1==decl) {
+  big_app1(pp); big_app(force); big_app1(pp+1); reduce(pp,2,fn_decl,0,51);
+}
+else if (cat1==stmt) {
+  big_app1(pp);
+  if (indent_param_decl) {
+    app(outdent); app(outdent);
+  }
+  big_app(force);
+  big_app1(pp+1); reduce(pp,2,function,-1,52);
+}
+@z
+
+@x
 void
 reduce(j,k,c,d,n)
 scrap_pointer j;
@@ -708,12 +1060,13 @@ eight_bits c;
 short k, d, n;
 @y
 static void
-reduce (scrap_pointer j, short k, eight_bits c, short d, short n)
+reduce(
+scrap_pointer j, short k,
+eight_bits c,
+short d, short n)
 @z
 
-Section 165.
-
-@x l.3029
+@x
 void
 squash(j,k,c,d,n)
 scrap_pointer j;
@@ -721,12 +1074,25 @@ eight_bits c;
 short k, d, n;
 @y
 static void
-squash (scrap_pointer j, short k, eight_bits c, short d, short n)
+squash(
+scrap_pointer j, short k,
+eight_bits c,
+short d, short n)
 @z
 
-Section 169.
+@x
+    overflow("token");
+@y
+    overflow(_("token"));
+@z
+
+@x
+    overflow("text");
+@y
+    overflow(_("text"));
+@z
 
-@x l.3096 -- rename local var, not to shadow param
+@x
 { scrap_pointer k; /* pointer into |scrap_info| */
   if (tracing==2) {
     printf("\n%d:",n);
@@ -750,239 +1116,583 @@ Section 169.
       else if (k_l->mathness /4 ==  no_math) putchar('-');
 @z
 
-Section 170.
-
-@x l.3125
+@x
 text_pointer
 translate() /* converts a sequence of scraps */
 @y
 static text_pointer
-translate (void) /* converts a sequence of scraps */
+translate(void) /* converts a sequence of scraps */
+@z
+
+@x
+    if (tok_ptr+6>tok_mem_end) overflow("token");
+@y
+    if (tok_ptr+6>tok_mem_end) overflow(_("token"));
+@z
+
+@x
+  printf("\nIrreducible scrap sequence in section %d:",section_count);
+@y
+  printf(_("\nIrreducible scrap sequence in section %d:"),section_count);
 @z
 
-Section 174.
+@x
+  printf("\nTracing after l. %d:\n",cur_line); mark_harmless;
+@y
+  printf(_("\nTracing after l. %d:\n"),cur_line); mark_harmless;
+@z
 
-@x l.3190
+@x
 void
 C_parse(spec_ctrl) /* creates scraps from \CEE/ tokens */
   eight_bits spec_ctrl;
 @y
 static void
-C_parse (eight_bits spec_ctrl) /* creates scraps from \CEE/ tokens */
-@z
-
-Section 181.
-
-@x l.3421
+C_parse(@t\1\1@> /* creates scraps from \CEE/ tokens */
+  eight_bits spec_ctrl@t\2\2@>)
+@z
+
+@x
+switch (next_control) {
+  case section_name:
+    app(section_flag+(int)(cur_section-name_dir));
+    app_scrap(section_scrap,maybe_math);
+    app_scrap(exp,yes_math);@+break;
+  case string: case constant: case verbatim: @<Append a string or constant@>;
+   @+break;
+  case identifier: app_cur_id(1);@+break;
+  case TeX_string: @<Append a \TEX/ string, without forming a scrap@>;@+break;
+  case '/': case '.':
+    app(next_control); app_scrap(binop,yes_math);@+break;
+  case '<': app_str("\\langle");@+app_scrap(prelangle,yes_math);@+break;
+@.\\langle@>
+  case '>': app_str("\\rangle");@+app_scrap(prerangle,yes_math);@+break;
+@.\\rangle@>
+  case '=': app_str("\\K"); app_scrap(binop,yes_math);@+break;
+@.\\K@>
+  case '|': app_str("\\OR"); app_scrap(binop,yes_math);@+break;
+@.\\OR@>
+  case '^': app_str("\\XOR"); app_scrap(binop,yes_math);@+break;
+@.\\XOR@>
+  case '%': app_str("\\MOD"); app_scrap(binop,yes_math);@+break;
+@.\\MOD@>
+  case '!': app_str("\\R"); app_scrap(unop,yes_math);@+break;
+@.\\R@>
+  case '~': app_str("\\CM"); app_scrap(unop,yes_math);@+break;
+@.\\CM@>
+  case '+': case '-': app(next_control); app_scrap(ubinop,yes_math);@+break;
+  case '*': app(next_control); app_scrap(raw_ubin,yes_math);@+break;
+  case '&': app_str("\\AND"); app_scrap(raw_ubin,yes_math);@+break;
+@.\\AND@>
+  case '?': app_str("\\?"); app_scrap(question,yes_math);@+break;
+@.\\?@>
+  case '#': app_str("\\#"); app_scrap(ubinop,yes_math);@+break;
+@.\\\#@>
+  case ignore: case xref_roman: case xref_wildcard:
+  case xref_typewriter: case noop:@+break;
+  case '(': case '[': app(next_control); app_scrap(lpar,maybe_math);@+break;
+  case ')': case ']': app(next_control); app_scrap(rpar,maybe_math);@+break;
+  case '{': app_str("\\{"@q}@>); app_scrap(lbrace,yes_math);@+break;
+@.\\\{@>@q}@>
+  case '}': app_str(@q{@>"\\}"); app_scrap(rbrace,yes_math);@+break;
+@q{@>@.\\\}@>
+  case ',': app(','); app_scrap(comma,yes_math);@+break;
+  case ';': app(';'); app_scrap(semi,maybe_math);@+break;
+  case ':': app(':'); app_scrap(colon,no_math);@+break;@/
+  @t\4@>  @<Cases involving nonstandard characters@>@;
+  case thin_space: app_str("\\,"); app_scrap(insert,maybe_math);@+break;
+@.\\,@>
+  case math_break: app(opt); app_str("0");
+    app_scrap(insert,maybe_math);@+break;
+  case line_break: app(force); app_scrap(insert,no_math);@+break;
+  case left_preproc: app(force); app(preproc_line);
+    app_str("\\#"); app_scrap(lproc,no_math);@+break;
+@.\\\#@>
+  case right_preproc: app(force); app_scrap(rproc,no_math);@+break;
+  case big_line_break: app(big_force); app_scrap(insert,no_math);@+break;
+  case no_line_break: app(big_cancel); app(noop); app(break_space);
+    app(noop); app(big_cancel);
+    app_scrap(insert,no_math);@+break;
+  case pseudo_semi: app_scrap(semi,maybe_math);@+break;
+  case macro_arg_open: app_scrap(begin_arg,maybe_math);@+break;
+  case macro_arg_close: app_scrap(end_arg,maybe_math);@+break;
+  case join: app_str("\\J"); app_scrap(insert,no_math);@+break;
+@.\\J@>
+  case output_defs_code: app(force); app_str("\\ATH"); app(force);
+    app_scrap(insert,no_math);@+break;
+@.\\ATH@>
+  default: app(inserted); app(next_control);
+    app_scrap(insert,maybe_math);@+break;
+}
+@y
+switch (next_control) {
+  case section_name:
+    app(section_flag+(int)(cur_section-name_dir));
+    app_scrap(section_scrap,maybe_math);
+    app_scrap(exp,yes_math);@+break;
+  case string: case constant: case verbatim:
+    @<Append a string or constant@>;@+break;
+  case identifier: app_cur_id(1);@+break;
+  case TeX_string:
+    @<Append a \TEX/ string, without forming a scrap@>;@+break;
+  case '/': case '.':
+    app(next_control);@+app_scrap(binop,yes_math);@+break;
+  case '<': app_str("\\langle");@+app_scrap(prelangle,yes_math);@+break;
+@.\\langle@>
+  case '>': app_str("\\rangle");@+app_scrap(prerangle,yes_math);@+break;
+@.\\rangle@>
+  case '=': app_str("\\K");@+app_scrap(binop,yes_math);@+break;
+@.\\K@>
+  case '|': app_str("\\OR");@+app_scrap(binop,yes_math);@+break;
+@.\\OR@>
+  case '^': app_str("\\XOR");@+app_scrap(binop,yes_math);@+break;
+@.\\XOR@>
+  case '%': app_str("\\MOD");@+app_scrap(binop,yes_math);@+break;
+@.\\MOD@>
+  case '!': app_str("\\R");@+app_scrap(unop,yes_math);@+break;
+@.\\R@>
+  case '~': app_str("\\CM");@+app_scrap(unop,yes_math);@+break;
+@.\\CM@>
+  case '+': case '-': app(next_control);@+app_scrap(ubinop,yes_math);@+break;
+  case '*': app(next_control);@+app_scrap(raw_ubin,yes_math);@+break;
+  case '&': app_str("\\AND");@+app_scrap(raw_ubin,yes_math);@+break;
+@.\\AND@>
+  case '?': app_str("\\?");@+app_scrap(question,yes_math);@+break;
+@.\\?@>
+  case '#': app_str("\\#");@+app_scrap(ubinop,yes_math);@+break;
+@.\\\#@>
+  case ignore: case xref_roman: case xref_wildcard:
+  case xref_typewriter: case noop:@+break;
+  case '(': case '[': app(next_control);@+app_scrap(lpar,maybe_math);@+break;
+  case ')': case ']': app(next_control);@+app_scrap(rpar,maybe_math);@+break;
+  case '{': app_str("\\{"@q}@>);@+app_scrap(lbrace,yes_math);@+break;
+@.\\\{@>@q}@>
+  case '}': app_str(@q{@>"\\}");@+app_scrap(rbrace,yes_math);@+break;
+@q{@>@.\\\}@>
+  case ',': app(',');@+app_scrap(comma,yes_math);@+break;
+  case ';': app(';');@+app_scrap(semi,maybe_math);@+break;
+  case ':': app(':');@+app_scrap(colon,no_math);@+break;@/
+  @t\4@>  @<Cases involving nonstandard characters@>@;
+  case thin_space: app_str("\\,");@+app_scrap(insert,maybe_math);@+break;
+@.\\,@>
+  case math_break: app(opt);@+app_str("0");@+
+    app_scrap(insert,maybe_math);@+break;
+  case line_break: app(force);@+app_scrap(insert,no_math);@+break;
+  case left_preproc: app(force);@+app(preproc_line);@+app_str("\\#");
+    app_scrap(lproc,no_math);@+break;
+@.\\\#@>
+  case right_preproc: app(force);@+app_scrap(rproc,no_math);@+break;
+  case big_line_break: app(big_force);@+app_scrap(insert,no_math);@+break;
+  case no_line_break: app(big_cancel);@+app(noop);@+app(break_space);@+
+    app(noop);@+app(big_cancel); app_scrap(insert,no_math);@+break;
+  case pseudo_semi: app_scrap(semi,maybe_math);@+break;
+  case macro_arg_open: app_scrap(begin_arg,maybe_math);@+break;
+  case macro_arg_close: app_scrap(end_arg,maybe_math);@+break;
+  case join: app_str("\\J");@+app_scrap(insert,no_math);@+break;
+@.\\J@>
+  case output_defs_code: app(force);@+app_str("\\ATH");@+app(force);
+    app_scrap(insert,no_math);@+break;
+@.\\ATH@>
+  default: app(inserted);@+app(next_control);
+    app_scrap(insert,maybe_math);@+break;
+}
+@z
+
+@x
+  overflow("scrap/token/text");
+@y
+  overflow(_("scrap/token/text"));
+@z
+
+@x
+case not_eq: app_str("\\I");@+app_scrap(binop,yes_math);@+break;
+@y
+case non_eq: app_str("\\I");@+app_scrap(binop,yes_math);@+break;
+@z
+
+@x
+        else err_print("! Double @@ should be used in strings");
+@y
+        else err_print(_("! Double @@ should be used in strings"));
+@z
+
+@x
 void app_cur_id();
 @y
-static void app_cur_id (boolean);
+void app_cur_id(boolean);@/
 @z
 
-Section 182.
-
-@x l.3424
+@x
 void
 app_cur_id(scrapping)
 boolean scrapping; /* are we making this into a scrap? */
 @y
-static void
-app_cur_id (boolean scrapping)
+void
+app_cur_id(@t\1\1@>
+boolean scrapping@t\2\2@>) /* are we making this into a scrap? */
 @z
 
-Section 183.
-
-@x l.3449
+@x
 text_pointer
 C_translate()
 @y
 static text_pointer
-C_translate (void)
+C_translate(void)
 @z
 
-Section 184.
+@x
+  if (next_control!='|') err_print("! Missing '|' after C text");
+@y
+  if (next_control!='|') err_print(_("! Missing '|' after C text"));
+@z
 
-@x l.3479
+@x
 void
 outer_parse() /* makes scraps from \CEE/ tokens and comments */
 @y
 static void
-outer_parse (void) /* makes scraps from \CEE/ tokens and comments */
+outer_parse(void) /* makes scraps from \CEE/ tokens and comments */
 @z
 
-Section 189.
-
-@x l.3585
+@x
 void
 push_level(p) /* suspends the current level */
 text_pointer p;
 @y
 static void
-push_level (text_pointer p) /* suspends the current level */
+push_level(@t\1\1@> /* suspends the current level */
+text_pointer p@t\2\2@>)
 @z
 
-Section 190.
+@x
+  if (stack_ptr==stack_end) overflow("stack");
+@y
+  if (stack_ptr==stack_end) overflow(_("stack"));
+@z
 
-@x l.3605
+@x
 void
 pop_level()
 @y
 static void
-pop_level (void)
+pop_level(void)
 @z
 
-Section 192.
-
-@x l.3627
+@x
 eight_bits
 get_output() /* returns the next token of output */
 @y
 static eight_bits
-get_output (void) /* returns the next token of output */
+get_output(void) /* returns the next token of output */
 @z
 
-Section 193.
+@x
+  return(a);
+@y
+  return((eight_bits)a);
+@z
 
-@x l.3664
+@x
 void
 output_C() /* outputs the current token list */
 @y
 static void
-output_C (void) /* outputs the current token list */
+output_C(void) /* outputs the current token list */
 @z
 
-Section 194.
-
-@x l.3687
+@x
 void make_output();
 @y
-static void make_output (void);
+static void make_output(void);@/
 @z
 
-Section 195.
-
-@x l.3690
+@x
 void
 make_output() /* outputs the equivalents of tokens */
+{
+  eight_bits a, /* current output byte */
 @y
 static void
-make_output (void) /* outputs the equivalents of tokens */
+make_output(void) /* outputs the equivalents of tokens */
+{
+  eight_bits a=0, /* current output byte */
 @z
 
-Section 202.
+@x
+  else if (b!='|') out(b)@;
+@y
+  else { if (b!='|') out(b)@;
+@z
 
-@x l.3927
+@x
+  }
+@y
+  } }
+@z
+
+@x
+  printf("\n! Illegal control code in section name: <");
+@y
+  fputs(_("\n! Illegal control code in section name: <"),stdout);
+@z
+
+@x
+    printf("\n! C text in section name didn't end: <");
+@y
+    fputs(_("\n! C text in section name didn't end: <"),stdout);
+@z
+
+@x
     if (b=='\'' || b=='"')
       if (delim==0) delim=b;
       else if (delim==b) delim=0;
 @y
     if (b=='\'' || b=='"') {
       if (delim==0) delim=b;
-      else if (delim==b) delim=0;
-    }
+      else if (delim==b) delim=0; }
 @z
 
-Section 205.
+@x
+      if (j>buffer+long_buf_size-3) overflow("buffer");
+@y
+      if (j>buffer+long_buf_size-3) overflow(_("buffer"));
+@z
 
-@x l.3951
-void phase_two();
+@x
+  if (j>buffer+long_buf_size-4) overflow("buffer");
 @y
-static void phase_two (void);
+  if (j>buffer+long_buf_size-4) overflow(_("buffer"));
 @z
 
-Section 206.
+@x
+void phase_two();
+@y
+static void phase_two(void);@/
+@z
 
-@x l.3955
+@x
 void
 phase_two() {
 @y
 static void
-phase_two (void) {
+phase_two(void) {
 @z
 
-Section 212.
+@x
+reset_input(); if (show_progress) printf("\nWriting the output file...");
+@y
+reset_input(); if (show_progress) fputs(_("\nWriting the output file..."),stdout);
+@z
 
-@x l.4074
-void finish_C();
+@x
+        err_print("! TeX string should be in C text only"); break;
+@y
+        err_print(_("! TeX string should be in C text only")); break;
+@z
+
+@x
+        err_print("! You can't do that in TeX text"); break;
 @y
-static void finish_C (boolean);
+        err_print(_("! You can't do that in TeX text")); break;
 @z
 
-Section 213.
+@x
+void finish_C();
+@y
+static void finish_C(boolean);@/
+@z
 
-@x l.4077
+@x
 void
 finish_C(visible) /* finishes a definition or a \CEE/ part */
   boolean visible; /* nonzero if we should produce \TEX/ output */
 @y
 static void
-finish_C (boolean visible) /* finishes a definition or a \CEE/ part */
+finish_C(@t\1\1@> /* finishes a definition or a \Cee\ part */
+  boolean visible@t\2\2@>) /* nonzero if we should produce \TeX\ output */
 @z
 
-Section 212.
-
-@x l.4092
+@x
+    if (out_ptr>out_buf+1)
+      if (*(out_ptr-1)=='\\')
+@.\\6@>
+@.\\7@>
+@.\\Y@>
         if (*out_ptr=='6') out_ptr-=2;
         else if (*out_ptr=='7') *out_ptr='Y';
 @y
-      {
+    if (out_ptr>out_buf+1) {
+      if (*(out_ptr-1)=='\\') {
+@.\\6@>
+@.\\7@>
+@.\\Y@>
         if (*out_ptr=='6') out_ptr-=2;
         else if (*out_ptr=='7') *out_ptr='Y';
       }
+    }
 @z
 
-Section 221.
+@x
+    err_print("! Improper macro definition");
+@y
+    err_print(_("! Improper macro definition"));
+@z
 
-@x l.4245
-void footnote();
+@x
+      default: err_print("! Improper macro definition"); break;
+@y
+      default: err_print(_("! Improper macro definition")); break;
+@z
+
+@x
+  if (scrap_ptr!=scrap_info+2) err_print("! Improper format definition");
+@y
+  if (scrap_ptr!=scrap_info+2) err_print(_("! Improper format definition"));
+@z
+
+@x
+  err_print("! You need an = sign after the section name");
 @y
-static void footnote (sixteen_bits);
+  err_print(_("! You need an = sign after the section name"));
 @z
 
-Section 222.
+@x
+  err_print("! You can't do that in C text");
+@y
+  err_print(_("! You can't do that in C text"));
+@z
+
+@x
+void footnote();
+@y
+static void footnote(sixteen_bits);@/
+@z
 
-@x l.4248
+@x
 void
 footnote(flag) /* outputs section cross-references */
 sixteen_bits flag;
 @y
 static void
-footnote (sixteen_bits flag) /* outputs section cross-references */
+footnote(@t\1\1@> /* outputs section cross-references */
+sixteen_bits flag@t\2\2@>)
 @z
 
-Section 225.
-
-@x l.4294
+@x
 void phase_three();
 @y
-static void phase_three (void);
+static void phase_three(void);@/
 @z
 
-Section 226.
-
-@x l.4297
+@x
 void
 phase_three() {
 @y
 static void
-phase_three (void) {
+phase_three(void) {
+@z
+
+@x
+if (no_xref) {
+  finish_line();
+  out_str("\\end");
+@.\\end@>
+  finish_line();
+}
+@y
+if (no_xref) {
+  finish_line();
+  out_str("\\end");
+@.\\end@>
+  active_file=tex_file;
+}
 @z
 
-@x l.4309 Use binary mode for output files
+@x
+  phase=3; if (show_progress) printf("\nWriting the index...");
+@y
+  phase=3; if (show_progress) fputs(_("\nWriting the index..."),stdout);
+@z
+
+@x
   if ((idx_file=fopen(idx_file_name,"w"))==NULL)
 @y
   if ((idx_file=fopen(idx_file_name,"wb"))==NULL)
 @z
 
-@x l.4324 Use binary mode for output files
+@x
+    fatal("! Cannot open index file ",idx_file_name);
+@y
+    fatal(_("! Cannot open index file "),idx_file_name);
+@z
+
+@x
+    @<Tell about changed sections@>; finish_line(); finish_line();
+@y
+    @<Tell about changed sections@>@; finish_line(); finish_line();
+@z
+
+@x
+  @<Do the first pass of sorting@>;
+  @<Sort and output the index@>;
+@y
+  @<Do the first pass of sorting@>@;
+  @<Sort and output the index@>@;
+@z
+
+@x
   if ((scn_file=fopen(scn_file_name,"w"))==NULL)
 @y
   if ((scn_file=fopen(scn_file_name,"wb"))==NULL)
 @z
 
-Section 235.
+@x
+    fatal("! Cannot open section file ",scn_file_name);
+@y
+    fatal(_("! Cannot open section file "),scn_file_name);
+@z
+
+@x
+  @<Output all the section names@>;
+@y
+  @<Output all the section names@>@;
+@z
+
+@x
+@.\\end@>
+  finish_line();
+  fclose(active_file);
+}
+@y
+@.\\end@>
+}
+finish_line(); fclose(active_file); active_file=NULL;
+@<Update the result when it has changed@>@;
+@z
+
+@x
+if (show_happiness) printf("\nDone.");
+@y
+if (show_happiness) {
+  if (show_progress) new_line;
+  fputs(_("Done."),stdout);
+}
+@z
 
-@x l.4440
+@x
+for (c=0; c<=255; c++) bucket[c]=NULL;
+@y
+for (c=0; c<256; c++) bucket[c]=NULL;
+@z
+
+@x
+    if (cur_name->xref!=(char*)xmem) {
+@y
+    if (cur_name->xref!=(void *)xmem) {
+@z
+
+@x
+collate[0]=0;
 strcpy(collate+1," \1\2\3\4\5\6\7\10\11\12\13\14\15\16\17");
 /* 16 characters + 1 = 17 */
 strcpy(collate+17,"\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37");
@@ -1006,85 +1716,266 @@ strcpy(collate+181,"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336
 strcpy(collate+197,"\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357");
 /* 16 characters + 197 = 213 */
 strcpy(collate+213,"\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377");
+/* 16 characters + 213 = 229 */
 @y
-strcpy((char *)collate+1," \1\2\3\4\5\6\7\10\11\12\13\14\15\16\17");
+collate[0]=0;
+strcpy((char *)collate+1,
+  " \1\2\3\4\5\6\7\10\11\12\13\14\15\16\17");
 /* 16 characters + 1 = 17 */
-strcpy((char *)collate+17,"\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37");
+strcpy((char *)collate+17,
+  "\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37");
 /* 16 characters + 17 = 33 */
-strcpy((char *)collate+33,"!\42#$%&'()*+,-./:;<=>?@@[\\]^`{|}~_");
+strcpy((char *)collate+33,
+  "!\42#$%&'()*+,-./:;<=>?@@[\\]^`{|}~_");
 /* 32 characters + 33 = 65 */
-strcpy((char *)collate+65,"abcdefghijklmnopqrstuvwxyz0123456789");
+strcpy((char *)collate+65,
+  "abcdefghijklmnopqrstuvwxyz0123456789");
 /* (26 + 10) characters + 65 = 101 */
-strcpy((char *)collate+101,"\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217");
+strcpy((char *)collate+101,
+  "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217");
 /* 16 characters + 101 = 117 */
-strcpy((char *)collate+117,"\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237");
+strcpy((char *)collate+117,
+  "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237");
 /* 16 characters + 117 = 133 */
-strcpy((char *)collate+133,"\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257");
+strcpy((char *)collate+133,
+  "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257");
 /* 16 characters + 133 = 149 */
-strcpy((char *)collate+149,"\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277");
+strcpy((char *)collate+149,
+  "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277");
 /* 16 characters + 149 = 165 */
-strcpy((char *)collate+165,"\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317");
+strcpy((char *)collate+165,
+  "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317");
 /* 16 characters + 165 = 181 */
-strcpy((char *)collate+181,"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337");
+strcpy((char *)collate+181,
+  "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337");
 /* 16 characters + 181 = 197 */
-strcpy((char *)collate+197,"\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357");
+strcpy((char *)collate+197,
+  "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357");
 /* 16 characters + 197 = 213 */
-strcpy((char *)collate+213,"\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377");
+strcpy((char *)collate+213,
+  "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377");
+/* 16 characters + 213 = 229 */
 @z
 
-Section 237.
-
-@x l.4474
+@x
 void  unbucket();
 @y
-static void unbucket (eight_bits);
+static void unbucket(eight_bits);@/
 @z
 
-Section 238.
-
-@x l.4477
+@x
 void
 unbucket(d) /* empties buckets having depth |d| */
 eight_bits d;
 @y
 static void
-unbucket (eight_bits d) /* empties buckets having depth |d| */
+unbucket(@t\1\1@> /* empties buckets having depth |d| */
+eight_bits d@t\2\2@>)
 @z
 
-Section 246.
+@x
+    if (sort_ptr>=scrap_info_end) overflow("sorting");
+@y
+    if (sort_ptr>=scrap_info_end) overflow(_("sorting"));
+@z
 
-@x l.4594
+@x
 void section_print();
 @y
-static void section_print (name_pointer);
+static void section_print(name_pointer);@/
 @z
 
-Section 247.
-
-@x l.4597
+@x
 void
 section_print(p) /* print all section names in subtree |p| */
 name_pointer p;
 @y
 static void
-section_print (name_pointer p) /* print all section names in subtree |p| */
+section_print(@t\1\1@> /* print all section names in subtree |p| */
+name_pointer p@t\2\2@>)
 @z
 
-Section 249.
-
-@x l.4620
-print_stats() {
+@x
+@ @<Output all the section names@>=section_print(root)
 @y
-print_stats (void) {
+@ @<Output all the section names@>=section_print(root);
 @z
 
-Section 250. (added)
-
-@x l.4643 - declare print_text(), so it can be 'used' in main.
+@x
+void
+print_stats() {
+@y
+void
+print_stats(void) {
+@z
+
+@x
+  printf("\nMemory usage statistics:\n");
+@.Memory usage statistics:@>
+  printf("%ld names (out of %ld)\n",
+            (long)(name_ptr-name_dir),(long)max_names);
+  printf("%ld cross-references (out of %ld)\n",
+            (long)(xref_ptr-xmem),(long)max_refs);
+  printf("%ld bytes (out of %ld)\n",
+            (long)(byte_ptr-byte_mem),(long)max_bytes);
+  printf("Parsing:\n");
+  printf("%ld scraps (out of %ld)\n",
+            (long)(max_scr_ptr-scrap_info),(long)max_scraps);
+  printf("%ld texts (out of %ld)\n",
+            (long)(max_text_ptr-tok_start),(long)max_texts);
+  printf("%ld tokens (out of %ld)\n",
+            (long)(max_tok_ptr-tok_mem),(long)max_toks);
+  printf("%ld levels (out of %ld)\n",
+            (long)(max_stack_ptr-stack),(long)stack_size);
+  printf("Sorting:\n");
+  printf("%ld levels (out of %ld)\n",
+            (long)(max_sort_ptr-scrap_info),(long)max_scraps);
+}
+@y
+  puts(_("\nMemory usage statistics:"));
+@.Memory usage statistics:@>
+  printf(_("%ld names (out of %ld)\n"),
+            (long)(name_ptr-name_dir),(long)max_names);
+  printf(_("%ld cross-references (out of %ld)\n"),
+            (long)(xref_ptr-xmem),(long)max_refs);
+  printf(_("%ld bytes (out of %ld)\n"),
+            (long)(byte_ptr-byte_mem),(long)max_bytes);
+  puts(_("Parsing:"));
+  printf(_("%ld scraps (out of %ld)\n"),
+            (long)(max_scr_ptr-scrap_info),(long)max_scraps);
+  printf(_("%ld texts (out of %ld)\n"),
+            (long)(max_text_ptr-tok_start),(long)max_texts);
+  printf(_("%ld tokens (out of %ld)\n"),
+            (long)(max_tok_ptr-tok_mem),(long)max_toks);
+  printf(_("%ld levels (out of %ld)\n"),
+            (long)(max_stack_ptr-stack),(long)stack_size);
+  puts(_("Sorting:"));
+  printf(_("%ld levels (out of %ld)\n"),
+            (long)(max_sort_ptr-scrap_info),(long)max_scraps);
+}
+@z
+
+@x
 @** Index.
 @y
-@ @<Predecl...@>=
-static void print_text (text_pointer p);
+@** Extensions for modern {\tt CWEB}.
+
+The following sections introduce code changes and extensions that have been
+created by numerous contributors over the course of a quarter century. They
+make \.{CWEB} adhere to modern coding standards and introduce new or improved
+features.
+
+Care has been taken to keep the original section numbering intact, so this new
+section should have the same number as the original ``\&{250.~Index},'' and
+additional material follows below.
+
+@* Set {\tt CWEAVE} flags.
+At least one of these is already used in \.{COMMON}.
+
+@<Set init...@>=
+  make_xrefs=force_lines=make_pb=indent_param_decl=order_decl_stmt=1;
+    /* controlled by command-line options */
+
+@* Function declarations.  Here are declarations---conforming to
+{\mc ANSI~C}---of all functions in this code, as far as they are
+not already in |"common.h"|.  These are private to \.{CWEAVE}.
+
+@<Predecl...@>=
+static eight_bits copy_TeX(void);@/
+static eight_bits get_output(void);@/
+static eight_bits skip_TeX(void);@/
+static text_pointer C_translate(void);@/
+static text_pointer translate(void);@/
+static token_pointer find_first_ident(text_pointer);@/
+static void app_str(const char *);@/
+static void big_app(token);@/
+static void big_app1(scrap_pointer);@/
+static void copy_limbo(void);@/
+static void C_parse(eight_bits);@/
+static void finish_line(void);@/
+static void flush_buffer(char *,boolean,boolean);@/
+static void make_reserved(scrap_pointer);@/
+static void make_underlined(scrap_pointer);@/
+static void new_section_xref(name_pointer);@/
+static void new_xref(name_pointer);@/
+static void outer_parse(void);@/
+static void output_C(void);@/
+static void out_name(name_pointer,boolean);@/
+static void out_section(sixteen_bits);@/
+static void out_str(const char *);@/
+static void pop_level(void);@/
+static void print_cat(eight_bits);@/
+#ifdef DEAD_CODE
+static void print_text(text_pointer p);@/
+#endif
+static void push_level(text_pointer);@/
+static void reduce(scrap_pointer,short,eight_bits,short,short);@/
+static void set_file_flag(name_pointer);@/
+static void skip_limbo(void);@/
+static void squash(scrap_pointer,short,eight_bits,short,short);@/
+static void update_node(name_pointer p);@/
+
+@* Output file update.  Most \CEE/ projects are controlled by a
+\.{Makefile} that automatically takes care of the temporal dependecies
+between the different source modules.  It is suitable that \.{CWEB} doesn't
+create new output for all existing files, when there are only changes to
+some of them. Thus the \.{make} process will only recompile those modules
+where necessary. The idea and basic implementation of this mechanism can
+be found in the program \.{NUWEB} by Preston Briggs, to whom credit is due.
+
+@<Update the result...@>=
+if((tex_file=fopen(tex_file_name,"r"))!=NULL) {
+  char x[BUFSIZ],y[BUFSIZ];
+  int x_size,y_size,comparison;
+
+  if((check_file=fopen(check_file_name,"r"))==NULL)
+    fatal(_("! Cannot open output file "),check_file_name);
+@.Cannot open output file@>
+
+  @<Compare the temporary output to the previous output@>@;
+
+  fclose(tex_file); tex_file=NULL;
+  fclose(check_file); check_file=NULL;
+
+  @<Take appropriate action depending on the comparison@>@;
+} else
+  rename(check_file_name,tex_file_name); /* This was the first run */
+
+strcpy(check_file_name,""); /* We want to get rid of the temporary file */
+
+@ We hope that this runs fast on most systems.
+
+@<Compare the temp...@>=
+do {
+  x_size = fread(x,1,BUFSIZ,tex_file);
+  y_size = fread(y,1,BUFSIZ,check_file);
+  comparison = (x_size == y_size); /* Do not merge these statements! */
+  if(comparison) comparison = !memcmp(x,y,x_size);
+} while(comparison && !feof(tex_file) && !feof(check_file));
+
+@ Note the superfluous call to |remove| before |rename|.  We're using it to
+get around a bug in some implementations of |rename|.
+
+@<Take appropriate action...@>=
+if(comparison)
+  remove(check_file_name); /* The output remains untouched */
+else {
+  remove(tex_file_name);
+  rename(check_file_name,tex_file_name);
+}
+
+@* Put ``version'' information in a single spot.
+Don't do this at home, kids! Push our local macro to the variable in \.{COMMON}
+for printing the |banner| and the |versionstring| from there.
+
+@d max_banner 50
+
+@<Common code...@>=
+extern char cb_banner[];
+
+@ @<Set init...@>=
+  strncpy(cb_banner,banner,max_banner-1);
 
 @** Index.
 @z
+
diff --git a/source/texk/web2c/help.h b/source/texk/web2c/help.h
index ffde71c0b49f2436701fe321ad6d02864b350e58..b2a61fd6a337429fc8243508ae891d5a46996db7 100644
--- a/source/texk/web2c/help.h
+++ b/source/texk/web2c/help.h
@@ -10,7 +10,7 @@
    thing, the messages have a lot in common, so it's nice to have them
    in one place.)
 
-Copyright 1995, 1996, 2009, 2011, 2012 Karl Berry.
+Copyright 1995, 1996, 2009, 2011-2019 Karl Berry.
 Copyright 2008 Taco Hoekwater.
 Copyright 2001, 2003, 2004 Olaf Weber.
 
@@ -56,9 +56,11 @@ const_string CTANGLEHELP[] = {
     "  unless otherwise specified by OUTFILE; in this case, '-' specifies",
     "  a null CHANGEFILE.",
     "",
-    "-b          suppress banner line on terminal",
-    "-h          suppress success message on completion",
-    "-p          suppress progress report messages",
+    "+b          print banner line on terminal",
+    "+h          print success message on completion",
+    "+p          print progress report messages",
+    "+/-q        shortcut for '-bhp'; also '--quiet' (default)",
+    "+/-v        shortcut for '+bhp'; also '--verbose'",
     "+s          print usage statistics",
     "--help      display this help and exit",
     "--version   output version information and exit",
@@ -73,12 +75,43 @@ const_string CWEAVEHELP[] = {
     "  unless otherwise specified by OUTFILE; in this case, '-' specifies",
     "  a null CHANGEFILE.",
     "",
-    "-b          suppress banner line on terminal",
+    "+b          print banner line on terminal",
+    "+h          print success message on completion",
+    "+p          print progress report messages",
+    "+/-q        shortcut for '-bhp'; also '--quiet' (default)",
+    "+/-v        shortcut for '+bhp'; also '--verbose'",
+    "-e          do not enclose C material in \\PB{...}",
     "-f          do not force a newline after every C statement in output",
-    "-h          suppress success message on completion",
-    "-p          suppress progress report messages",
+    "-i          suppress indentation of parameter declarations",
+    "-o          suppress separation of declarations and statements",
     "-x          omit indices, section names, table of contents",
-    "+e          enclose C material in \\PB{...}",
+    "+lX         use macros for language X as of Xcwebmac.tex",
+    "+s          print usage statistics",
+    "--help      display this help and exit",
+    "--version   output version information and exit",
+    NULL
+};
+
+const_string CTWILLHELP[] = {
+    "Usage: ctwill [OPTIONS] WEBFILE[.w] [{CHANGEFILE[.ch]|-} [OUTFILE[.tex]]]",
+    "  Weave WEBFILE with CHANGEFILE into a TeX document with mini-indexes.",
+    "  Default CHANGEFILE is " DEV_NULL ";",
+    "  TeX output goes to the basename of WEBFILE extended with `.tex'",
+    "  unless otherwise specified by OUTFILE; in this case, '-' specifies",
+    "  a null CHANGEFILE.",
+    "",
+    "+b          print banner line on terminal",
+    "+h          print success message on completion",
+    "+p          print progress report messages",
+    "+/-q        shortcut for '-bhp'; also '--quiet' (default)",
+    "+/-v        shortcut for '+bhp'; also '--verbose'",
+    "-e          do not enclose C material in \\PB{...}",
+    "-f          do not force a newline after every C statement in output",
+    "-i          suppress indentation of parameter declarations",
+    "-o          suppress separation of declarations and statements",
+    "-x          omit indices, section names, table of contents",
+    "+P          \\input ctproofmac.tex instead of ctwimac.tex",
+    "+/-lX       use macros for language X as of Xct{wi|proof}mac.tex",
     "+s          print usage statistics",
     "--help      display this help and exit",
     "--version   output version information and exit",
diff --git a/source/texk/web2c/luatexdir/luaffi/call_arm.dasc b/source/texk/web2c/luatexdir/luaffi/call_arm.dasc
index f85753255fb2b191f3121af863b9cb3c99281407..a92bd1637d78ba8ff40b7fad49945c1315b8f427 100644
--- a/source/texk/web2c/luatexdir/luaffi/call_arm.dasc
+++ b/source/texk/web2c/luatexdir/luaffi/call_arm.dasc
@@ -217,7 +217,7 @@ cfunction compile_callback(lua_State* L, int fidx, int ct_usr, const struct ctyp
         | load32 r3, mt
         | mov r2, #0 // -1 - ct_usr
         | mvn r1, #1 // -2 - val
-        | lcall extern to_typed_pointer
+        | lcall extern check_typed_pointer
         | mov DATA, r0
         | mvn r1, #3 // -4 - remove 3 (upval table, ret val, usr value)
         | lcall extern lua_settop
@@ -235,7 +235,7 @@ cfunction compile_callback(lua_State* L, int fidx, int ct_usr, const struct ctyp
             | load32 r3, mt
             | mvn r2, #0 // -1 - ct_usr
             | mvn r1, #1 // -2 - val
-            | lcall extern to_enum
+            | lcall extern check_enum
             | mov DATA, r0
             | mvn r1, #3 // -4 - remove 3 (upval table, ret val, usr value)
             | lcall extern lua_settop
@@ -271,7 +271,7 @@ cfunction compile_callback(lua_State* L, int fidx, int ct_usr, const struct ctyp
 
         case INTPTR_TYPE:
             | mvn r1, #0 // -1
-            | lcall extern check_intptr
+            | lcall extern check_uintptr
             goto single;
 
         case FLOAT_TYPE:
@@ -393,11 +393,11 @@ void compile_function(lua_State* L, cfunction func, int ct_usr, const struct cty
             | mov r0, L_ARG
 
             if (mt->pointers || mt->is_reference) {
-                | bl extern to_typed_pointer
+                | bl extern check_typed_pointer
             } else if (mt->type == FUNCTION_PTR_TYPE) {
-                | bl extern to_typed_function
+                | bl extern check_typed_cfunction
             } else if (mt->type == ENUM_TYPE) {
-                | bl extern to_enum
+                | bl extern check_enum
             }
 
             | str r0, [DATA], #4
@@ -456,7 +456,7 @@ void compile_function(lua_State* L, cfunction func, int ct_usr, const struct cty
                 break;
 
             case INTPTR_TYPE:
-                | lcall extern check_intptr
+                | lcall extern check_uintptr
                 | str r0, [DATA], #4
                 break;
 
diff --git a/source/texk/web2c/luatexdir/luaffi/call_arm.h b/source/texk/web2c/luatexdir/luaffi/call_arm.h
index efe7f9567e37c2b003d058edc3dea35fe98eadb6..d6d5a01c6dd25369cb1b354e9bddaf7283c6eba2 100644
--- a/source/texk/web2c/luatexdir/luaffi/call_arm.h
+++ b/source/texk/web2c/luatexdir/luaffi/call_arm.h
@@ -579,19 +579,19 @@ static const char *const extnames[] = {
   "push_float",
   "lua_pushnumber",
   "lua_callk",
-  "to_typed_pointer",
+  "check_typed_pointer",
   "lua_settop",
-  "to_enum",
+  "check_enum",
   "check_uint32",
   "check_int32",
   "check_uint64",
   "check_int64",
-  "check_intptr",
+  "check_uintptr",
   "check_float",
   "check_double",
   "lua_gettop",
   "luaL_error",
-  "to_typed_function",
+  "check_typed_cfunction",
   "unpack_varargs_stack",
   "SetLastError",
   "FUNCTION",
diff --git a/source/texk/web2c/luatexdir/luaffi/ffi.c b/source/texk/web2c/luatexdir/luaffi/ffi.c
index 7771b512db5c0d3239d50a718ba1f4d6a3de60d2..03667d9f582cc3c2f4e9f5830241bfc69b9cefd0 100644
--- a/source/texk/web2c/luatexdir/luaffi/ffi.c
+++ b/source/texk/web2c/luatexdir/luaffi/ffi.c
@@ -3576,7 +3576,7 @@ int luaopen_ffi(lua_State *L)
 "\n"
 "The ARM processor is currently not supported. There are subtle\n"
 "differences between this module and the one in luajitTeX \n"
-"and we hope to be in sync around TeXLive 2018.\n"
+"and we hope to be in sync around TeXLive 2020.\n"
 "Different OS can have different interfaces,\n"
 "for instance OS_WIN has not 'complex.h'. If you want portable\n"
 "code, stick to the most common concepts.\n"
diff --git a/source/texk/web2c/luatexdir/luaffi/ffi.h b/source/texk/web2c/luatexdir/luaffi/ffi.h
index 8190a973892794c9cfd89feb1fbda026cedb1c52..8611409252ca37c94676c4653aa9d5e71881faf4 100644
--- a/source/texk/web2c/luatexdir/luaffi/ffi.h
+++ b/source/texk/web2c/luatexdir/luaffi/ffi.h
@@ -148,7 +148,7 @@ static void (lua_remove)(lua_State *L, int idx) {
 
 /* See ffi.c: replace luaopen_ffi with a stub    */
 /* if FFI_ENABLE_LUATEX_INTERFACE is not defined */
-#if (defined ARCH_X86 || defined ARCH_X64) && (defined OS_CE || defined OS_WIN || defined OS_LINUX || defined OS_BSD || defined OS_POSIX || defined OS_OSX)
+#if (defined ARCH_X86 || defined ARCH_X64 ||defined ARCH_ARM) && (defined OS_CE || defined OS_WIN || defined OS_LINUX || defined OS_BSD || defined OS_POSIX || defined OS_OSX)
 #define FFI_ENABLE_LUATEX_INTERFACE
 #endif 
 /* for the moment */
diff --git a/source/texk/web2c/luatexdir/luatex_svnversion.h b/source/texk/web2c/luatexdir/luatex_svnversion.h
index 4e917c56d27889150612e162462d56c757e8688c..bf2491277a5ef283a6bbbfef5624e17945d20924 100644
--- a/source/texk/web2c/luatexdir/luatex_svnversion.h
+++ b/source/texk/web2c/luatexdir/luatex_svnversion.h
@@ -1 +1 @@
-#define luatex_svn_revision 7038
+#define luatex_svn_revision 7039
diff --git a/source/texk/web2c/man/ChangeLog b/source/texk/web2c/man/ChangeLog
index 38f3f7588edd7b5c7bed4c972bbd7ab2a156162b..af11ec2d850c31fdcc18396c9a88d07674dfc070 100644
--- a/source/texk/web2c/man/ChangeLog
+++ b/source/texk/web2c/man/ChangeLog
@@ -1,3 +1,17 @@
+2019-01-10  Andreas Scherer  <https://ascherer.github.io>
+
+	* ctwill.man: New manpage for CTWILL and its tools.
+	* Makefile.am (bootstrap_man_sources): add ctwill.man.
+	(man1_links): add ctwill-refsort and ctwill-twinx as ctwill aliases.
+
+2019-01-10  Andreas Scherer  <https://ascherer.github.io>
+
+	* cweb.man: editorial changes.
+
+2019-01-06  Andreas Scherer  <https://ascherer.github.io>
+
+	* cweb.man: update for CWEBbin options, etc.
+
 2018-12-21  Karl Berry  <karl@freefriends.org>
 
 	* mpost.man: mention rmpost, (r)pmpost, and (r)upmpost.
diff --git a/source/texk/web2c/man/Makefile.am b/source/texk/web2c/man/Makefile.am
index 6cd8b3d21b1f0e2d9213f42eb5f39cca00f05f1d..0920d8f092de694a23122bfca493a58a607d06b1 100644
--- a/source/texk/web2c/man/Makefile.am
+++ b/source/texk/web2c/man/Makefile.am
@@ -1,4 +1,4 @@
-## $Id: Makefile.am 48174 2018-07-10 16:28:20Z karl $
+## $Id: Makefile.am 49666 2019-01-10 23:03:46Z karl $
 ## Makefile.am for the TeX Live subdirectory texk/web2c/man/
 ## Copyright 2018 Karl Berry <tex-live@tug.org>
 ## Copyright 2009-2015 Peter Breitenlohner <tex-live@tug.org>
@@ -6,10 +6,11 @@
 ##
 man_sources = $(bootstrap_man_sources)
 EXTRA_DIST = $(bootstrap_man_sources)
-bootstrap_man_sources = ctie.man cweb.man tangle.man tie.man
+bootstrap_man_sources = ctie.man cweb.man ctwill.man tangle.man tie.man
 
 # Symlinks within $(man1dir): FILE:LINK indicates LINK.1->FILE.1
 man1_links = cweb:ctangle cweb:cweave
+man1_links += ctwill:ctwill-refsort ctwill:ctwill-twinx
 
 if WEB
 man_sources += $(web_man_sources)
diff --git a/source/texk/web2c/man/Makefile.in b/source/texk/web2c/man/Makefile.in
index 8b81675694c0cae03f87425a966b3ae8278c1212..a77f48ae443a0e0e070d64d395fe6a3d2713da54 100644
--- a/source/texk/web2c/man/Makefile.in
+++ b/source/texk/web2c/man/Makefile.in
@@ -448,10 +448,11 @@ EXTRA_DIST = $(bootstrap_man_sources) $(web_man_sources) tex.man \
 	mf.man mpost.man etex.man $(pdftex_man_sources) ptex.man \
 	luatex.man xetex.man $(otangle_man_sources) aleph.man \
 	$(misc_man_sources) spell.add
-bootstrap_man_sources = ctie.man cweb.man tangle.man tie.man
+bootstrap_man_sources = ctie.man cweb.man ctwill.man tangle.man tie.man
 
 # Symlinks within $(man1dir): FILE:LINK indicates LINK.1->FILE.1
-man1_links = cweb:ctangle cweb:cweave $(am__append_3) $(am__append_5) \
+man1_links = cweb:ctangle cweb:cweave ctwill:ctwill-refsort \
+	ctwill:ctwill-twinx $(am__append_3) $(am__append_5) \
 	$(am__append_6) $(am__append_10) $(am__append_12) \
 	$(am__append_14) $(am__append_17) $(am__append_19)
 web_man_sources = bibtex.man dvicopy.man dvitomp.man dvitype.man gftodvi.man \
diff --git a/source/texk/web2c/man/ctwill.man b/source/texk/web2c/man/ctwill.man
new file mode 100644
index 0000000000000000000000000000000000000000..e92a6e0b6849359cc4d0c332e5119d8bef445499
--- /dev/null
+++ b/source/texk/web2c/man/ctwill.man
@@ -0,0 +1,198 @@
+.\" Automatically generated by Pandoc 2.5
+.\"
+.TH "CTWILL" "1" "January 11, 2019" "Web2c @VERSION@" "General Commands Manual"
+.hy
+.SH NAME
+.PP
+ctwill, ctwill-refsort, ctwill-twinx \[en] translate CWEB to TeX
+.PD 0
+.P
+.PD
+with mini\-indexes per spread or per section
+.SH SYNOPSIS
+.PP
+\f[B]ctwill\f[R] [\f[I]options\f[R]] \f[I]webfile\f[R][.w]
+[{\f[I]changefile\f[R][.ch]|\-} [\f[I]outfile\f[R][.tex]]]
+.PD 0
+.P
+.PD
+\f[B]ctwill-refsort\f[R] < \f[I]indexfile\f[R].ref > \f[I]indexfile\f[R].sref
+.PD 0
+.P
+.PD
+\f[B]ctwill-twinx\f[R] \f[I]outfile\f[R].tex [\f[I]outfile\f[R].tex \&...] >
+index.tex
+.SH DESCRIPTION
+.PP
+The \f[B]ctwill\f[R] program converts a CWEB source document into a TeX
+file that may be formatted and printed in the usual way.
+It takes appropriate care of typographic details like page layout and
+the use of indentation, \f[I]italics\f[R], \f[B]boldface\f[R], etc., and
+it supplies extensive cross\-index information that it gathers
+automatically.
+.PP
+CWEB allows you to prepare a single document containing all the
+information that is needed both to produce a compilable C program and to
+produce a well\-formatted document describing the program in as much
+detail as the writer may desire.
+The user of CWEB ought to be familiar with TeX as well as C.
+.PP
+The command line should have one, two, or three names on it.
+The first is taken as the CWEB input file (and \f[B].w\f[R] is added if
+there is no extension).
+If there is a second name, it is a change file (and \f[B].ch\f[R] is
+added if there is no extension).
+The change file overrides parts of the CWEB file, as described in the
+documentation.
+If there is a third name, it overrides the default name of the output
+file, which is ordinarily the same as the name of the input file (but on
+the current directory) with the extension \f[B].tex\f[R].
+If you just want to change the output file name, but don\[cq]t have a
+change file to apply, you can use `\f[B]\-\f[R]' as the second argument.
+.PP
+\f[B]ctwill\f[R] is exactly like \f[B]cweave\f[R] except that it
+produces much better documentation, for which you must work harder.
+You should run \f[B]ctwill\f[R] twice, once to prime the pump and once
+to get decent answers.
+Moreover, you must run the output twice through TeX.
+.PP
+After \f[B]tex foo\f[R] you will have output that looks like final pages
+except that the entries of mini\-indexes won\[cq]t be alphabetized.
+The first run produces a weird file called \f[B]foo.ref\f[R].
+Say \f[B]ctwill-refsort < foo.ref > foo.sref\f[R] and then another \f[B]tex
+foo\f[R] will produce alphabetized output.
+.PP
+The \f[B]ctwill-twinx\f[R] program compiles a master index for a set of related
+programs that have been processed by \f[B]ctwill\f[R].
+The individual programs should define their names with a line of the
+form \f[B]\[rs]def\[rs]title{NAME}\f[R].
+.PP
+The mini\-indexes list identifiers that are used but not defined on each
+two\-page spread.
+At the end of each section, \f[B]ctwill\f[R] gives TeX a list of
+identifiers used in that section and information about where they are
+defined.
+.PP
+The current meaning of every identifier is initially
+\f[B]\[rs]uninitialized\f[R].
+Then \f[B]ctwill\f[R] reads the \f[B].aux\f[R] file for your job, if
+any.
+.PP
+Before reading the \f[B].aux\f[R] file, \f[B]ctwill\f[R] actually looks
+for a file called \f[B]system.bux\f[R], which will be read if present.
+And after \f[B]foo.aux\f[R], a third possibility is \f[B]foo.bux\f[R].
+The general convention is to put definitions of system procedures such
+as \f[I]printf\f[R] into \f[B]system.bux\f[R], and to put definitions
+found in specifically foo\-ish header files into \f[B]foo.bux\f[R].
+Like the \f[B].aux\f[R] files, \f[B].bux\f[R] files should contain only
+\f[B]\[at]$\f[R] specifications.
+.PP
+The meaning specified by \f[B]\[at]$\&...\[at]>\f[R] generally has four
+components: an identifier (followed by space), a program name (enclosed
+in braces), a section number (followed by space), and a TeX part.
+.PP
+A special \f[I]proofmode\f[R] is provided so that you can check
+\f[B]ctwill\f[R]\[cq]s conclusions about cross\-references.
+Run \f[B]ctwill\f[R] with the flag \f[B]+P\f[R], and TeX will produce a
+specially formatted document (\f[I]without\f[R] mini\-indexes) in which
+you can check that your specifications are correct.
+.PP
+More details how to use \f[B]ctwill\f[R] can be found in the first
+sections of its source code, respectively the change file
+\f[B]cweav\-twill.ch\f[R] applicable to the \f[B]cweave.w\f[R] source.
+.SH OPTIONS
+.PP
+Options on the command line may be either turned off with `\f[B]\-\f[R]'
+(if they are on by default) or turned on with `\f[B]+\f[R]' (if they are
+off by default).
+In fact, the options are processed from left to right, so a sequence
+like \f[B]\[en]verbose \-h\f[R] will only show the \f[B]banner line\f[R]
+(\f[B]+b\f[R]) and the \f[B]progress report\f[R] (\f[B]+p\f[R]), but
+leave out the \f[B]happy message\f[R] (\f[B]\-h\f[R]).
+.IP \[bu] 2
+\f[B]+b\f[R]: print banner line on terminal
+.IP \[bu] 2
+\f[B]+h\f[R]: print success message on completion
+.IP \[bu] 2
+\f[B]+p\f[R]: print progress report messages
+.IP \[bu] 2
+\f[B]+q\f[R]/\f[B]\-q\f[R]: shortcut for \f[B]\-bhp\f[R]; also
+\f[B]\[en]quiet\f[R] (default)
+.IP \[bu] 2
+\f[B]+v\f[R]/\f[B]\-v\f[R]: shortcut for \f[B]+bhp\f[R]; also
+\f[B]\[en]verbose\f[R]
+.IP \[bu] 2
+\f[B]\-e\f[R]: do not enclose C material in \f[B]\f[R]
+.IP \[bu] 2
+\f[B]\-f\f[R]: do not force a newline after every C statement in output
+.IP \[bu] 2
+\f[B]\-i\f[R]: suppress indentation of parameter declarations
+.IP \[bu] 2
+\f[B]\-o\f[R]: suppress separation of declarations and statements
+.IP \[bu] 2
+\f[B]\-x\f[R]: omit indices, section names, table of contents
+.IP \[bu] 2
+\f[B]+P\f[R]: \f[B]\[rs]input ctproofmac.tex\f[R] instead of
+\f[B]ctwimac.tex\f[R]
+.IP \[bu] 2
+\f[B]+lX\f[R]/\f[B]\-lX\f[R]: use macros for language \f[I]X\f[R] as of
+\f[I]X\f[R]{\f[B]ctwimac\f[R]|\f[B]ctproofmac\f[R]}\f[B].tex\f[R]
+.IP \[bu] 2
+\f[B]+s\f[R]: print usage statistics
+.IP \[bu] 2
+\f[B]\[en]help\f[R]: display help message and exit
+.IP \[bu] 2
+\f[B]\[en]version\f[R]: output version information and exit
+.SH ENVIRONMENT
+.PP
+The environment variable CWEBINPUTS is used to search for the input
+files, or the system default if CWEBINPUTS is not set.
+See tex(1) for the details of the searching.
+.SH FILES
+.PP
+The location of the files mentioned below varies from system to system.
+Use the \f[B]kpsewhich\f[R] utility to find their locations.
+.IP \[bu] 2
+\f[B]ctwimac.tex\f[R]: The default TeX macros \f[B]\[rs]input\f[R] in
+the first line of the output file.
+.IP \[bu] 2
+\f[B]ctproofmac.tex\f[R]: If \f[B]ctwill\f[R] is invoked with the
+\f[B]+P\f[R] option, it will change the first line of the output file to
+\f[B]\[rs]input ctproofmac.tex\f[R].
+.PP
+In both cases you can request some prefix \f[I]X\f[R] with the
+\f[B]+lX\f[R] option, e.g., \f[B]+ld\f[R] will \f[B]\[rs]input
+dctwimac.tex\f[R] and \f[B]+Pld\f[R] will \f[B]\[rs]input
+dctproofmac.tex\f[R].
+.IP \[bu] 2
+\f[I]webfile\f[R]\f[B].bux\f[R]: Reference definitions to resolve from
+other modules.
+.IP \[bu] 2
+\f[B]system.bux\f[R]: Reference definitions to resolve from C standard
+library header files like \f[B]<stdio.h>\f[R].
+.PP
+Other \f[B]aux\f[R]iliary files with references are created
+automatically by \f[B]ctwill\f[R] and the actual index files are created
+by TeX.
+.IP \[bu] 2
+\f[B]cwebman.tex\f[R]: The CWEB user manual.
+.SH SEE ALSO
+.IP \[bu] 2
+The CWEB System of Structured Documentation: by Donald E.\ Knuth and
+Silvio Levy (hardcopy version of \f[B]cwebman.tex\f[R] and the source
+code listings of \f[B]common.w\f[R], \f[B]ctangle.w\f[R], and
+\f[B]cweave.w\f[R]).
+.IP \[bu] 2
+Literate Programming: by D.\ E.\ Knuth.
+.IP \[bu] 2
+Weaving a Program: by Wayne Sewell.
+.PP
+cweb(1), tex(1), cc(1)
+.PP
+As of 2019, \f[B]ctwill\f[R] and its utilities \f[B]ctwill-refsort\f[R] and
+\f[B]ctwill-twinx\f[R] have been fully integrated with the extended CWEBbin
+system that serves as the basis for CWEB in TeX Live; see the project
+page (https://github.com/ascherer/cwebbin).
+.SH AUTHORS
+Don Knuth wrote \f[B]ctwill\f[R] based on \f[B]cweave\f[R] by Silvio
+Levy and Knuth.
diff --git a/source/texk/web2c/man/cweb.man b/source/texk/web2c/man/cweb.man
index 82a134a8dd221d80be4f7af9eb3c5fdb4541d886..6f00a0ed9ebe1ddbcd5c05f09e266d775ea6ff22 100644
--- a/source/texk/web2c/man/cweb.man
+++ b/source/texk/web2c/man/cweb.man
@@ -1,24 +1,22 @@
-.TH CWEB 1 "28 October 2018" "Web2C @VERSION@"
+.TH CWEB 1 "10 January 2018" "Web2C @VERSION@"
 .\"=====================================================================
 .SH NAME
 ctangle, cweave \- translate CWEB to C and/or TeX
 .\"=====================================================================
 .SH SYNOPSIS
-.na
 .B ctangle
-.RB [ \-bhp ]
-.RB [ +s ]
+.RB [ +bhps ]
 .IR webfile [ \fB.w\fP ]
 .RI [{ changefile [ \fB.ch\fP ]| \fB\-\fP }
 .RI [ outfile [ \fB.c\fP ]]]
 .br
 .B cweave
-.RB [ \-befhpx ]
-.RB [ +s ]
+.RB [ +bhps ]
+.RB [ \-efiox ]
+.RB [ \-lX | +lX ]
 .IR webfile [ \fB.w\fP ]
 .RI [{ changefile [ \fB.ch\fP ]| \fB\-\fP }
 .RI [ outfile [ \fB.tex\fP ]]]
-.ad
 .\"=====================================================================
 .SH DESCRIPTION
 The
@@ -66,46 +64,55 @@ extension
 or
 .BR .tex .
 .PP
-Options in the command line may be either turned off with\ \-
-(if they are on by default) or turned on with\ + (if they are off by
+Options in the command line may be either turned off with\ '\-'
+(if they are on by default) or turned on with\ '+' (if they are off by
 default).
 In fact, the options are processed from left to right,
-so a sequence like -f\ +f corresponds to +f (which is the default).
+so a sequence like '-f\ +f' corresponds to '+f' (which is the default).
+.PP
+Both programs operate silently by default (as of 2019).
 .PP
 The
-.B \-b
-option suppresses the banner line that normally appears on your terminal
+.B +b
+option prints the banner line on your terminal
 when ctangle or cweave begins.
 The
-.B \-h
-option suppresses the happy message that normally appears if the processing
+.B +h
+option prints the happy message if the processing
 was successful.
 The
-.B \-p
-option suppresses progress reports (starred module numbers) as the processing
+.B +p
+option prints progress reports (starred module numbers) as the processing
 takes place.
-If you say
-.BR \-bhp ,
-you get nothing but error messages.
 .PP
 The
 .B +s
 option prints statistics about memory usage at the end of a run.
 .PP
-There are three other options applicable to
+There are six other options applicable to
 .B cweave
 only:
-.B \-f
-means do not force a newline after every statement in the formatted output.
 .B \-e
 inhibits the enclosure of C\ material formatted by
-.I cweave
-in brackets
-\ePB{.\|.\|.}.
+.B cweave
+in
+\ePB{.\|.\|.}
+brackets.
 Such brackets are normally inserted so that special hooks
 can be used by
 .I cweb-latex
 and similar programs.
+By default,
+\ePB{.\|.\|.}.
+is defined as a no-op.
+.B \-f
+means do not force a newline after every statement in the formatted output.
+.B \-i
+suppresses the indentation of parameter declarations.
+.B \-lX
+(or +lX) uses macros for language X\ from Xcwebmac.tex.
+.B \-o
+suppresses the visual separation of declarations and statements.
 .B \-x
 means omit the index and table of contents.
 .\"=====================================================================
@@ -144,8 +151,12 @@ and the source code listings).
 .\"=====================================================================
 .SH AUTHORS
 Don Knuth wrote WEB for TeX and Pascal.
+.br
 Silvio Levy designed and developed CWEB
 by adapting the WEB conventions to\ C and by recoding everything in CWEB.
 Knuth began using CWEB and made further refinements.
 Many other helpers are acknowledged in the CWEB manual.
-
+.br
+As of 2019, the CWEB system in TeX Live is based on the CWEBbin extension
+that collects ideas and improvements from numerous contributors;
+see https://github.com/ascherer/cwebbin.
diff --git a/source/texk/web2c/pdftexdir/pdftex_version.h b/source/texk/web2c/pdftexdir/pdftex_version.h
index de2a0661ce0c849d45450a35b5f3e03f699de9af..3ceb2c603d4c28bc23056ab8c4bef16e5fa580e4 100644
--- a/source/texk/web2c/pdftexdir/pdftex_version.h
+++ b/source/texk/web2c/pdftexdir/pdftex_version.h
@@ -1 +1 @@
-#define PDFTEX_VERSION "1.40.19"
+#define PDFTEX_VERSION "1.40.20"
diff --git a/source/utils/README b/source/utils/README
index 05b728e538b67eb9b860a44ce0668a3ba7118088..c9ed16833f49dc00e85fa175f2061ea625dbc882 100644
--- a/source/utils/README
+++ b/source/utils/README
@@ -1,15 +1,15 @@
-$Id: README 48727 2018-09-21 22:18:21Z karl $
+$Id: README 49658 2019-01-10 18:49:48Z karl $
 Public domain.  Originally written 2005 by Karl Berry.
 
 Extra utilities we (optionally) compile for TeX Live.
 See comments in ../texk/README.
 
-asymptote 2.44 - checked 8apr18
+asymptote 2.47 - checked 10jan19
   update to TL from CTAN, to include prebuilt doc.
   see http://tug.org/texlive/build.html#asymptote
   and tlpkg/bin/tl-update-asy
 
-autosp 2018-02-23 - checked 23feb18
+autosp 2019-01-08 - checked 10Jan19
   http://ctan.org/pkg/autosp
 
 devnag - from devanagari package installed in texmf-dist.