Project import generated by Copybara.
GitOrigin-RevId: 03d7d72d983d47c17f7de95bbeae89fe33e41943
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..5f1611c
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,89 @@
+---
+Language: Cpp
+# BasedOnStyle: Google
+AccessModifierOffset: -1
+AlignAfterOpenBracket: DontAlign
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: true
+AlignOperands: false
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: true
+AllowShortLoopsOnASingleLine: true
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: TopLevel
+AlwaysBreakBeforeMultilineStrings: true
+AlwaysBreakTemplateDeclarations: true
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterClass: false
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: false
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ BeforeCatch: false
+ BeforeElse: false
+ IndentBraces: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+ColumnLimit: 90
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 8
+Cpp11BracedListStyle: false
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IncludeCategories:
+ - Regex: '^<.*\.h>'
+ Priority: 1
+ - Regex: '^<.*'
+ Priority: 2
+ - Regex: '.*'
+ Priority: 3
+IndentCaseLabels: false
+IndentWidth: 4
+IndentWrappedFunctionNames: false
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: false
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 200
+PointerAlignment: Right
+ReflowComments: true
+SortIncludes: false
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Auto
+TabWidth: 4
+UseTab: Always
+...
diff --git a/.dir-locals.el b/.dir-locals.el
new file mode 100644
index 0000000..610642c
--- /dev/null
+++ b/.dir-locals.el
@@ -0,0 +1,4 @@
+((makefile-automake-mode
+ (tab-width . 8))
+ (org-mode
+ (fill-column . 70)))
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..1397b26
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,307 @@
+# *~
+# .DS_Store
+
+# for .dockerignore
+.git
+
+# MacOS
+# .DS_Store
+
+# tag files
+# TAGS
+GPATH
+GRTAGS
+GSYMS
+GTAGS
+
+# /
+Makefile
+Makefile.in
+configure
+liblouis.pc
+config.log
+depcomp
+config.guess
+ltmain.sh
+config.sub
+config.status
+libtool
+autom4te.cache
+missing
+aclocal.m4
+install-sh
+INSTALL
+
+# valgrind
+valgrind.log
+
+# Eclipse
+# .cproject
+# .project
+
+# /build-aux/
+build-aux/ar-lib
+build-aux/compile
+build-aux/config.guess
+build-aux/config.rpath
+build-aux/config.sub
+build-aux/depcomp
+build-aux/install-sh
+build-aux/ltmain.sh
+build-aux/mdate-sh
+build-aux/missing
+build-aux/test-driver
+build-aux/texinfo.tex
+
+# /contrib/
+contrib/liblouis.elc
+contrib/braille-input.elc
+
+# /doc/
+doc/Makefile
+doc/Makefile.in
+doc/mdate-sh
+doc/texinfo.tex
+doc/version.texi
+doc/stamp-vti
+doc/liblouis.html
+doc/liblouis.info
+doc/liblouis.txt
+doc/liblouis.pdf
+doc/liblouis.fn
+doc/liblouis.pg
+doc/liblouis.opcode
+doc/liblouis.log
+doc/liblouis.ky
+doc/liblouis.tp
+doc/liblouis.toc
+doc/liblouis.fns
+doc/liblouis.vr
+doc/liblouis.pgs
+doc/liblouis.opcodes
+doc/liblouis.aux
+doc/liblouis.cp
+doc/liblouis.t2p/
+
+# /gnulib/
+gnulib/.libs
+gnulib/.deps
+gnulib/*.o
+gnulib/*.lo
+gnulib/*.la
+gnulib/Makefile
+gnulib/Makefile.in
+gnulib/alloca.h
+gnulib/dirent.h
+gnulib/errno.h
+gnulib/getopt.h
+gnulib/limits.h
+gnulib/stddef.h
+gnulib/stdint.h
+gnulib/stdio.h
+gnulib/stdlib.h
+gnulib/string.h
+gnulib/sys/
+gnulib/unistd.h
+
+# /liblouis/
+liblouis/.libs
+liblouis/.deps
+liblouis/*.o
+liblouis/*.lo
+liblouis/*.la
+liblouis/Makefile
+liblouis/Makefile.in
+liblouis/stamp-h1
+liblouis/config.h.in
+liblouis/config.h
+liblouis/liblouis.h
+
+# /m4/
+m4/Makefile
+m4/Makefile.in
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
+
+# /man/
+man/Makefile
+man/Makefile.in
+man/lou_allround.1
+man/lou_checkhyphens.1
+man/lou_checktable.1
+man/lou_debug.1
+man/lou_trace.1
+man/lou_translate.1
+man/lou_checkyaml.1
+
+# /python/
+python/Makefile
+python/Makefile.in
+python/build
+python/setup.py
+
+# /python/louis/
+python/louis/Makefile
+python/louis/Makefile.in
+python/louis/__init__.py
+python/louis/*.pyc
+
+# /tables
+tables/Makefile
+tables/Makefile.in
+
+# /tests/
+tests/.libs
+tests/.deps
+tests/*.o
+tests/*.exe
+tests/*.log
+tests/*.trs
+tests/Makefile
+tests/Makefile.in
+tests/backtranslate
+tests/backtranslate_noUndefinedDots
+tests/backtranslate_partialTrans
+tests/backtranslate_with_letsign
+tests/capitalization
+tests/capitalized_with_sentance
+tests/capitalized_word
+tests/checkTable
+tests/check_metadata
+tests/compbrlAtCursor
+tests/emphclass
+tests/en_gb_g1_italics
+tests/findTable
+tests/getTable
+tests/hash_collision
+tests/hyphenate
+tests/hyphenate_achena
+tests/hyphenate_alderen
+tests/hyphenate_straightforward
+tests/hyphenate_xxx
+tests/infiniteTranslationLoop
+tests/inpos
+tests/inpos_compbrl
+tests/inpos_match_replace
+tests/lastworditalafter
+tests/letterDefTest
+tests/logging
+tests/outpos
+tests/pass0_typebuf
+tests/pass1Only
+tests/pass2
+tests/pass2_inpos
+tests/present_progressive
+tests/resolve_table
+tests/resolve_table.h
+tests/squash_space
+tests/typeform
+tests/typeform_for_emphclass
+tests/uplow_with_unicode
+tests/yaml/*.log
+tests/yaml/*.trs
+
+# /tests/yaml/
+tests/yaml/Makefile
+tests/yaml/Makefile.in
+tests/yaml/*.log
+tests/yaml/*.trs
+
+# /tests/tables/
+tests/tables/Makefile.in
+tests/tables/Makefile
+tests/tables/emphclass/Makefile
+tests/tables/emphclass/Makefile.in
+tests/tables/moreTables/Makefile.in
+tests/tables/moreTables/Makefile
+tests/tables/resolve_table/Makefile
+tests/tables/resolve_table/Makefile.in
+tests/tables/resolve_table/dir_1/Makefile
+tests/tables/resolve_table/dir_1/Makefile.in
+tests/tables/resolve_table/dir_2/Makefile
+tests/tables/resolve_table/dir_2/Makefile.in
+tests/tables/resolve_table/dir_1/dir_1.1/Makefile
+tests/tables/resolve_table/dir_1/dir_1.1/Makefile.in
+tests/tablesWithMetadata/Makefile
+tests/tablesWithMetadata/Makefile.in
+
+# /tests/ueb_test_data/
+tests/ueb_test_data/Makefile
+tests/ueb_test_data/Makefile.in
+
+# /tools/
+tools/.libs
+tools/.deps
+tools/*.o
+tools/*.la
+tools/*.lo
+tools/Makefile
+tools/Makefile.in
+tools/lou_allround
+tools/lou_checkhyphens
+tools/lou_checktable
+tools/lou_checkyaml
+tools/lou_debug
+tools/lou_trace
+tools/lou_translate
+tools/lou_compare
+tools/*.exe
+
+# /tools/gnulib
+tools/gnulib/.libs
+tools/gnulib/.deps
+tools/gnulib/*.o
+tools/gnulib/*.lo
+tools/gnulib/*.la
+tools/gnulib/Makefile
+tools/gnulib/Makefile.in
+tools/gnulib/errno.h
+tools/gnulib/getopt-cdefs.h
+tools/gnulib/getopt.h
+tools/gnulib/limits.h
+tools/gnulib/stddef.h
+tools/gnulib/stdint.h
+tools/gnulib/stdio.h
+tools/gnulib/stdlib.h
+tools/gnulib/string.h
+tools/gnulib/sys/
+tools/gnulib/unistd.h
+tools/gnulib/unistr.h
+tools/gnulib/unistr/.dirstamp
+tools/gnulib/unitypes.h
+
+# /tools/gnulib/unistr/
+tools/gnulib/unistr/.libs
+tools/gnulib/unistr/.deps
+tools/gnulib/unistr/*.o
+tools/gnulib/unistr/*.la
+tools/gnulib/unistr/*.lo
+
+# stuff used with /tools/lou_compare
+# input.txt
+# pass.txt
+# fail.txt
+# output.txt
+
+# /windows/
+windows/*.obj
+windows/liblouis.dll
+windows/liblouis.lib
+windows/liblouis.exp
+windows/Makefile
+windows/Makefile.in
+
+# /windows/include
+windows/include/Makefile
+windows/include/Makefile.in
+
+# /windows/utils
+windows/utils/Makefile
+windows/utils/Makefile.in
+
+# stuff for local development
+# local/
+# local
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..7f2c4af
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,79 @@
+# define liblouis so that Travis CI service can build and test it
+
+# require Trusty so we have a modern version of texinfo (> 5.0) and
+# automake (> 1.14)
+sudo: required
+dist: xenial
+
+language: c
+
+services:
+ - docker
+
+env:
+ global:
+ # COVERITY_SCAN_TOKEN
+ - secure: "k2AM90pXF/IqX8CRSUPD3dkMktu9IUtFafDVvA1iC4p7hMfwOM4UIC/0E5Dqxwv4ULc7yqbWVchZwHMqteEqcJX8xbxsGqt4s1LtNosV2xjikbGmXVl3cp0qqv3exVcUaxtzxDs2Ee379sTUpVDK314M9oH5ky4N2L+971c1v84="
+ # GITHUB_TOKEN
+ - secure: "FbDvOO7Nqih9z0S+9RL/cvz/VTM5nlEUgJdUT7MefFjIAh+YCfv5sw6FkQpaiOx4xkd63tLrUvjJXi7fy4oERLDO2Qk4OOsntJUfNZqWlsGHZWUTfvgYkcNyNhXe2P4lKnnFaZbqui9Ec9OdnsR1DmrtIoq24BKTxYXCsxdux04="
+
+matrix:
+ include:
+ - compiler: gcc
+ env: MODE=build-gcc
+ - compiler: gcc
+ env: MODE=build-gcc ENABLE_UCS4=--enable-ucs4
+ - compiler: i686-w64-mingw32-gcc
+ env: MODE=build-mingw ENABLE_UCS4=--enable-ucs4 ARCH=32
+ - compiler: x86_64-w64-mingw32-gcc
+ env: MODE=build-mingw ENABLE_UCS4=--enable-ucs4 ARCH=64
+ - compiler: gcc
+ env: MODE=build-js
+ - env: MODE=check-format
+
+before_install:
+ - sudo apt-get update -qq
+ - 'chmod +x ./.travis/before_install/*.sh'
+ - 'chmod +x ./.travis/script/*.sh'
+ - 'chmod +x ./.travis/after_success/*.sh'
+ - case "$MODE" in
+ build-mingw) source .travis/before_install/mingw.sh ;;
+ build-js) source .travis/before_install/emscripten.sh ;;
+ build-gcc) source .travis/before_install/gcc.sh ;;
+ check-format) sudo apt-get install -y clang-format-3.9 ;;
+ esac
+ - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
+
+script:
+ - cd $TRAVIS_BUILD_DIR
+ - case "$MODE" in
+ build-mingw) source .travis/script/mingw.sh ;;
+ build-js) source .travis/script/emscripten.sh ;;
+ build-gcc) source .travis/script/gcc.sh ;;
+ check-format) source .travis/script/check-format.sh ;;
+ esac
+
+after_failure:
+ - case "$MODE" in
+ build-mingw|build-gcc) cat tests/test-suite.log ;;
+ esac
+
+after_success:
+ - case "$MODE" in
+ build-mingw) source .travis/after_success/mingw.sh ;;
+ build-js) source .travis/after_success/emscripten.sh ;;
+ esac
+
+# tell the irc channel about the results of the build
+notifications:
+ irc: "irc.oftc.net#liblouis"
+
+addons:
+ coverity_scan:
+ project:
+ name: "liblouis/liblouis"
+ description: "Build submitted via Travis CI"
+ notification_email: liblouis-liblouisxml@freelists.org
+ build_command_prepend: "./autogen.sh && ./configure && make clean"
+ build_command: "make"
+ branch_pattern: coverity_scan
diff --git a/.travis/after_success/emscripten.sh b/.travis/after_success/emscripten.sh
new file mode 100644
index 0000000..7b84fb8
--- /dev/null
+++ b/.travis/after_success/emscripten.sh
@@ -0,0 +1,54 @@
+if [ "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_BRANCH" != "master" ]; then
+ echo "[liblouis-js] Not publishing. Is pull request or non-master branch."
+ exit 0
+fi
+
+if [ -z "$BUILD_VERSION" ]; then
+ echo "[liblouis-js] no build version specified. Not publishing."
+ exit 0
+fi
+
+echo "[liblouis-js] publishing builds to development channel..."
+
+git config user.name "Travis CI" &&
+git config user.email "liblouis@users.noreply.github.com" &&
+
+# --- decrypt and enable ssh key that allows us to push to the
+# liblouis/js-build repository.
+
+openssl aes-256-cbc -K $encrypted_cf3facfb36cf_key -iv $encrypted_cf3facfb36cf_iv -in ./.travis/secrets/deploy_key.enc -out deploy_key -d &&
+chmod 600 deploy_key &&
+eval `ssh-agent -s` &&
+ssh-add deploy_key &&
+
+# --- push commit and tag to repository. (This will also automatically
+# publish the package in the bower registry as the bower registry
+# just fetches tags and builds from the dev channel.)
+
+cd ../js-build &&
+git add --all &&
+
+if [ -z `git diff --cached --exit-code` ]; then
+ echo "[liblouis-js] Build is identical to previous build. Omitting commit, only adding tag."
+else
+ git commit -m "Automatic build of version ${BUILD_VERSION}" &&
+ git push git@github.com:liblouis/js-build.git master
+
+ if [ $? != 0 ]; then
+ echo "[liblouis-js] Failed to commit. Aborting."
+ exit 1
+ fi
+fi
+
+git tag -a ${BUILD_VERSION} -m "automatic build for version ${BUILD_VERSION}" &&
+git push git@github.com:liblouis/js-build.git $BUILD_VERSION
+
+echo "[liblouis-js] publishing builds to release channel..."
+
+if [ "$IS_OFFICIAL_RELEASE" != true ]; then
+ echo "[liblouis-js] Is not an official release. Not publishing to package managers."
+ exit 0
+fi
+
+# --- push in npm registry
+# TODO
diff --git a/.travis/after_success/mingw.sh b/.travis/after_success/mingw.sh
new file mode 100644
index 0000000..12598f0
--- /dev/null
+++ b/.travis/after_success/mingw.sh
@@ -0,0 +1,79 @@
+if [ "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_BRANCH" != "master" ]; then
+ echo "[mingw] Not publishing. Is pull request or non-master branch."
+ exit 0
+fi
+
+echo "[mingw] Zipping up build..."
+
+INSTALL_DIR=win$ARCH-install
+COMMIT=$( git rev-parse --short=7 HEAD )
+ZIP=liblouis-win$ARCH-$COMMIT.zip
+
+make install && \
+cd $INSTALL_DIR && \
+zip -r $ZIP * && \
+cd .. && \
+mv $INSTALL_DIR/$ZIP .
+
+if [ $? != 0 ]; then
+ echo "[mingw] Failed to zip up build"
+ exit 1
+fi
+
+RELEASE_ID=8031256
+GITHUB_USER="bertfrees"
+
+echo "[mingw] First deleting previous build"
+
+# Using "curl -u" because authenticated requests get a higher rate limit
+assets=$(curl -u "$GITHUB_USER:$GITHUB_TOKEN" \
+ "https://api.github.com/repos/liblouis/liblouis/releases/$RELEASE_ID/assets" \
+ 2>/dev/null)
+if echo "$assets" | jq -e '.message' >/dev/null 2>/dev/null; then
+ echo "$assets" | jq -r '.message' >&2
+ exit 1
+else
+ assets=$(echo "$assets" | jq -r '.[] | select(.name | match("^liblouis-win'$ARCH'-.+\\.zip$")) | .url') || exit 1
+ echo "$assets" \
+ | while read u; do
+ if ! message=$(curl -u "$GITHUB_USER:$GITHUB_TOKEN" -X DELETE "$u" 2>/dev/null); then
+ echo "[mingw] Failed to delete asset $u"
+ exit 1
+ elif [ -n "$message" ]; then
+ echo "$message" | jq -r '.message' >&2
+ echo "[mingw] Failed to delete asset $u"
+ exit 1
+ fi
+ done
+fi
+
+echo "[mingw] Uploading builds to Github release..."
+
+if ! curl -u "$GITHUB_USER:$GITHUB_TOKEN" \
+ -H "Content-type: application/zip" \
+ -X POST \
+ "https://uploads.github.com/repos/liblouis/liblouis/releases/$RELEASE_ID/assets?name=$ZIP" \
+ --data-binary @$ZIP \
+ 2>/dev/null \
+ | jq -e '.url'
+then
+ echo "[mingw] Failed to upload asset"
+ exit 1
+fi
+
+echo "[mingw] Editing release description..."
+
+DESCRIPTION="Latest build: $COMMIT"
+if ! curl -u "$GITHUB_USER:$GITHUB_TOKEN" \
+ -H "Accept: application/json" \
+ -H "Content-type: application/json" \
+ -X PATCH \
+ "https://api.github.com/repos/liblouis/liblouis/releases/$RELEASE_ID" \
+ -d "{\"tag_name\": \"snapshot\", \
+ \"body\": \"$DESCRIPTION\"}" \
+ 2>/dev/null \
+ | jq -e '.url'
+then
+ echo "[mingw] Failed to edit release description"
+ exit 1
+fi
diff --git a/.travis/before_install/emscripten.sh b/.travis/before_install/emscripten.sh
new file mode 100644
index 0000000..571d74b
--- /dev/null
+++ b/.travis/before_install/emscripten.sh
@@ -0,0 +1,42 @@
+if [ -z "$TRAVIS_COMMIT" ]; then
+ echo "[liblouis-js] not building in travis. Aborting..."
+ exit 1
+fi
+
+export COMMIT_SHORT=$(echo $TRAVIS_COMMIT | cut -c1-6)
+
+echo $TRAVIS_TAG | grep "^v[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$"
+
+if [ $? -eq 1 ]; then
+ echo "[liblouis-js] tag is not valid version string."
+ export BUILD_VERSION="commit-${COMMIT_SHORT}"
+ export IS_OFFICIAL_RELEASE=false
+else
+ # NOTE: tags cannot be revoked. Only automatically publish as release
+ # candidate. A contributer should confirm the correctness of the build
+ # and rerelease unaltered binaries without the -rc suffix.
+ export BUILD_VERSION="${TRAVIS_TAG}-rc.1"
+ export IS_OFFICIAL_RELEASE=true
+fi
+
+echo "[liblouis-js] Assigned this build the version number ${BUILD_VERSION}" &&
+
+# --- obtain liblouis-js. Contains tests and js snippets appended to builds.
+# liblouis-js version should be incremented by hand, to keep the repositories
+# in sync.
+git clone https://github.com/liblouis/liblouis-js.git &&
+cd liblouis-js &&
+git checkout 8a28e9380c591c58e4b411bb366c76cf686ac418 &&
+cd .. &&
+# --- obtain the latest version of liblouis/js-build
+# we publish/deploy to this repository. Contains package
+# descriptions (package.json and bower.json) and documentation
+# that must/should be part of packages in package managers.
+
+# Note: we clone this repository to a location outside of the liblouis/liblouis
+# git repository to avoid issues caused by nested git repositorys
+git clone --depth 1 https://github.com/liblouis/js-build.git ../js-build &&
+
+echo "[liblouis-js] obtaining docker image of build tools..." &&
+docker pull dolp/liblouis-js-build-travis:1.37.3-64bit
+
diff --git a/.travis/before_install/gcc.sh b/.travis/before_install/gcc.sh
new file mode 100644
index 0000000..825ffca
--- /dev/null
+++ b/.travis/before_install/gcc.sh
@@ -0,0 +1 @@
+sudo apt-get install -y libyaml-dev
diff --git a/.travis/before_install/mingw.sh b/.travis/before_install/mingw.sh
new file mode 100644
index 0000000..190bc83
--- /dev/null
+++ b/.travis/before_install/mingw.sh
@@ -0,0 +1,9 @@
+sudo apt-get install -y $(test $ARCH == 32 && echo libc6-dev-i386 || echo mingw-w64) jq texinfo
+mkdir -p $HOME/src &&
+cd $_ &&
+curl -L https://github.com/yaml/libyaml/archive/0.2.2.tar.gz | tar zx &&
+cd libyaml-0.2.2 &&
+./bootstrap &&
+./configure --host $(test $ARCH == 32 && echo i686-w64-mingw32 || echo x86_64-w64-mingw32) --prefix=$HOME/build/win$ARCH/libyaml &&
+make &&
+make install
diff --git a/.travis/script/check-format.sh b/.travis/script/check-format.sh
new file mode 100755
index 0000000..de87454
--- /dev/null
+++ b/.travis/script/check-format.sh
@@ -0,0 +1,5 @@
+# apply clang-format and check for uncommitted changes
+./autogen.sh && \
+./configure && \
+make format-sources && \
+git diff-index --exit-code HEAD -- . ':!.travis'
diff --git a/.travis/script/emscripten-build-command.sh b/.travis/script/emscripten-build-command.sh
new file mode 100644
index 0000000..74e0d9c
--- /dev/null
+++ b/.travis/script/emscripten-build-command.sh
@@ -0,0 +1,23 @@
+function buildjs {
+
+ if [ $1 != "32" -a $1 != "16" ]; then
+ echo "argument 1 must either be 32 for UTF32 builts or 16 for UTF16 builds"
+ exit 1
+ fi
+
+ if [ -z $2 ]; then
+ echo "argument 2 must be a valid filename"
+ exit 1
+ fi
+
+ set -x
+
+ emcc ./liblouis/.libs/liblouis.a -s RESERVED_FUNCTION_POINTERS=1 -s MODULARIZE=1\
+ -s EXPORT_NAME="'liblouisBuild'" -s EXTRA_EXPORTED_RUNTIME_METHODS="['FS',\
+ 'Runtime', 'stringToUTF${1}', 'Pointer_Stringify']" --pre-js ./liblouis-js/inc/pre.js\
+ --post-js ./liblouis-js/inc/post.js ${3} -o ./out/${2} &&
+
+ cat ./liblouis-js/inc/append.js >> ./out/${2}
+
+ set +x
+}
diff --git a/.travis/script/emscripten-build.sh b/.travis/script/emscripten-build.sh
new file mode 100644
index 0000000..8a5771f
--- /dev/null
+++ b/.travis/script/emscripten-build.sh
@@ -0,0 +1,27 @@
+source ./.travis/script/emscripten-build-command.sh &&
+mkdir out &&
+
+echo "[liblouis-js] starting build process in docker image..." &&
+
+./autogen.sh &&
+
+echo "[liblouis-js] configuring and making UTF-16 builds..." &&
+emconfigure ./configure --disable-shared &&
+emmake make &&
+# install to obtain a table folder which does not contain build scripts
+emmake make install prefix="$(pwd)/out-emscripten-install"
+
+buildjs "16" "build-no-tables-utf16.js" &&
+#buildjs "16" "build-no-tables-wasm-utf16.js" "-s WASM=1" &&
+#buildjs "16" "build-tables-embeded-root-utf16.js" "--embed-files ./out-emscripten-install/share/liblouis/tables@/" &&
+
+echo "[liblouis-js] configuring and making UTF-32 builds..." &&
+emconfigure ./configure --enable-ucs4 --disable-shared &&
+emmake make &&
+
+echo "[liblouis-js] building UTF-32 with no tables..." &&
+buildjs "32" "build-no-tables-utf32.js" &&
+#buildjs "32" "build-no-tables-wasm-utf32.js" "-s WASM=1" &&
+#buildjs "32" "build-tables-embeded-root-utf32.js" "--embed-files ./out-emscripten-install/share/liblouis/tables@/" &&
+
+echo "[liblouis-js] done building in docker image..."
diff --git a/.travis/script/emscripten.sh b/.travis/script/emscripten.sh
new file mode 100644
index 0000000..2ba1d52
--- /dev/null
+++ b/.travis/script/emscripten.sh
@@ -0,0 +1,52 @@
+# --- build all four currently published builds of liblouis (UTF-16 with
+# tables, UTF-16 wihout tables, UTF-32 with tables and UTF-32 without
+# tables) in a docker image that has all necessary build tools installed.
+rm -f ../js-build/build-*.js
+
+echo "[liblouis-js] starting docker image with emscripten installed..."
+docker run --rm -v $(pwd):/src dolp/liblouis-js-build-travis:1.37.3-64bit /bin/bash -c "./.travis/script/emscripten-build.sh"
+
+if [ $? != 0 ]; then
+ echo "[liblouis-js] Build failed. Aborting..."
+ exit 1
+fi
+
+# --- collect all files that are necessary for a publish in package
+# managers.
+echo "[liblouis-js] bundling files to package for publish..." &&
+rm -rf ../js-build/tables/ &&
+cp -R ./out-emscripten-install/share/liblouis/tables/ ../js-build/tables/ &&
+cp -Rf ./out/* ../js-build/
+
+if [ "$IS_OFFICIAL_RELEASE" = true ]; then
+ cd ../js-build
+ npm version --no-git-tag-version $BUILD_VERSION
+
+ if [ $? != 0 ]; then
+ echo "[liblouis-js] Failed to update npm version tag. Aborting."
+ exit 1
+ fi
+
+ cd -
+fi
+
+ls -lah ../js-build
+
+# --- make sure the package we just build is not damaged.
+echo "[liblouis-js] testing builds..."
+
+# NOTE: `npm link` exposes the newly build npm package to the
+# test runner. The `--production`-flag is necessary as it ensures
+# that no publicly published package of the build is downloaded
+# and tested instead.
+cd liblouis-js &&
+npm link ../../js-build --production &&
+# NOTE: we only test the build in NodeJS as the browser test environment
+# segfaults sometimes for successful builds.
+npm run test-node &&
+cd ..
+
+if [ $? != 0 ]; then
+ echo "[liblouis-js] Not publishing as at least one build failed tests."
+ exit 1
+fi
diff --git a/.travis/script/gcc.sh b/.travis/script/gcc.sh
new file mode 100644
index 0000000..57aab1e
--- /dev/null
+++ b/.travis/script/gcc.sh
@@ -0,0 +1,13 @@
+./autogen.sh &&
+./configure $ENABLE_UCS4 --with-yaml &&
+make &&
+make check #&&
+# check display names
+# FIXME: temporarily disabled because this causes a memory corruption error on Travis
+# if [[ -n ${ENABLE_UCS4+x} ]]; then
+# cd extra/generate-display-names &&
+# if ! make; then
+# cat generate.log
+# false
+# fi
+# fi
diff --git a/.travis/script/mingw.sh b/.travis/script/mingw.sh
new file mode 100644
index 0000000..03a57c8
--- /dev/null
+++ b/.travis/script/mingw.sh
@@ -0,0 +1,11 @@
+./autogen.sh &&
+export CPPFLAGS="-I/$HOME/build/win$ARCH/libyaml/include/" &&
+export LDFLAGS="-L/$HOME/build/win$ARCH/libyaml/lib/" &&
+./configure --host $(test $ARCH == 32 && echo i586-mingw32msvc || echo x86_64-w64-mingw32) \
+ $ENABLE_UCS4 --with-yaml --prefix=$(pwd)/win$ARCH-install &&
+make LDFLAGS="$LDFLAGS -avoid-version -Xcompiler -static-libgcc"
+
+# FIXME:
+# make CPPFLAGS='-I/$HOME/build/win32/libyaml/include/' \
+# LDFLAGS='-L/$HOME/build/win32/libyaml/lib/' \
+# distwin32
diff --git a/.travis/secrets/deploy_key.enc b/.travis/secrets/deploy_key.enc
new file mode 100644
index 0000000..f237447
--- /dev/null
+++ b/.travis/secrets/deploy_key.enc
Binary files differ
diff --git a/ANNOUNCEMENT b/ANNOUNCEMENT
new file mode 100644
index 0000000..aaeaf6e
--- /dev/null
+++ b/ANNOUNCEMENT
@@ -0,0 +1,192 @@
+liblouis 3.11.0 has been released
+
+The liblouis developer team is proud to announce the liblouis release
+3.11.0. The release is available for download at:
+
+https://github.com/liblouis/liblouis/releases
+
+Introduction
+============
+
+Liblouis is an open-source braille translator and back-translator. It
+features support for computer, literary and math braille, supports
+contracted and uncontracted translation for many, many languages [1]_.
+It plays an important role in an open source accessibility stack and is
+used by screenreaders such as NVDA, Orca and JAWS. A companion project
+liblouisutdml [2]_ deals with formatting of braille.
+
+Noteworthy changes in this release
+==================================
+
+A tremendous amount of work by Dave Mielke and Bert Frees has gone into
+this release. They have improved liblouis for use on note taker devices,
+for backwards translation and a number of languages. Many other
+contributors (listed below) have also helped in fixing bugs and
+improving braille tables, such as Dutch, Mongolian, Polish, Ancient
+Greek, Danish, Irish, Chinese, and American Braille Computer Code.
+
+For a detailed list of all the changes refer to the list of closed
+issues [3]_.
+
+New features
+------------
+
+- Enable ``always`` rules with a single character and a single braille
+ cell for back-translation. Thanks to Bue Vester-Andersen.
+- Implement ``noUndefined`` mode for forward translation, thanks to
+ Dave Mielke.
+- Use fallback braille representations (NABCC) for rendering undefined
+ characters in hexadecimal notation, thanks to Dave Mielke.
+- Always render undefined characters, also ASCII characters, in
+ hexadecimal notation.
+- Add a new metadata field ``index-name`` for selecting a table from a
+ list fast and efficiently. It has the most important information
+ first and no redundant information. It should look nice when sorted.
+ This in contrast to the existing ``display-name`` field which is for
+ describing a table accurately and should sound good. Thanks to Dave
+ Mielke and Bert Frees.
+
+Bug fixes
+---------
+
+- Don't let a caps passage end on a word with no letters. Thanks to
+ Bert Frees.
+- Handle word resets in the last word of an caps or emphasis passage if
+ the end indicator was placed before the word. Thanks to Bert Frees.
+- Never convert to lowercase if ``capsletter`` is not defined. Thanks
+ to Bert Frees.
+- Fix position mapping for back-translation when ``noUndefined`` mode
+ is active. Thanks to Dave Mielke.
+- Fix bug where a translation would hang on words that match both a
+ ``nocont`` and a ``repeated`` rule. Thanks to Dave Mielke.
+- Fix bug where the effect of ``capsnocont`` would leak to the next
+ word if that word starts with a capital. Thanks to Bue
+ Vester-Andersen.
+
+Braille table improvements
+--------------------------
+
+- Fix an issue with ordinal numbers inside caps passages in Dutch
+ braille. Thanks to Bert Frees.
+- Improved back-translation for Mongolian thanks to Angaragerdene.
+- Fixes to Polish grade 1 and Polish computer braille thanks to Łukasz
+ Golonka.
+- Improvements to Ancient Greek braille, which has been renamed
+ "Greek international braille". A version with composed
+ accents is made available as a .uti table. Thanks to Dave Mielke and
+ Μαρια Γεωργακαράκου (Maria Georgakarakou).
+- Various improvements to modern Greek thanks to Dave Mielke.
+- Improvements and fixes to Spanish contracted braille. Details in
+ #741. Thanks to Juan Pablo Bello.
+- Improvements and fixes to the Danish tables. Thanks to Bue
+ Vester-Andersen.
+- Add a display table to match Word CX which is used in Norway and
+ Sweden, and maybe also in other countries thanks to Lars Bjørndal.
+- Fix handling of colon within number in Dutch braille, thanks to Jake
+ Kyle.
+- Fix translation of bullet and dot operators in Dutch braille, thanks
+ to Paul Rambags
+- Added North American Braille Computer Code table (``en-nabcc.utb``)
+ which is the counterpart of the ``text_nabcc.dis`` display table.
+ Thanks to Dave Mielke.
+- Add support for the International Phonetic Alphabet (IPA) to the
+ Chinese bopomofo braille table, thanks to Hurt Huang and Sponge Jhan.
+ Various improvements, including dot patterns and test cases, to the
+ Chinese bopomofo braille table, thanks to Sponge Jhan.
+- Unified English Braille no longer displays a single underscore when
+ multiple underscores are in the text, thanks to André-Abush Clause.
+- Update to Afrikaans uncontracted braille and new table for contracted
+ braille. Thanks to Christo de Klerk and Greg Kearney.
+- Update Irish braille (contracted and uncontracted) to the May 2019
+ version of the specification, thanks to Ronan McGuirk
+
+Other changes
+-------------
+
+- The python wrapper now encodes and decodes strings to/from UTF-16 and
+ UTF-32 using the surrogatepass error handler. This ensures that
+ single UTF-16 surrogate characters are processed correctly by the
+ wrapper and don't raise an encoding/decoding error. Thanks to Leonard
+ de Ruijter.
+- Metadata keys and values are now case insensitive, thanks to Dave
+ Mielke.
+- Remove ``unicodedefs.cti``. It was obsolete and never meant to be
+ included by any tables. Instead use the online references as
+ mentioned in the documentation now. See also #696.
+- ``lou_checkyaml`` test reporting has been improved, thanks to Bert
+ Frees. For example it now has a ``--verbose`` option so that printing
+ of expected failures can be enabled.
+- Hyphenation tables have been removed from tables except those needed
+ for ``nocross`` rules, thanks to Bert Frees.
+
+ The idea is that the caller (for example ``odt2braille`` or
+ ``liblouisutdml``) should be able to decide for themselves which
+ hyphenation table to use. The case in which a table contains nocross
+ rules is an exception. In this case the hyphenation patterns are a
+ real part of the table. Because it is not recommended to append an
+ own hyphenation table in this case, a ``#-has-nocross`` metadata
+ field was added to indicate that a table contains nocross rules.
+- ``lou_hyphenate`` can now handle more than just words (sequences of
+ letters), e.g compound words, thanks to Bert Frees.
+
+Deprecation notice
+------------------
+
+- The ``noUndefinedDots`` mode has been renamed to ``noUndefined``. For
+ backwards compatibility ``noUndefinedDots`` is still available in the
+ header file and in the Python bindings, as an alias for
+ ``noUndefined``.
+
+Backwards incompatible changes
+------------------------------
+
+None
+
+Invisible changes
+-----------------
+
+- Internally separate more clearly the display and translation phases.
+
+New, renamed or removed tables
+------------------------------
+
+New
+~~~
+
+- grc-international-common.uti
+- grc-international-composed.uti
+- grc-international-decomposed.uti
+- en-nabcc.utb
+
+Renamed
+~~~~~~~
+
+- gr-bb.ctb -> grc-international-en.utb
+
+Removed
+~~~~~~~
+
+- unicodedefs.cti
+- fi-fi.ctb
+
+Next release
+============
+
+The next release will be published on December 2 2019 so please keep up
+the excellent work and keep those improvements coming.
+
+Share and Enjoy!
+
+– Christian Egli, on behalf of the liblouis developers
+
+Footnotes
+=========
+
+.. [1]
+ https://github.com/liblouis/liblouis/tree/master/tables
+
+.. [2]
+ https://github.com/liblouis/liblouisutdml
+
+.. [3]
+ https://github.com/liblouis/liblouis/milestone/21?closed=1
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..302de78
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,219 @@
+MAIN AUTHOR
+
+ John J. Boyer <john.boyer@abilitiessoft.org> from Abilitiessoft, Inc.
+ - is the founder, creator and original author of the liblouis
+ project(s)
+ - has put his heart and soul into liblouis
+ - has written the bulk of the code
+ - maintainer emeritus
+
+CODE CONTRIBUTORS
+
+A team of three developers has taken over maintenance work since John
+Boyer did a step back in 2014:
+
+ Christian Egli <christian.egli@sbs.ch> from SBS <www.sbs.ch>
+ - maintains the build and version control systems and does releases
+ on a regular basis
+ - has done code contributions
+ - is one of the project maintainers
+
+ Mesar Hameed <mesar.hameed@gmail.com>
+ - has done code contributions
+ - has done a lot of table maintenance
+ - was the main developer of the test harness
+ - is one of the project maintainers
+
+ Bert Frees <bertfrees@gmail.com> for DocArch <www.docarch.be> and SBS <www.sbs.ch>
+ - has done code contributions
+ - has done table contributions as well
+ - is one of the project maintainers
+
+Considerable coding was done by:
+
+ Bue Vester-Andersen <bue@vester-andersen.dk>
+ Dave Mielke <dave@mielke.cc>
+ Davy Kager <mail@davykager.nl>
+ Eitan Isaacson <eitan@ascender.com>
+ James Teh <jamie@jantrid.net>
+ Michael Curran <mick@kulgan.net>
+ Michael Whapples <mwhapples@aim.com>
+ Mike Gray <mgray@aph.org>
+ Reiner Dolp <hallo@reinerdolp.com>
+
+Patches were provided by:
+
+ Arend Arends <arend.arends@hccnet.nl>
+ Chris Brannon
+ Jeremy Roman <jbroman@google.com>
+ Ken Perry <kperry@aph.org>
+ Martin Michlmayr <tbm@cyrius.com>
+ Matt Wenn
+ Mike Gorse
+ Milan Zamazal <pdm@brailcom.org>
+ Peter Nilsson Lundblad <plundblad@google.com>
+ Simon Aittamaa, Index Braille <simon.aittamaa@indexbraille.com>
+ Timothy Lee <timothy.ty.lee@gmail.com>
+ Victor Montalvão vicmont@microsoft.com
+ Vincent Untz <vuntz@gnome.org>
+ Volker Bijewitz <v.bijewitz@baum.de>
+
+BRLTTY AUTHORS
+
+Liblouis was derived from the Linux screen reader BRLTTY. Because it
+is rather difficult to trace back exactly which parts of BRLTTY ended
+up in liblouis we just list all BRLTTY contributors here (see also
+brltty.com/contact.html).
+
+The team:
+
+ Dave Mielke <dave@mielke.cc>
+ Nicolas Pitre <nico@fluxnic.net>
+ Stéphane Doyon <s.doyon@videotron.ca>
+
+Other contributors:
+
+ Andreas Gross <andi@andi-bika.de>
+ August Hörandl <hoerandl@elina.htlw1.ac.at>
+ Brailcom o.p.s. <technik@brailcom.cz>
+ Christian Comaschi <christian_comaschi@libero.it>
+ Coscell Kao <coscell@mail.batol.net>
+ James Bowden
+ John Boyer <director@chpi.org>
+ Jos Lemmens <jlemmens@inter.nl.net>
+ Mario Lang <mlang@delysid.org>
+ Nikhil Nair <nn201@cus.cam.ac.uk>
+ Oscar Fernandez <ofa@once.es>
+ Per Lejontand <pele@acc.umu.se>
+ Samuel Thibault <samuel.thibault@labri.fr>
+ Sébastien Hinderer <sebastien.hinderer@libertysurf.fr>
+ Stephane Dalton <sdalton@videotron.ca>
+ Wolfgang Astleitner <wolfgang.astleitner@liwest.at>
+ Yannick Plassiard <Yannick.Plassiard@free.fr>
+
+TABLE AND TEST CONTRIBUTORS
+
+ Aaron Cannon <cannona@fireantproductions.com>
+ Abdolamir Banisaeid <saedjan@gmail.com>
+ Adi Kushnir <adikushnir@gmail.com>
+ Alex Ho
+ Ammar Usama <ammar.usama@nlb.no>
+ André-Abush Clause <dev@andreabc.net>
+ Anthony Tibbs
+ Artis Raugulis
+ Ashoka Bandula Weerawardhana
+ Birkir Gunnarsson <birkir@midstod.is>
+ Brailcom, o.p.s. <technik@brailcom.cz>
+ Branislav Mamojka <mamojka@unss.sk>
+ Bue Vester-Andersen <bue@vester-andersen.dk>
+ Bo-Cheng Jhan <school510587@yahoo.com.tw>
+ Carles Sadurní Anguita <www.transcriptor.net>
+ Carlos Ferreira <cferreira9886@gmail.com>
+ Caterina Avoledo <catery81@yahoo.it>
+ Chennai Shankar <brailleacl@gmail.com> from Braille Section Team, Anna Centenary Library
+ Christian Waldvogel <christian.waldvogel@sbszh.ch> from SBS <www.sbs.ch>
+ Coscell Kao <coscell@molerat.net>
+ Danko Butorac <danko@ipsis.hr>
+ Dave Mielke <dave@mielke.cc>
+ David Hole
+ David Reynolds <dkreynolds@ntlworld.com>
+ Dinakar T.D. <td.dinkar@gmail.com>
+ Dinesh Kaushal<dineshkaushal@hotmail.com>
+ Dipendra Manocha <d@saksham.org>
+ Erez Kugler <erez@gaash.com> from TSR GAASH <www.tsr-gaash.co.il>
+ Eric Yip
+ Frédéric Schwebel
+ Gatis Grintals
+ Greg Kearney <gkearney@gmail.com>
+ Halim Sahin <halim.sahin@web.de>
+ Hammer Attila <hammera@pickup.hu>, <hammer.attila@infoalap.hu> from IT Foundation for the Visually Impaired in Hungary
+ Hans Schou <chlor@schou.dk>
+ Harri Pasanen <harri@mpaja.com>
+ Henri Apperloo <h.apperloo@cbb.nl> from CBB <www.cbb.nl>
+ Him Prasad Gautam
+ Hurt Huang <hurt.nzsmr@gmail.com>
+ Igor B. Poretsky <poretsky@mlbox.ru>
+ Ikrami Ahmad <ikrami.ahmad@gmail.com>
+ International league of Blind Esperantists (LIBE) <libe.narzan.com>
+ Jake Kyle from Compass Braille <jake@compassbraille.org>
+ James Datray from Freedom Scientific
+ James Bowden <james.bowden@rnib.org.uk> from Royal National Institute of Blind People (RNIB)
+ Jan Halousek <merit@login.cz> from MERIT
+ Jan Hegr <hegrjan@gmail.com>
+ Joseph Lee <joseph.lee22590@gmail.com>
+ Jostein Austvik Jacobsen <josteinaj@gmail.com>
+ José Enrique Fernández del Campo <jefdelcampo@gmail.com>
+ Jožef Gregorc <jozko.gregorc@gmail.com>
+ Juan Carlos Buño Suárez <quetzatl@eresmas.net>
+ Juan Pablo Bello <juanpisjaws@gmail.com>
+ Jukka Eerikäinen <jukka.eerikainen@celia.fi> from Celia <www.celia.fi>
+ Jürgen Dengo <jyrgen.dengo@gmail.com>
+ KM Yuen
+ Kaifang Bao baokaifang@gmail.com from RejoinTech
+ Karol Pecyna <HarpoDeveloper@gmail.com> from Harpo <http://int.harpo.com.pl>
+ Keny Yuen
+ Kevin Derome
+ Knut Arne Bjørndal <bob+liblouis@cakebox.net>
+ Lars Bjørndal <lars@handytech.no>, <lars@lamasti.net>
+ Luis Lorente Barajas (ONCE-CIDAT)
+ Leon Ungier <Leon.Ungier@ViewPlus.com> from ViewPlus Technologies, Inc. <www.viewplus.com>
+ Leona Holloway <Leona.Holloway@visionaustralia.org> from Vision Australia
+ Leonard de Ruijter from Babbage B.V. <www.babbage.com>
+ Ludovic Oger <oger.ludovic@gmail.com>
+ Łukasz Golonka <wulfryk1@gmail.com>
+ Mateja Jenčič
+ Michel Such <michel.such@free.fr>
+ Mike Sivill <mike.sivill@viewplustechnologies.com> from ViewPlus Technologies, Inc.
+ Mohammed R. Ramadan <mramadan@nattiq.com>
+ Mohammadreza Rashad <mohammadreza5712@gmail.com>
+ Monk Jeremiah from Visoki Dečani <visokidecani@gmail.com>
+ Neil Soiffer <NeilS@dessci.com>
+ Nicolas Pitre <nico@cam.org>
+ Nicolai Svendsen <chojiro1990@gmail.com>
+ Patrick Zajda
+ Paul Rambags <paulrambags@dedicon.nl>
+ Paul Wood <paulw.torchtrust@gmail.com>
+ Peter Engström <peter.engstrom@indexbraille.com> from Index Braille
+ Peter Vágner <pvdeejay@gmail.com>
+ Rimas Kudelis <rq@akl.lt>
+ Ronan McGuirk <ronan.p.mcguirk@gmail.com>
+ Roshanson <736781877@qq.com>
+ Rui Batista <ruiandrebatista@gmail.com>
+ Rui Fontes <rui.fontes@tiflotecnia.com>
+ Rumiana Kamenska <rkamenska@gmail.com>
+ Samuel Thibault <samuel.thibault@ens-lyon.org>
+ Sébastien Sablé <sable@users.sourceforge.net>
+ Sergiy Moskalets (www.trosti.com.ua)
+ Simone Dal Maso <simone.dalmaso@juvox.it>
+ Sreeja Parameswaran <sreeja.param@gmail.com>
+ Stefan Moisei <vortex37@gmail.com>
+ Sukil Etxenike <sukiletxe@yahoo.es>
+ Sunian Loomee <ghito@qq.com>
+ Tamru E. Belay <tamru@sympatico.ca>, <g.braille@sympatico.ca> from Adaptive Technology Center for the Blind (ATCB)
+ Timothy Wynn
+ Tom Johnston <Tom.Johnston@accessibilityconsulting.co.uk>
+ Tsengel Maidar tsengel@digitalsunngo.org
+ Uğur Gürbüz <ugur.gurbuz@brailleteknik.com>
+ Yuemei Sun from ViewPlus Technologies, Inc.
+ Zlatko Sobočan <zlatko.sobocan@tifloglobus.hr>
+ Zvonimir Stanecic <zvonimirek222@yandex.com>
+ <Aliminator83@gmail.com>
+ <eric@integra-belgium.com>
+
+LIBHNJ AUTHORS
+
+Code was borrowed from the hyphenation library Libhnj.
+
+ Raph Levien <raph@acm.org>
+
+Hyphenation dictionaries were copied from OpenOffice.org.
+
+OTHER CONTRIBUTORS
+
+These are contributions not in the form of code or tables.
+
+ John Gardner <john.gardner@viewplus.com> from ViewPlus Technologies, Inc. <www.viewplus.com>
+
+Unknown contribution:
+
+ Alastair Irving
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/COPYING.LESSER b/COPYING.LESSER
new file mode 100644
index 0000000..4362b49
--- /dev/null
+++ b/COPYING.LESSER
@@ -0,0 +1,502 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..31e92e1
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,1654 @@
+2014-03-21 Lars Bjørndal <lars@lamasti.net>
+
+ * tables/no-no-g0.utb:
+ * tables/hyph_nn_NO.dic:
+ * tables/hyph_nb_NO.dic: Add hyphenation tables from the hyphen-nb
+ and hyphen-nn packages version 2.1.
+
+2014-01-06 Peter Nilsson Lundblad <plundblad@google.com>
+
+ * liblouis/wrappers.c: Two unused variables that I just removed.
+
+ * liblouis/lou_translateString.c: Changed two variables of type
+ typeforms to int since they're used as bitfields.
+ * liblouis/compileTranslationTable.c (parseChars): The loop
+ counter in the utf8 decoding couldn't go below 0, but the compiler
+ couldn't prove that. I think the change from >= to > in the
+ termination condition is correct since the byte has to be >= 0x80
+ in this case so the finial iteration isn't necessary (if it would
+ be, the compiler would be right and we'd actually have an array
+ out of bounds).
+
+2013-07-19 Patrick Zajda <patrick@zajda.fr>
+
+ * tables/fr-bfu-comp8.utb: corrections.
+
+2013-06-21 Christian Egli <christian.egli@sbs.ch>
+
+ * configure.ac: Update release number
+
+2013-06-10 Joseph Lee <joseph.lee22590@gmail.com>
+
+ * tables/en-ueb-g1.ctb:
+ * tables/en-ueb-chardefs.uti: latest additions to Unified English
+ Braille.
+
+2013-06-06 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/Makefile.am (table_files):
+ * liblouis/compileTranslationTable.c (doLang2table):
+ (compileTranslationTable): Remove the lang2table feature. It was
+ never used, undocumented and contains an out-of-bounds access bug.
+ See also
+ http://www.freelists.org/post/liblouis-liblouisxml/PATCH-FW-Outofbounds-access-in-doLang2Table
+
+2013-06-03 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/hash_collision.c:
+ * tests/Makefile.am (XFAIL_TESTS): Mark the hash_collision test as
+ a known failure.
+
+ * liblouis/compileTranslationTable.c (allocateSpaceInTable): When
+ the table needs more space it is reallocated. Unfortunately not
+ all references to the table (such as the tableChain) are updated.
+ This is now fixed.
+
+ * tests/tables/large.ctb:
+ * tests/tables/Makefile.am:
+ * HACKING: Added a new section about profiling and some test table
+ that can be used for profiling.
+
+2013-05-28 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/hash_collision.c:
+ * tests/tables/empty.ctb:
+ * tests/tables/Makefile.am:
+ * tests/Makefile.am: Add a new test to benchmark the hash
+ algorithm.
+
+2013-01-28 Igor B. Poretsky <poretsky@mlbox.ru>
+
+ * tables/ru-litbrl.ctb:
+ * tables/ru-letters.dis:
+ * tables/ru-compbrl.ctb:
+ * tables/ru-chardefs.cti:
+ * tables/Makefile.am (table_files): Add new russian tables.
+
+ * tables/hyph_ru.dic: Added russian hyphenation dictionary.
+
+ * tables/it-it-comp6.utb: A little fix for Italian table.
+
+2013-01-28 Knut Arne Bjørndal <bob+liblouis@cakebox.net>
+
+ * tables/no-no-g0.utb: Fixes for Emphasis marks in the norwegian
+ braille table.
+
+2013-01-25 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/no-no-g0.utb: Corrections for double angle quotation
+ mark. Thanks to Knut Arne Bjørndal <bob+liblouis@cakebox.net> for
+ the patch.
+
+2013-01-24 Christian Egli <christian.egli@sbs.ch>
+
+ * tools/lou_trace.c: Fix warnings and run through indent.
+
+2013-01-24 David Reynolds <dkreynolds@ntlworld.com>
+
+ * tables/en-gb-comp8.ctb: Add the British pound sign.
+
+2013-01-21 David Reynolds <dkreynolds@ntlworld.com>
+
+ * tables/en-gb-comp8.ctb: Added a table for U.K. English 8 dot
+ Computer braille.
+
+2013-01-21 Joseph Lee <joseph.lee22590@gmail.com>
+
+ * tables/en-ueb-g2.ctb: Improvements based on Leona's requested
+ changes.
+
+2013-01-17 Joseph Lee <joseph.lee22590@gmail.com>
+
+ * tables/en-ueb-g2.ctb: Changed some entries thanks to the
+ document that Leona provided.
+
+2013-01-11 Christian Egli <christian.egli@sbs.ch>
+
+ * liblouis/Makefile.am:
+ * gnulib/Makefile.am:
+ * configure.ac:
+ * HACKING: Use the malloc and realloc modules from gnulib to
+ enable cross compilation to windows using mingw.
+
+2013-01-09 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/ko.ctb: Fixes for the Korean tables by Joseph Lee.
+
+2013-01-04 Christian Egli <christian.egli@sbs.ch>
+
+ * gnulib/sys/*.h:
+ * gnulib/m4/*.m4
+ * gnulib/*.h:
+ * gnulib/*.c:
+ * gnulib/Makefile.am:
+ * build-aux/snippet/*.h: Upgrade to gnulib v0.0-7794-g964bbc2
+
+ * tables/en-ueb-g2.ctb: excludes entries that are not needed,
+ thanks to Joseph Lee.
+
+ * tables/Makefile.am (table_files):
+ * tables/ko.ctb:
+ * tables/ko-g2.ctb:
+ * tables/ko-g1.ctb: Added Korean tables by Joseph Lee.
+
+ * tests/check_all_tables.pl: Ignore zip files.
+
+2012-12-21 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/check_all_tables.pl: Exclude backup, patch, diff and txt
+ files from the table tests.
+
+2012-12-20 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/Makefile.am (table_files):
+ * tables/ru-ru-comp8: Remove ru-ru-comp8 table as it fails and is
+ a duplicate of ru.ctb
+
+ * tests/check_all_tables.pl: Check all files by default and
+ exclude only known exceptions, e.g. Makefiles, shell scripts, etc.
+
+2012-12-19 Christian Egli <christian.egli@sbs.ch>
+
+ * gnulib/m4/unistd_h.m4:
+ * gnulib/m4/gnulib-comp.m4:
+ * gnulib/m4/extern-inline.m4:
+ * gnulib/unistd.in.h:
+ * gnulib/unistd.c:
+ * gnulib/Makefile.am (libgnu_la_SOURCES):
+ * build-aux/snippet/warn-on-use.h: Upgrade to newest gnulib
+
+ * tests/brl_checks.c (convert_typeform): Make it compile under
+ C89.
+
+ * tools/lou_translate.c (print_help):
+ * tools/lou_trace.c (print_help):
+ * tools/lou_debug.c (print_help):
+ * tools/lou_checktable.c (print_help):
+ * tools/lou_checkhyphens.c (print_help):
+ * tools/lou_allround.c (print_help): Update the usage message to
+ show that more than one table can be specified.
+
+2012-12-18 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/tables/Makefile.am (EXTRA_DIST): Add all test tables.
+
+2012-12-17 Christian Egli <christian.egli@sbs.ch>
+
+ * NEWS: Added all new features to the NEWS entry for this release.
+
+ * doc/liblouis.texi: Add documentation for the lou_trace program.
+
+ * tools/lou_trace.c: Add copyright information.
+ (print_script): Fixes to the printing of context rules.
+
+ * liblouis/lou_translateString.c (checkMultCaps):
+ (noCompbrlAhead): Fix the valgrind warnings properly without
+ adding a regression.
+ (translateString): Make sure appliedRules are also updated for the
+ context opcode.
+
+2012-12-17 Hammer Attila <hammera@pickup.hu>
+
+ * tests/harnessSources/hu-hu-g1_harness_source.txt:
+ * tests/harnessSources/hu-hu-g1-hyph_harness_source.txt:
+ * tests/harness/hu-hu-g1_harness.txt:
+ * tests/harness/hu-hu-g1-hyph_harness.txt:
+ * tables/hu-exceptionwords.cti: Bug fix and tests for the
+ Hungarian grade 1 table.
+
+2012-12-14 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/typeform.c: Added a comment about the purpose of this
+ file, as it isn't really a test
+
+ * tests/brl_checks.h:
+ * tests/brl_checks.c (convert_typeform): Add the new function to
+ the header file.
+
+2012-12-13 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/typeform.c:
+ * tests/en_gb_g1_italics.c:
+ * tests/brl_checks.c:
+ * liblouis/compileTranslationTable.c: Fix compiler warnings, like
+ unused variables, macro redefinition, comparison between signed
+ and unsigned integer expressions, etc.
+
+ * configure.ac:
+ * NEWS: Update for release 2.5.2
+
+2012-12-13 Paul Wood <paulw.torchtrust@gmail.com>
+
+ * tables/en-GB-g2.ctb: Fix a regression with the 'com'
+ contraction.
+
+2012-12-10 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/ukchardefs.cti: Fixes provided by Paul Paul Wood.
+
+2012-12-07 Paul Wood <paulw.torchtrust@gmail.com>
+
+ * tables/en-GB-g2.ctb: Corrections to the g2 table.
+
+2012-12-06 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/ko.ctb:
+ * tables/Makefile.am (table_files): Add a table for Korean
+ provided by Joseph Lee <joseph.lee22590@gmail.com>
+
+2012-12-04 Christian Egli <christian.egli@sbs.ch>
+
+ * liblouis/Makefile.am (AM_ETAGSFLAGS): The langmap option only
+ works if you use ctags. Newer versions of etags (i.e. emacs 24 and
+ up) seem to generate proper TAGS files even for *.ci files, so
+ this option can be removed.
+
+2012-12-03 Christian Egli <christian.egli@sbs.ch>
+
+ * liblouis/lou_translateString.c (lou_dotsToChar): Fix some
+ valgrind warnings about invalid reads, i.e. do some array bound
+ checking.
+
+2012-12-03 Joseph Lee <joseph.lee22590@gmail.com>
+
+ * tables/Makefile.am (table_files):
+ * tables/en-ueb-g1.ctb:
+ * tables/en-ueb-g2.ctb: Added ueb tables
+
+2012-10-02 Christian Egli <christian.egli@sbs.ch>
+
+ * gnulib: Update gnulib
+
+2012-09-21 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/it-it-comp8.utb: More fixes to the italian table. Thanks
+ to Simone Dal Maso <simone.dalmaso@juvox.it>
+
+2012-09-06 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/Makefile.am (check_PROGRAMS):
+ * tests/brl_checks.c:
+ * tests/brl_checks.h:
+ * tests/pass1Only.c: Added a test case for the reported memory
+ problem with pass1Only.
+
+2012-09-05 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/runHarness.py (test_allCases): Add some code to enable the
+ harness to return the result of the tests. Disable it for now as
+ there are still some tables that fail that we cannot fix before
+ release.
+
+ * tables/de-de-comp8.ctb: Added more unicode definitions. Thanks
+ to Aliminator83@gmail.com.
+
+2012-09-04 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/check_all_tables.pl:
+ * tests/check_endless_loop.pl:
+ * tests/multiple_table_path.pl: When doing VPATH builds (such as
+ in `make distcheck`) the binary for lou_checktable is not found.
+ Just use a relative path to find it.
+
+2012-07-10 Christian Egli <christian.egli@sbs.ch>
+
+ * doc/liblouis.texi (How to Write Translation Tables): Document
+ the fact that translation tables can now be in UTF-8.
+ (Top): Document the doctests.
+ (How to Write Translation Tables): Add some minimal documentation
+ about the doctests
+
+2012-06-28 Christian Egli <christian.egli@sbs.ch>
+
+ * doc/liblouis.texi (Miscellaneous Opcodes): Enhance the
+ documentation on the display opcode
+
+2012-06-14 Christian Egli <christian.egli@sbs.ch>
+
+ * liblouis/lou_translateString.c (hyphenate): Fix a buffer overrun.
+
+2012-06-07 Christian Egli <christian.egli@sbs.ch>
+
+ * liblouis/compileTranslationTable.c (compilePassOpcode): Increase
+ the number of chars matched in a $a. expression from 32 to 0xffff.
+
+ * doc/liblouis.texi (The Context and Multipass Opcodes): Document
+ the fact that context $a. matches are limited to 0xffff
+
+ * python/louis/__init__.py.in (hyphenate): Now that we know that
+ hyphens array should be inlen+1 adapt the Python bindings
+ accordingly.
+
+ * doc/liblouis.texi (lou_hyphenate): Fix a documentation bug with
+ lou_hyphenate. The length of the hyphens array should be inlen+1.
+
+ * tests/Makefile.am (check_PROGRAMS):
+ * tests/brl_checks.c (check_hyphenation):
+ * tests/brl_checks.h:
+ * tests/hyphenate.c (main): Add a test program hyphenation.
+
+2012-06-01 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/Makefile.am:
+ * tests/repeated.c:
+ * tests/squash_space.c:
+ * tests/tables/Makefile.am:
+ * tests/tables/repeated.utb:
+ * tests/tables/repeated_with_correct.utb:
+ * tests/tables/squash_space_with_context_1.utb:
+ * tests/tables/squash_space_with_context_2.utb:
+ * tests/tables/squash_space_with_correct.utb:
+ * tests/tables/squash_space_with_repeated.utb: More tests for
+ squashing white space. It looks like I found some bugs after all.
+
+ * tests/brl_checks.c (check_translation): Also print the input
+ string and delimit the strings with single quotes to better see
+ white space.
+
+ * TODO: Added a TODO file to note things that could/should be
+ done.
+
+ * tables/de-de-comp8.ctb: Add Symbols such as double quotes,
+ dashes to the German computer braille table. Thanks to
+ Aliminator83@gmail.com
+
+2012-05-31 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/Makefile.am:
+ * tests/repeated.c:
+ * tests/tables/Makefile.am:
+ * tests/tables/repeated.utb:
+ * tests/tables/repeated_with_correct.utb: Added a test for the
+ repeated opcode. Rumors had it that it was buggy, but it does what
+ it is supposed to.
+
+ * doc/liblouis.texi (The correct Opcode): Remove the comment about
+ input and output positions being incorrect. This bug has been fixed.
+
+2012-05-30 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/tables/letterDefTest_uppercase.ctb:
+ * tests/tables/letterDefTest_uplow.ctb:
+ * tests/tables/letterDefTest_lowercase.ctb:
+ * tests/tables/letterDefTest_letter.ctb:
+ * tests/letterDefTest.c (main): Convert the test so that it
+ returns the result of the test. Also use the \xhhhh notation for
+ unicode so that it works with the c based test framework.
+
+2012-05-11 Christian Egli <christian.egli@sbs.ch>
+
+ * liblouis/compileTranslationTable.c (doLang2table): Remove an
+ unused variable that was reported by -Wall
+ (getALine): Properly initialize a variable. This issue was
+ reported by Valgrind.
+
+2012-05-07 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/brl_checks.c (check_translation): Enhance to be able to
+ handle \xhhhh encoded strings like the rest of liblouis. This is
+ to support unicode based test cases.
+
+ * tests/uplow_with_unicode.c:
+ * tests/tables/uplow_with_unicode.ctb:
+ * tests/tables/lowercase_with_unicode.ctb:
+ * tests/Makefile.am (uplow_with_unicode_SOURCES): Add a test for
+ the problem with lowercase and unicode.
+
+2012-04-20 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/nl-BE.dis:
+ * tables/Makefile.am (table_files):
+ * tests/doctests/Makefile.am:
+ * tests/doctests/nl-BE-g1.ctb_test.txt: Added a doctest for the
+ dutch tables
+
+2012-04-18 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/pass2_outpos.c:
+ * tests/pass2_inpos.c: Rename test to reflect what it really
+ tests.
+
+ * tests/Makefile.am:
+ * tests/brl_checks.h:
+ * tests/brl_checks.c (check_inpos):
+ * tests/inpos_compbrl.c: Rename check_outpos to check_inpos to
+ reflect the true intention of the function.
+
+2012-04-17 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/doctests/en-GB-g2.ctb_test.txt:
+ * tests/check_doctests.py (TestHelper): Add a test helper to
+ simplify the writing of doctests.
+
+ * tests/tables/moreTables/include.utb:
+ * tests/Makefile.am (TESTS_ENVIRONMENT):
+ * tests/multiple_table_path.pl: Added some tests for the improved
+ LOUIS_TABLEPATH functionality.
+
+2012-04-13 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/Makefile.am:
+ * tests/tables/pass2.ctb:
+ * tests/pass2_outpos.c: Add a test for the problem with pass2 and outpos.
+
+ * tests/brl_checks.h:
+ * tests/brl_checks.c (check_outpos):
+ * tests/inpos_compbrl.c (main): Enhance so that output position
+ can be checked for different tables.
+
+2012-03-23 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/tables/pass2.ctb:
+ * tests/tables/Makefile.am:
+ * tests/pass2.c:
+ * tests/Makefile.am: Add a test to show the regression with the
+ pass2 opcode.
+
+ * tests/brl_checks.c (check_translation): Make the printing of
+ test results more robust (against out of bound errors).
+
+2012-03-21 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/Makefile.am (TESTS_ENVIRONMENT): Set the env variables so
+ that the libraries and executables from the source directories are
+ used instead of the installed ones.
+
+2012-03-20 Christian Egli <christian.egli@sbs.ch>
+
+ * configure.ac:
+ * tests/Makefile.am: Only enable the Python based tests if
+ configured with ucs4.
+
+2012-03-02 Mesar Hameed <mesar.hameed@gmail.com>
+
+ * configure.ac:
+ * doc/liblouis.texi:
+ * tests/Makefile.am:
+ * tests/harness/Makefile.am:
+ * tests/harness/__init__.py:
+ * tests/harness/en-GB-g2_harness.py:
+ * tests/runHarness.py: Add a test harness, i.e. an infrastructure
+ to be able to do table tests in a simple and concise syntax.
+
+2012-03-01 Christian Egli <christian.egli@sbs.ch>
+
+ * configure.ac:
+ * python/louis/Makefile.am:
+ * tests/Makefile.am:
+ * tests/check_doctests.py:
+ * tests/doctests/Makefile.am:
+ * tests/doctests/en-GB-g2.ctb_test.txt: Check for Python in
+ configure and if there is a Python interpreter enable some Python
+ based doctests.
+
+
+2012-02-27 Mesar Hameed <mesar.hameed@gmail.com>
+
+ * python/louis/__init__.py.in: Expose the constants otherTrans and
+ ucBrl in the python bindings.
+
+2012-02-22 Christian Egli <christian.egli@sbs.ch>
+
+ * configure.ac: Update version number
+
+ * tables/ta-ta-g1.ctb: Added a new tamil table by Mesar Hameed
+ <mesar.hameed@gmail.com>
+
+ * tables/no-no.ctb: Additions to the Norwegian braille tables
+ thanks to David Hole.
+
+2012-02-21 Juan Carlos Buño Suárez <quetzatl@eresmas.net>
+
+ * tables/Es-Es-G0.utb: add support for the letter Ñ to the Spanish
+ table.
+
+2012-02-20 Birkir Gunnarsson <birkir@midstod.is>
+
+ * tables/is.ctb: Updates and additions to Icelandic 8-dot braille
+ table.
+
+2012-02-06 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/Es-Es-G0.utb: Added Spanish grade0 table provided by José
+ Enrique Fernández del Campo and Juan Carlos Buño Suárez.
+
+2012-02-01 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/pt-pt-g1.utb: Added improvements to Portuguese table by
+ Rui Batista <ruiandrebatista@gmail.com>.
+
+ * tables/hyph_cs_CZ.dic:
+ * tables/Makefile.am (table_files): Added hyphenation table for
+ Czech provided by Jan Halousek
+
+2012-01-09 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/ar-ar-g1.utb: Added updates to Generic Arabic table by
+ Mesar Hameed <mesar.hameed@gmail.com>
+
+2011-08-19 Bert Frees <bertfrees@gmail.com>
+
+ * tables/cs-chardefs.cti:
+ * tables/cs-g1.ctb:
+ * tables/cs-translation.ctb: Improved translation tables for Czech
+ braille. Credit goes to Jan Halousek
+
+2011-08-08 Michel Such <michel.such@free.fr>
+
+ * tables/fr-bfu-comp8.utb:
+ * tables/fr-bfu-comp6.utb: Updated French tables.
+
+2011-06-28 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/Makefile.am (table_files): Added the table provided by
+ Mesar Hameed to the build process.
+
+2011-06-28 Mesar Hameed <mesar.hameed@gmail.com>
+
+ * tables/ar-fa.utb: Added a table for Arabic Farsi.
+
+ * tables/ar-ar-g1.utb: Enhance the Generic Arabic Grade 1 table
+
+2011-06-24 Christian Egli <christian.egli@sbs.ch>
+
+ * windows/Makefile.nmake: Rename the Makefile to Makefile.nmake to
+ make sure it's not overwritten by autoconf
+
+ * windows/Makefile.am (SUBDIRS): Add the include sub dir
+
+2011-06-17 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/Makefile.am (en_gb_g1_italics_SOURCES):
+ * tests/en_gb_g1_italics.c (main): Add a test case for italics
+ with the en-gb-g1.utb table.
+
+2011-05-30 Stefan Moisei <vortex37@gmail.com>
+
+ * tables/ro.ctb: Updates to Romanian table.
+
+2011-05-25 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/brl_checks.c (check_translation): Print the outbuf using a
+ dedicated function. The normal printf with the %ls modifier
+ doesn't work as outbuf is not really of type wchar_t. Now the
+ received output is correctly printed in the test cases.
+
+2011-05-18 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/braille-patterns.cti: Fix a problem with the definition
+ of Unicode character U+2800. This issue was brought up on the list
+ by James Teh.
+
+2011-05-18 Michel Such <michel.such@free.fr>
+
+ * tables/fr-bfu-comp8.utb: Some fixes for french tables.
+
+2011-05-09 Christian Egli <christian.egli@sbs.ch>
+
+ * NEWS:
+ * configure.ac: Changed the version number.
+
+2011-05-03 Coscell Kao <coscell@molerat.net>
+
+ * tables/zh-tw.ctb: Update the Chinese braille table.
+
+2011-04-26 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/ar-ar-g1.utb (math): Integrate a patch by Mesar Hameed
+ <mesar.hameed@gmail.com>, some white space and encoding cleanup.
+
+2011-04-15 Peter Engström <peter.engstrom@indexbraille.com>
+
+ * tables/sr-chardefs.cti:
+ * tables/sr-g1.ctb:
+ * tables/sr-translation.ctb:
+ * tables/Makefile.am (table_files): Added braille tables for
+ Serbian
+
+ * tables/gez-chardefs.cti:
+ * tables/gez-g1.ctb:
+ * tables/gez-translation.ctb:
+ * tables/Makefile.am (table_files): Added braille tables for
+ Ethiopic
+
+ * tables/ckb-chardefs.cti:
+ * tables/ckb-g1.ctb:
+ * tables/ckb-translation.ctb:
+ * tables/Makefile.am (table_files): Added braille tables for
+ Sorani (Kurdish)
+
+2011-04-15 Bert Frees <bertfrees@gmail.com>
+
+ * tables/es-chardefs.cti:
+ * tables/es-g1.ctb:
+ * tables/es-translation.ctb:
+ * tables/Makefile.am (table_files): Improvements to the Spanish
+ Braille tables.
+
+ * tables/nl-BE-translation.ctb:
+ * tables/nl-BE-g1.ctb:
+ * tables/Makefile.am (table_files): Improvements to the Dutch
+ Braille tables.
+
+ * tables/braille-patterns.cti:
+ * tables/nl-BE-chardefs.cti:
+ * tables/wiskunde-chardefs.cti:
+ * tables/wiskunde-translation.ctb:
+ * tables/wiskunde.ctb:
+ * tables/Makefile.am (table_files): Improvements to the Flemish
+ Braille Math Code tables.
+
+2011-04-15 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/check_all_tables.pl: Make sure translation tables which
+ are just meant to be included such as *-translation.ctb are not
+ checked.
+
+2011-04-08 Coscell Kao <coscell@molerat.net>
+
+ * tables/zh-tw.ctb: Improvements to the Chinese braille table
+
+2011-03-30 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/multiple_table_path.pl: Make sure the test also run in a
+ VPATH build, i.e. in make distcheck.
+
+2011-03-28 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/Makefile.am (table_files): Added a new swedish table
+ provided by Samuel Thibault.
+
+ * doc/liblouis.texi (Deprecated Opcodes): Added a section on
+ deprecated opcodes.
+
+2011-03-21 Christian Egli <christian.egli@sbs.ch>
+
+ * contrib/liblouis.spec: Removed spec file as it is now maintained
+ in Fedora.
+
+2011-03-03 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/it-it-g1.utb2: Added an updated italian 8 dot table
+ provided by Caterina Avoledo <catery81@yahoo.it>
+
+2010-12-16 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/check_all_tables: Removed
+
+ * tests/check_all_tables.pl: Port the check_all_tables shell
+ script to perl and add a timeout to handle the endless loop
+ problem when checking all the tables.
+
+2010-12-09 Bert Frees <bertfrees@gmail.com>
+
+ * tables/nl-BE.cti:
+ * tables/nl-BE-g1.ctb: modified the Dutch tables a bit, for
+ improved back-translation and hyphenation.
+
+2010-12-09 Lars Bjørndal <lars@lamasti.net>
+
+ * tables/no-no-g0.utb:
+ * tables/no-no-g1.utb:
+ * tables/no-no-g2.utb:
+ * tables/no-no-g3.utb: Added slightly modified versions of
+ Norwegian braille tables.
+
+2010-12-07 Christian Egli <christian.egli@sbs.ch>
+
+ * tests/tables/loop.ctb:
+ * tests/tables/Makefile.am:
+ * tests/check_endless_loop.pl:
+ * tests/Makefile.am:
+ * configure.ac: Add a new test case which exhibits an endless loop
+ in the table compiler if you configure with --enable-ucs4.
+
+ * tables/is-chardefs6.cti: Fix a problem with undefined dot
+ patterns.
+
+2010-12-07 Bert Frees <bertfrees@gmail.com>
+
+ * tables/wiskunde_edit.cti:
+ * tables/wiskunde.cti:
+ * tables/wiskunde.ctb:
+ * tables/nl-BE.cti:
+ * tables/nl-BE-g1.ctb: Added Dutch tables provided by Bert Frees
+
+2010-11-26 Christian Egli <christian.egli@sbs.ch>
+
+ * doc/liblouis.texi (Translation Opcodes): Fix typos and add an
+ example for the usage of joinnum.
+ (The Context and Multipass Opcodes): Added some clarification on
+ the workings of the multipass opcode that was posted to the
+ mailing list by Bert Frees.
+ (The Context and Multipass Opcodes): beautify the table
+ of characters that can be used for attribute strings.
+
+2010-11-18 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/is-chardefs8.cti: Add table for computer braille based on
+ the IceBraille standard, v1.0 by Birkir Gunnarsson,
+ birkir@midstod.is
+
+2010-11-12 Christian Egli <christian.egli@sbs.ch>
+
+ * tables/Makefile.am (table_files):
+ * tables/es-old.dis:
+ * tables/es-new.dis:
+ * tables/es-g1.ctb:
+ * tables/es-chardefs.cti:
+ * tables/ca-g1.ctb:
+ * tables/ca-chardefs.cti: Added Spanish tables made by Bert Frees
+ <bertfrees@gmail.com>.
+
+2010-09-27 Christian Egli <christian.egli@sbszh.ch>
+
+ * tables/Makefile.am (table_files): Integrate the new indian tables.
+ (table_files): Integrate the new Icelandic table.
+
+2010-09-27 Birkir Gunnarsson <birkir@midstod.is>
+
+ * tables/is-chardefs6.cti: Added support for Icelandic 6-dot.
+
+2010-09-27 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ * tables/as.ctb:
+ * tables/awa.ctb:
+ * tables/bengali.cti:
+ * tables/bh.ctb:
+ * tables/bn.ctb:
+ * tables/bra.ctb:
+ * tables/devanagari.cti:
+ * tables/dra.ctb:
+ * tables/gon.ctb:
+ * tables/gu.ctb:
+ * tables/gujarati.cti:
+ * tables/gurmukhi.cti:
+ * tables/hi.ctb:
+ * tables/kannada.cti:
+ * tables/kha.ctb:
+ * tables/kn.ctb:
+ * tables/kok.ctb:
+ * tables/kru.ctb:
+ * tables/malayalam.cti:
+ * tables/ml.ctb:
+ * tables/mni.ctb:
+ * tables/mr.ctb:
+ * tables/mun.ctb:
+ * tables/mwr.ctb:
+ * tables/ne.ctb:
+ * tables/new.ctb:
+ * tables/or.ctb:
+ * tables/oriya.cti:
+ * tables/pa.ctb:
+ * tables/pi.ctb:
+ * tables/sa.ctb:
+ * tables/sat.ctb:
+ * tables/sd.ctb:
+ * tables/ta.ctb:
+ * tables/tamil.cti:
+ * tables/te.ctb:
+ * tables/telugu.cti: Added quite a few indian tables.
+
+2010-08-27 Christian Egli <christian.egli@sbszh.ch>
+
+ * NEWS: Added NEWS entry for release 2.1.1
+
+2010-08-23 Christian Egli <christian.egli@sbszh.ch>
+
+ * tests/lastworditalafter.c (main): Handle two tests more elegantly.
+
+ * tests/brl_checks.c (check_translation): Make the testing code
+ robust against NULL values in the typeform parameter.
+
+ * tests/Makefile.am (check_PROGRAMS): Add lastworditalafter to
+ check_PROGRAMS.
+
+2010-08-23 James Teh <jamie@jantrid.net>
+
+ * NEWS: Small corrections. Also, include issue numbers with
+ their associated changes.
+
+2010-08-19 Christian Egli <christian.egli@sbszh.ch>
+
+ * tests/Makefile.am (XFAIL_TESTS): Move lastworditalafter to
+ XFAIL_TESTS as they currently fail
+
+ * NEWS: Added News items for release 1.9.0, 2.0.0 and 2.1.0
+
+2010-08-06 James Teh <jamie@jantrid.net>
+
+ * liblouis/lou_translateString.c: Fix the output cursorPos when the
+ compbrlAtCursor mode is enabled and the characters around the cursor
+ translate to multiple braille cells, such as in the Chinese braille
+ tables.
+
+2010-08-05 James Teh <jamie@jantrid.net>
+
+ * python/louis/__init__.py.in: Allow the user to configure the maximum
+ output length by specifying a number by which the input length is
+ multiplied using the outlenMultiplier module variable. The default will
+ handle the case where every input character is undefined in the
+ translation table. Previously, this was hard-coded to 2, which was
+ insufficient in some cases.
+ Rename tran_tables argument to tableList in all functions to be
+ consistent with liblouis itself.
+
+2010-08-04 James Teh <jamie@jantrid.net>
+
+ * python/louis/__init__.py.in: Corrections/clarifications to docstrings.
+ Add compbrlLeftCursor mode constant.
+ Add compileString function which wraps lou_compileString.
+
+2010-08-03 James Teh <jamie@jantrid.net>
+
+ * liblouis/lou_translateString.c: Fix the input/output position arrays
+ for characters in the input which are undefined in the translation
+ table.
+
+2010-07-21 James Teh <jamie@jantrid.net>
+
+ * python/setup.py: Remove unnecessary imports, allowing this to
+ run in Python 2.7. (issue 12)
+
+2010-04-15 Christian Egli <christian.egli@sbszh.ch>
+
+ * tests/brl_checks.h:
+ * tests/brl_checks.c (check_translation): Add a function for
+ checking a translation against an expected result.
+
+ * tests/lastworditalafter.c (main): Add a test for handling of
+ italics using an English and a German table
+
+ * tests/Makefile.am (lastworditalafter_SOURCES): Added the
+ lastworditalafter test to the check programs
+
+2010-02-12 Michael Whapples <mwhapples@aim.com>
+
+ * python/louis/__init__.py.in: Added python function louis.backTranslate
+ to wrap lou_backTranslate. Has same calling as louis.translate but again
+ with the slightly different meanings as described in liblouis
+ documentation for lou_backTranslate.
+ Also made some minor error corrections in docstrings.
+
+2010-02-12 Michael Whapples <mwhapples@aim.com>
+
+ * python/louis/__init__.py.in: Added louis.backTranslateString to wrap
+ lou_backTranslateString in python. Calling is similar to that for
+ louis.translateString. You should be aware of the possible different
+ use of typeform in lou_translateString and lou_backTranslateString.
+
+2010-02-11 Michael Whapples <mwhapples@aim.com>
+
+ * python/louis/__init__.py.in: Added support for python to recieve
+ typeform data back from louis.translate and louis.translateString.
+ For both of these the data will be placed in the typeform list handed
+ in to the function. If you don't want this to happen then don't
+ use a list (eg. use a tuple).
+
+2010-02-11 Michael Whapples <mwhapples@aim.com>
+
+ * python/louis/__init__.py.in: Added louis.hyphenate to allow access
+ from python to the lou_hyphenate function. Its definition is
+ def hyphenate(tran_tables, inbuf, mode=0)
+ Where tran_tables is a list like for the translate functions,
+ inbuf is the text or Braille to hyphenate and mode says if inbuf
+ is to be treated as text or Braille. It returns the hyphenation
+ data in a string.
+
+2010-02-04 James Teh <jamie@jantrid.net>
+
+ * python/louis/__init__.py.in: lou_translate* writes output information
+ in typeform, so allocate enough bytes for it. Fixes possible buffer
+ overruns and resultant crashes.
+
+2010-01-07 Christian Egli <christian.egli@sbszh.ch>
+
+ * liblouis/compileTranslationTable.c (compileError): Change the
+ format of table checking error messages to a format similar to the
+ one used in gcc.
+
+2009-11-30 Carlos Ferreira <cferreira9886@gmail.com>
+
+ * tables/Pt-Pt-g1.utb:
+ * tables/pt-pt-g2.ctb: Added tables for Portuguese grade 1 and 2.
+
+2009-11-30 Mike Sivill <mike.sivill@viewplus.com>
+
+ * tables/da-dk-g2.ctb: Added tables for Danish grade 2.
+
+2009-11-23 John J. Boyer <john.boyer@abilitiessoft.org>
+
+ * Release 1.8.0: See NEWS for new features
+
+
+2009-11-20 Christian Waldvogel <christian.waldvogel@sbszh.ch>
+
+ * tables/de-ch-accents.cti:
+ * tables/de-ch-g0.utb:
+ * tables/de-ch-g1.ctb:
+ * tables/de-ch-g2.ctb:
+ * tables/de-chardefs6.cti:
+ * tables/de-chardefs8.cti:
+ * tables/de-de-accents.cti:
+ * tables/de-de-g0.utb:
+ * tables/de-de-g1.ctb:
+ * tables/de-de-g2.ctb:
+ * tables/de-eurobrl6.dis:
+ * tables/de-eurobrl6u.dis:
+ * tables/de-g0-core.utb:
+ * tables/de-g1-core.ctb:
+ * tables/de-g2-core.ctb:
+ * tests/check_all_tables: Added German grade 2 and Swiss German
+ grade 0, 1 and 2.
+
+2009-11-18 Christian Egli <christian.egli@sbszh.ch>
+
+ * doc/liblouis.texi (lou_checkhyphens): Document the --help and
+ --version options that all the tools support now. Also document
+ the lou_checkhyphens tool.
+
+2009-11-12 Christian Egli <christian.egli@sbszh.ch>
+
+ * liblouis/liblouis.h.in (widechar):
+ * liblouis/liblouis.h (widechar):
+ * configure.ac: No longer include config.h in liblouis.h. Instead
+ define the type of widechar in configure and generate liblouis.h
+ based on the options given to configure and liblouis.h.in.
+
+2009-11-05 Christian Egli <christian.egli@sbszh.ch>
+
+ * COPYING:
+ * COPYING.LIB:
+ * README: Explain that the library is licensed under LGPL and the
+ tools under GPL.
+
+ * HACKING: Mention the use of gnulib and explain how to update it.
+
+2009-11-02 Christian Egli <christian.egli@sbszh.ch>
+
+ * tables/Makefile.am (table_files):
+ * tables/sv-1996.ctb:
+ * tables/sv-1989.ctb: Added two more tables for Swedish that were
+ ported from brltty by Samuel Thibault.
+
+2009-10-16 Christian Egli <christian.egli@sbszh.ch>
+
+ * tests/table_test_corpuses/README:
+ * tests/table_test_corpuses/Makefile.am:
+ * tests/table_test_corpuses/test_de-de-g0.utb:
+ * tests/table_test_corpuses/test_en-us-g2.ctb:
+ * tests/check_tables_against_corpus.pl:
+ * tests/Makefile.am: Added a framework for corpus based table tests.
+
+2009-10-13 Christian Egli <christian.egli@sbszh.ch>
+
+ * man/Makefile.am: When generating the man pages at distribution
+ time you need to make sure that all the libraries and all the
+ tools are built. This makes the Makefile complex for no good
+ reason (since John doesn't have help2man anyway). So the man pages
+ are not distributed now. If a user wants man pages they have to
+ install help2man.
+
+2009-10-09 Christian Egli <christian.egli@sbszh.ch>
+
+ * Makefile.am:
+ * configure.ac:
+ * tools/lou_allround.c:
+ * tools/lou_checkhyphens.c:
+ * tools/lou_checktable.c:
+ * tools/lou_debug.c:
+ * tools/lou_translate.c: Integrate gnulib (modules getopt,
+ progname and version-etc) and use it to add --help and --version
+ options to all the tools. Due to an (apparent) restriction in
+ progname I also changed the config header to (standard) "config.h"
+ instead of "louiscfg.h".
+
+ * man/Makefile.am (man_MANS): Automatically generate man pages for
+ all the tools if help2man is installed.
+
+2009-10-08 Christian Egli <christian.egli@sbszh.ch>
+
+ * tools/lou_allround.c:
+ * tools/lou_checkhyphens.c:
+ * tools/lou_checktable.c:
+ * tools/lou_debug.c:
+ * tools/lou_translate.c: Change the license of the tools to GPL.
+
+2009-09-18 Christian Egli <christian.egli@sbszh.ch>
+
+ * tests/Makefile.am: Define the test scripts with check_SCRIPTS
+ and make sure they are distributed.
+
+
+2009-08-24 Christian Egli <christian.egli@sbszh.ch>
+
+ * tests/Makefile.am: Re-enable the present_progressive test but
+ mark it as "expected failure" so that the test suite still passes.
+
+ * tests/present_progressive.c: Add a description as to what this
+ test is trying to check. Thanks Jamie for the explanation.
+
+2009-08-21 Christian Egli <christian.egli@sbszh.ch>
+
+ * tests/Makefile.am: Comment out the present_progressive test
+ completely so autogen.sh no longer complains.
+
+2009-08-19 Mike Sivill <mike.sivill@viewplus.com>
+
+ * tables/da.ctb:
+ * tables/da-dk-g1.utb: Bug fixes for the Danish tables
+
+2009-08-19 Christian Egli <christian.egli@sbszh.ch>
+
+ * tests/Makefile.am (check_PROGRAMS): disable the
+ present_progressive test.
+
+ * tables/Makefile.list, tables/Makefile.skel: removed as
+ functionality is now provided by maketablelist.sh
+
+ * tables/maketablelist.sh: renamed from tables/maketablelist
+
+2009-08-12 Christian Egli <christian.egli@sbszh.ch>
+
+ * tests/check_all_tables (TABLES): No longer check include tables
+ that are not valid on their own.
+
+2009-08-11 John J. Boyer <john.boyer@abilitiessoft.org>
+
+ * Updated edit tables for UK maths and Marburg to give more
+ readable output.
+
+2009-08-03 John J. Boyer <john.boyer@abilitiessoft.org>
+
+ * Added new tables for Marburg maths.
+
+
+2009-07-29 John J. Boyer <john.boyer@abilitiessoft.org>
+
+ * Added replaceGrouping function
+
+
+2009-07-28 Christian Egli <christian.egli@sbszh.ch>
+
+ * tables/Makefile.am: Remove some spurious files from the list of
+ tables.
+
+2009-07-28 John J. Boyer <john.boyer@abilitiessoft.org>
+ * Alpha release of UK Maths tables
+
+2009-07-17 Lars Bjørndal <lars@lamasti.net>
+
+ * contrib/liblouis.spec: Added rpm spec file.
+
+2009-07-13 John J. Boyer <john.boyer@abilitiessoft.org>
+
+ * Merged compileTranslationTable.c and lou_translateString.c
+ with code for non-nemeth math back into trunk
+
+2009-07-06 Christian Egli <christian.egli@sbszh.ch>
+
+ * tables/Makefile.am (table_files): Bring the list of tables up to
+ date.
+
+2009-07-03 Christian Egli <christian.egli@sbszh.ch>
+
+ * tests/Makefile.am (TESTS_ENVIRONMENT): Set the environment so
+ that the tests also pass when building in a separate directory and
+ in particular for the `distcheck' rule.
+
+ * tests/brl_checks.c (TRANTAB): Since the Makefile sets the
+ LOUIS_TABLEPATH we no longer need to specify the path to the
+ table.
+
+ * tests/check_all_tables: Use LOUIS_TABLEPATH to find the tables.
+
+ * tables/sk-sk.utb: Fix errors that were reported by
+ lou_checktable.
+
+2009-07-03 James Teh <jamie@jantrid.net>
+
+ * configure.ac: Include the version suffix in the dll name for Windows again (don't add -avoid-version).
+ * python/Makefile.am:
+ * python/louis/__init__.py.in: Use the precise name of the library
+ that the bindings were built with. This ensures the correct ABI
+ and allows the bindings to work on systems which do not use the .so
+ extension.
+
+2009-07-02 Christian Egli <christian.egli@sbszh.ch>
+
+ * doc/liblouis.texi (How to Write Translation Tables): Fix the
+ prefix for characters operand. It is \y for 5 digits and \z for 8
+ digits.
+
+2009-07-02 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ * tables/spaces.ctb:
+ * tables/ru.ctb:
+ * tables/gd.ctb:
+ * tables/en-chess.ctb:
+ * tables/fr-2007.ctb:
+ * tables/boxes.ctb:
+ * tables/de-chess.ctb: Fixed problems with 5-digit character
+ operands in tables.
+
+2009-07-01 Christian Egli <christian.egli@sbszh.ch>
+
+ * tests/check_all_tables: Added a test that invokes lou_checktable
+ on all tables.
+
+ * tests/Makefile.am (TESTS): Add the check_all_tables test to the
+ list of tests.
+
+2009-06-12 John J. Boyer <john.boyer@abilitiessoft.org>
+
+ * Added lou_checkhyphens tool for checking hyphenation tables and
+ the performance of the lou_hyphenate function. Did bugfixes in
+ lou_hyphenate. More to come.
+
+2009-05-19 John J. Boyer <john.boyer@abilitiessoft.org>
+
+ * Added noback and nofor opcode prefixes
+ * Documentation in liblouis.texi, etc.
+
+
+2009-04-22 John J. Boyer <john.boyer@abilitiessoft.org>
+ * Added repword opcode with documentation
+
+2009-03-24 John J. Boyer <john.boyer@abilitiessoft.org>
+
+ * Added ability to specify first four user-defined classes in
+ multipass opcodes.
+
+ * Updated documentation with table of multipass attributes
+
+
+2009-03-19 John J. Boyer <john.boyer@abilitiessoft.org>
+ * Fixed bug with French back-translation.
+
+
+2009-03-12 John J. Boyer <john.boyer@abilitiessoft.org>
+ * doc/Makefile.am: datarootdir may not be correct.
+
+
+2009-03-09 Christian Egli <christian.egli@sbszh.ch>
+
+ * doc/Makefile.am (doc_DATA): Use the default location for docdir.
+ Thanks to Lars Bjørndal for the report.
+
+2009-03-04 John J. Boyer <john.boyer@abilitiessoft.org>
+ * New Norwegian tables
+ * Release 1.6.0
+
+
+2009-02-26 John J. Boyer <john.boyer@abilitiessoft.org>
+
+ * Removed egregiously bad German Grade 2 taale.
+
+
+2009-02-23 (2) John J. Boyer <john.boyer@abilitiessoft.org>
+
+ * doc/louis.texi: Correcting and updating documentation
+
+
+2009-02-20 (2) John J. Boyer <john.boyer@abilitiessoft.org>
+
+ * Moved mac-osx-10.5 directory to liblouisxml
+
+
+2009-02-20 John J. Boyer <john.boyer@abilitiessoft.org>
+
+ * Added the directory mac-osx-10.5 and its files for building
+ liblouis and liblouisxml on the Mac.
+
+
+2009-02-19 Christian Egli <christian.egli@sbszh.ch>
+
+ * tables/hyph_nl_NL.dic:
+ * tables/cy-cy-g1.utb: The svn:eol-style says these files are LF,
+ however they contain CRs. So when doing a svn cat you'll get an
+ error saying "svn: Inconsistent line ending style". I fixed this
+ with dos2unix.
+
+2009-02-18 John J. Boyer <john.boyer@abilitiessoft.org>
+
+ * Changing e-mail, website and company name to abilitiessoft.
+
+
+2009-02-17 John J. Boyer <john.boyer@jjb-software.com>
+
+ * Added Russian Tables and correct Danish tables from ViewPlus
+
+2009-02-16 John J. Boyer <john.boyer@jjb-software.com>
+ * Documented exactdots opcode.
+
+
+2009-02-15 John J. Boyer <john.boyer@jjb-software.com>
+
+ * compileTranslationTable.c: Fined automatic path finding. Moved
+ getProgramPath there from paths.c in liblouisxml, and made it
+ exportable as lou_getProgramPath
+ * liblouis.h: added lou_getProgramPath for Windows only.
+
+2009-02-14 James Teh <jamie@jantrid.net>
+
+ * liblouis/compileTranslationTable.c:
+ * liblouis/liblouis.h:
+ * liblouis/lou_backTranslateString.c:
+ * liblouis/lou_translateString.c: Use stdcall calling convention if building for Windows.
+ * configure.ac: If building for Windows, pass --add-stdcall-alias to the linker so that non-decorated function aliases are generated for the stdcall exported functions.
+ * python/louis/__init__.py: Update to work with stdcall under Windows.
+
+2009-02-14 Eitan Isaacson <eitan@ascender.com>
+
+ * liblouis/compileTranslationTable.c (getFullTablePath): Added a
+ new table search path function.
+ * liblouis/Makefile.am: Define a macro with the installed
+ tables directory TABLESDIR.
+
+2009-02-09 John J. Boyer <john.boyer@jjb-software.com>
+
+ * Latest French tables.
+
+2009-02-09 Christian Egli <christian.egli@sbszh.ch>
+
+ * doc/liblouis.texi (Programming with liblouis): Move the
+ programming section to the back and rename to emphasize more on
+ the user instead of the programmer.
+
+ * doc/liblouis-guide.texi: rename it to liblouis.texi.
+
+2009-02-03 John J. Boyer <john.boyer@jjb-software.com>
+
+ * Implement exactdots opcode
+
+2009-01-22 Christian Egli <christian.egli@sbszh.ch>
+
+ * doc/liblouis-guide.texi (The Context and Multipass Opcodes):
+ Document the problem with correct and multipass opcodes and input
+ and output positions.
+
+2009-01-21 James Teh <jamie@jantrid.net>
+
+ * tables/UEBC-g1.ctb: Some fixes to the UEBC grade 1 table.
+
+2009-01-20 James Teh <jamie@jantrid.net>
+
+ * python/louis/__init__.py: Add pass1Only mode.
+
+2009-01-20 (2) John J. Boyer <john.boyer@jjb-software.com>
+ * Implemented pass1Only mode bit
+ * Can now set pass1Only in lou_allround
+2009-01-20 John J. Boyer <john.boyer@jjb-software.com>
+ * Change version in configure.ac to 1.5.2
+
+2009-01-20 James Teh <jamie@jantrid.net>
+
+ * liblouis/lou_translateString.c: Fix the bug whereby the next character in the input was skipped if doing compbrlAtCursor and the first character of the word was a capital letter.
+ * liblouis/compileTranslationTable.c: lou_version() now returns PACKAGE_VERSION as defined in louiscfg.h.
+ * configure.ac: Include -avoid-version in LDFLAGS if the host is mingw or cygwin so that the version suffix is not included in the dll filename.
+
+2009-01-19 Christian Egli <christian.egli@sbszh.ch>
+
+ * doc/liblouis-guide.texi (Top): Added some minimal docu for the
+ Python bindings.
+
+2009-01-19 Eitan Isaacson <eitan@ascender.com>
+
+ * Makefile.am:
+ * configure.ac:
+ * python/Makefile.am:
+ * python/louis/Makefile.am: Added Python bindings to autotooled
+ distribution.
+
+ * python/README: Unset executable flag.
+
+2009-01-19 James Teh <jamie@jantrid.net>
+
+ * liblouis/lou_translateString.c: Fix issues when compbrlAtCursor is set, input is being removed due to a "repeated" opcode and cursorPos lies within the repeated input.
+
+2009-01-18 James Teh <jamie@jantrid.net>
+
+ * liblouis/lou_translateString.c: When contracting or expanding in the output, map all positions of the input to the first position of the output and all positions of the output to the first position of the input. Mapping to subsequent positions of a contraction doesn't make sense, as the contraction only makes sense as a whole.
+
+2009-01-15 Eitan Isaacson <eitan@ascender.com>
+
+ * python/setup.py:
+ * python/louis/__init__.py: Added Python bindings.
+
+2009-01-15 John J. Boyer <john.boyer/jjb-software.com>
+
+ * Version 1.5.1: bugfix
+ * liblouis/lou_translateString.c: fixed multi-word phrases
+ * tools/lou_debug.c : fixed bug in character display
+ * liblouis/compileTranslationTable.c : fixed bug in
+ findOpcodeName
+
+2009-01-14 James Teh <jamie@jantrid.net>
+
+ * liblouis/lou_translateString.c: Fix the inpos array values for the case where a rule has an output length which is larger than its input length. For example, using UEBC, given the input "#", the output will be "_?". The array mapping from output to input (inpos) previously specified [0, 1], which is incorrect; there is no character at index 1 in the input. The correct result is now returned; i.e. [0, 0].
+
+2009-01-12 John J. Boyer <john.boyer@jjb-software.com>
+
+ * Fixed problem with French Braille
+ * Completed lou_debug tool
+ * Added hooks in compileTranslationTable.c for lou_debug
+ * Updated louis.h with hook prototypes and documentation
+ * Changed version number to 1.5.0
+
+2009-01-08 Christian Egli <christian.egli@sbszh.ch>
+
+ * doc/Makefile.am (AM_MAKEINFOHTMLFLAGS): Generate the html as one
+ big page.
+
+2008-12-20 Eitan Isaacson <eitan@ascender.com>
+
+ * ChangeLog:
+ * configure.ac:
+ * doc/Makefile.am:
+ * doc/liblouis-guide.texi:
+ * doc/version.texi:
+ * liblouis/lou_translateString.c:
+ * liblouis/louiscfg.h.in:
+ * tables/Cz-Cz-g1.utb:
+ * tables/Fr-Ca-g2.ctb:
+ * tables/Fr-Fr-g2.ctb:
+ * tables/Lv-Lv-g1.utb:
+ * tables/Makefile.am:
+ * tables/Nl-Nl-g1.utb:
+ * tables/No-No-g0.utb:
+ * tables/No-No-g1.ctb:
+ * tables/No-No-g2.ctb:
+ * tables/No-No-g3.ctb:
+ * tables/Pl-Pl-g1.utb:
+ * tables/Pt-Pt-g1.utb:
+ * tables/Se-Se-g1.utb:
+ * tables/UEBC-g1.utb:
+ * tables/UEBC-g2.ctb:
+ * tables/ar-ar-g1.utb:
+ * tables/bg.ctb:
+ * tables/boxes.ctb:
+ * tables/cy-cy-g1.utb:
+ * tables/cy-cy-g2.ctb:
+ * tables/da-1252.ctb:
+ * tables/da-lt.ctb:
+ * tables/da.ctb:
+ * tables/de-chess.ctb:
+ * tables/de-de-g0.utb:
+ * tables/de-de-g1.ctb:
+ * tables/de-de-g2.ctb:
+ * tables/de-de.dis:
+ * tables/en-GB-g2.ctb:
+ * tables/en-chess.ctb:
+ * tables/en-gb-g1.utb:
+ * tables/en-us-brf.dis:
+ * tables/en-us-comp6.ctb:
+ * tables/en-us-comp8.ctb:
+ * tables/en-us-g1.utb:
+ * tables/en-us-g2.ctb:
+ * tables/en-us-interline.ctb:
+ * tables/en_CA.ctb:
+ * tables/eo.ctb:
+ * tables/et.ctb:
+ * tables/eurodefs.cti:
+ * tables/fi-fi-8dot.ctb:
+ * tables/fi-fi.ctb:
+ * tables/fi1.ctb:
+ * tables/fi2.ctb:
+ * tables/fr-2007.ctb:
+ * tables/fr-bfu-comp6.utb:
+ * tables/fr-bfu-comp8.utb:
+ * tables/fr-ca-g1.utb:
+ * tables/fr-fr-g1.utb:
+ * tables/gd.ctb:
+ * tables/gr-bb.ctb:
+ * tables/gr-gr-g1.utb:
+ * tables/hi-in-g1.utb:
+ * tables/hr.ctb:
+ * tables/hy.ctb:
+ * tables/hyph_de_DE.dic:
+ * tables/hyph_it_IT.dic:
+ * tables/hyph_nl_NL.dic:
+ * tables/hyph_no_NO.dic:
+ * tables/is.ctb:
+ * tables/it-it-g1.utb:
+ * tables/it-it-g1.utb2:
+ * tables/lt.ctb:
+ * tables/nemeth_edit.ctb:
+ * tables/nl-be-g1.utb:
+ * tables/no-gen.dis:
+ * tables/no-no.dis:
+ * tables/ro.ctb:
+ * tables/ru.ctb:
+ * tables/se-se.dis:
+ * tables/sk-sk-g1.utb:
+ * tables/sk-sk.utb:
+ * tables/spaces.ctb:
+ * tables/text_nabcc.dis:
+ * tables/tr.ctb:
+ * tables/ukchardefs.cti:
+ * tables/uni-text.dis:
+ * tables/vi.ctb:
+ * tables/zh-tw.ctb:
+ * tools/Makefile.am:
+ * tools/lou_checktable.c:
+ * tools/lou_debug.c:
+ * configure.in:
+ * doc/liblouis-guide.html:
+ * doc/liblouis-guide.txt: Merge with 1.4.0, and John's autotools.
+
+
+2008-11-12 Christian Egli <christian.egli@sbszh.ch>
+
+ * doc/liblouis-guide.texi: Added the guide in texinfo
+ * doc/Makefile.am (.texi.txt): Integrate the texinfo guide in the
+ build system.
+
+2008-06-16 John J. Boyer <john.boyer@jjb-software.com>
+
+ * Release liblouis-1.3.8
+ * Competed conversion to Gnu autotools that Eitan Isaacson started.
+
+2008-05-29 John J. Boyer <john.boyer@jjb-software.com>
+
+ * Release liblouis-1.3.71
+ * Bugs with compbrlAtCursor and returned inlen have been fixed.
+ * lou_allround has a new heature to test returned lengths.
+ * Bugs with nocont opcode fixed.
+
+2008-05-12 John J. Boyer <john.boyer@jjb-software.com>
+
+ * Release liblouis-1.3.7
+ * The moretables directory has been renamed to tables.
+ * Documentation has been moved to the docs directory.
+ * Only the programs allround, checktable and translate
+ are now supported.
+ * The names of these programs have been changed to lou_allround,
+ lou_checktable and lou_translate
+ * A few bugs have been fixed.
+
+2008-03-31 John J. Boyer <john.boyer@jjb-software.com>
+
+ * Release 1.3.6
+ * The moretables directory now contains the latest versions of
+ both the translation and hyphenation tables.
+ * The COPYING file has been changed to reflct the change from GPL to LGPL.
+
+2008-01-29 Eitan Isaacson <eitan@ascender.com>
+
+ * configure.in: Bumped to new version.
+ * tools/Makefile.am: Changed tool names
+ * tools/allround.c:
+ * tools/basicround.c:
+ * tools/checktable.c:
+ * tools/dotsround.c:
+ * tools/roundtrip.c:
+ * tools/testback.c:
+ * tools/translate.c:
+ * tools/lou_allround.c:
+ * tools/lou_basicround.c:
+ * tools/lou_checktable.c:
+ * tools/lou_dotsround.c:
+ * tools/lou_roundtrip.c:
+ * tools/lou_testback.c:
+ * tools/lou_translate.c: Prefixed all binaries with lou_.
+
+2008-01-23 Eitan Isaacson <eitan@ascender.com>
+
+ * configure.in:
+ * doc/liblouis-guide.html:
+ * doc/liblouis-guide.txt:
+ * liblouis/lou_backTranslateString.c:
+ * liblouis/lou_translateString.c:
+ * tables/chardefs.cti:
+ * tables/en-us-g2.ctb:
+ * tools/allround.c: John's 1.3.51 release.
+
+ * liblouis/lou_translateString.c:
+ * tools/Makefile.am:
+ * tools/allround.c: Jonh's 1.3.42 release.
+
+2008-01-17 Eitan Isaacson <eitan@ascender.com>
+
+ * configure.in: Tagged version 1.3.5.
+
+ * configure.in: Removed unsupported/Makefile.am
+ * tables/Makefile.am: Removed unsupported subdir.
+ * tables/unsupported: Removed.
+
+ * liblouis.pc.in: Added a variable called 'tablesdir'.
+ * tables/Cz-Cz-g1.utb:
+ * tables/Es-Es-g1.utb:
+ * tables/Fr-Ca-g2.ctb:
+ * tables/Fr-Fr-g2.ctb:
+ * tables/Lv-Lv-g1.utb:
+ * tables/Makefile.am:
+ * tables/Nl-Nl-g1.utb:
+ * tables/No-No-g0.utb:
+ * tables/No-No-g1.ctb:
+ * tables/No-No-g2.ctb:
+ * tables/No-No-g3.ctb:
+ * tables/Pl-Pl-g1.utb:
+ * tables/Pt-Pt-g1.utb:
+ * tables/README:
+ * tables/Se-Se-g1.utb:
+ * tables/UEBC-g1.utb:
+ * tables/UEBC-g2.ctb:
+ * tables/ar-ar-g1.utb:
+ * tables/cy-cy-g1.utb:
+ * tables/cy-cy-g2.ctb:
+ * tables/de-de-g0.utb:
+ * tables/de-de-g1.ctb:
+ * tables/de-de-g2.ctb:
+ * tables/de-de.dis:
+ * tables/en-GB-g2.ctb:
+ * tables/en-gb-g1.utb:
+ * tables/en-us-g1.utb:
+ * tables/errors:
+ * tables/eurodefs.cti:
+ * tables/fr-ca-g1.utb:
+ * tables/fr-fr-g1.utb:
+ * tables/gr-gr-g1.utb:
+ * tables/hi-in-g1.utb:
+ * tables/hyph_de_DE.dic:
+ * tables/hyph_en_US.dic:
+ * tables/hyph_es_ES.dic:
+ * tables/hyph_fr_FR.dic:
+ * tables/hyph_it_IT.dic:
+ * tables/hyph_nl_NL.dic:
+ * tables/hyph_no_NO.dic:
+ * tables/hyph_pl_PL.dic:
+ * tables/hyph_pt_PT.dic:
+ * tables/hyph_sv_SE.dic:
+ * tables/it-it-g1.utb:
+ * tables/nl-be-g1.utb:
+ * tables/no-no.dis:
+ * tables/se-se.dis:
+ * tables/text_nabcc.dis:
+ * tables/ukchardefs.cti:
+ * tables/uni-text.dis:
+ * tables/unsupported:
+ * tables/unsupported/Cz-Cz-g1.utb:
+ * tables/unsupported/Es-Es-g1.utb:
+ * tables/unsupported/Fr-Ca-g2.ctb:
+ * tables/unsupported/Fr-Fr-g2.ctb:
+ * tables/unsupported/Lv-Lv-g1.utb:
+ * tables/unsupported/Makefile.am:
+ * tables/unsupported/Nl-Nl-g1.utb:
+ * tables/unsupported/No-No-g0.utb:
+ * tables/unsupported/No-No-g1.ctb:
+ * tables/unsupported/No-No-g2.ctb:
+ * tables/unsupported/No-No-g3.ctb:
+ * tables/unsupported/Pl-Pl-g1.utb:
+ * tables/unsupported/Pt-Pt-g1.utb:
+ * tables/unsupported/README:
+ * tables/unsupported/Se-Se-g1.utb:
+ * tables/unsupported/UEBC-g1.utb:
+ * tables/unsupported/UEBC-g2.ctb:
+ * tables/unsupported/ar-ar-g1.utb:
+ * tables/unsupported/chardefs.cti:
+ * tables/unsupported/countries.cti:
+ * tables/unsupported/cy-cy-g1.utb:
+ * tables/unsupported/cy-cy-g2.ctb:
+ * tables/unsupported/de-de-g0.utb:
+ * tables/unsupported/de-de-g1.ctb:
+ * tables/unsupported/de-de-g2.ctb:
+ * tables/unsupported/de-de.dis:
+ * tables/unsupported/en-GB-g2.ctb:
+ * tables/unsupported/en-gb-g1.utb:
+ * tables/unsupported/en-us-g1.utb:
+ * tables/unsupported/en-us-g2.ctb:
+ * tables/unsupported/errors:
+ * tables/unsupported/eurodefs.cti:
+ * tables/unsupported/fr-ca-g1.utb:
+ * tables/unsupported/fr-fr-g1.utb:
+ * tables/unsupported/gr-gr-g1.utb:
+ * tables/unsupported/hi-in-g1.utb:
+ * tables/unsupported/hyph_de_DE.dic:
+ * tables/unsupported/hyph_en_US.dic:
+ * tables/unsupported/hyph_es_ES.dic:
+ * tables/unsupported/hyph_fr_FR.dic:
+ * tables/unsupported/hyph_it_IT.dic:
+ * tables/unsupported/hyph_nl_NL.dic:
+ * tables/unsupported/hyph_no_NO.dic:
+ * tables/unsupported/hyph_pl_PL.dic:
+ * tables/unsupported/hyph_pt_PT.dic:
+ * tables/unsupported/hyph_sv_SE.dic:
+ * tables/unsupported/it-it-g1.utb:
+ * tables/unsupported/nl-be-g1.utb:
+ * tables/unsupported/no-no.dis:
+ * tables/unsupported/se-se.dis:
+ * tables/unsupported/text_nabcc.dis:
+ * tables/unsupported/ukchardefs.cti:
+ * tables/unsupported/uni-text.dis: Flattened tables directory,
+ all tables not live in basedir/tables.
+
+2008-01-16 Eitan Isaacson <eitan@ascender.com>
+
+ * README:
+ * doc/liblouis-guide.html:
+ * doc/liblouis-guide.txt:
+ * liblouis/compileTranslationTable.c:
+ * liblouis/lou_backTranslateString.c:
+ * liblouis/lou_translateString.c:
+ * tables/chardefs.cti: John's changes.
+ * configure.in: Bumped to version 1.3.41.
+
+ * liblouis/liblouis.h: Added an include to louiscfg.h for
+ character width.
+ * configure.in: Added --enable-ucs4 for 4 byte wide characters.
+ * liblouis/Makefile.am: Added louiscfg.h for installation.
+
+2008-01-03 Eitan Isaacson <eitan@ascender.com>
+
+ * configure.in: First autotooled version.
+
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..a05410f
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,29 @@
+FROM debian:jessie
+
+LABEL maintainer="Liblouis Maintainers <liblouis-liblouisxml@freelists.org>"
+
+# Fetch build dependencies
+RUN apt-get update && apt-get install -y \
+ autoconf \
+ automake \
+ curl \
+ libtool \
+ libyaml-dev \
+ make \
+ pkg-config \
+ python \
+ texinfo \
+ && rm -rf /var/lib/apt/lists/*
+
+# compile and install liblouis
+ADD . /usr/src/liblouis
+WORKDIR /usr/src/liblouis
+RUN ./autogen.sh && ./configure --enable-ucs4 && make && make install && ldconfig
+
+# install python bindings
+WORKDIR /usr/src/liblouis/python
+RUN python setup.py install
+
+# clean up
+WORKDIR /root
+RUN rm -rf /usr/src/liblouis
diff --git a/Dockerfile.dev b/Dockerfile.dev
new file mode 100644
index 0000000..a62bbb4
--- /dev/null
+++ b/Dockerfile.dev
@@ -0,0 +1,29 @@
+FROM debian:jessie
+
+MAINTAINER Liblouis Maintainers "liblouis-liblouisxml@freelists.org"
+
+# developer environment
+RUN apt-get update
+RUN apt-get install -y make autoconf automake libtool pkg-config curl
+
+# for cross-compiling
+RUN apt-get install -y mingw32 mingw-w64 libc6-dev-i386
+
+# for running cross-compiled tests
+RUN dpkg --add-architecture i386 && apt-get update && apt-get install -y wine32 wine64
+
+# for check_yaml
+WORKDIR /root/src/
+RUN curl -L https://github.com/yaml/libyaml/archive/0.2.2.tar.gz | tar zx
+WORKDIR /root/src/libyaml-0.2.2
+RUN ./bootstrap
+RUN ./configure --host i586-mingw32msvc --prefix=/root/build/win32/libyaml
+RUN make
+RUN make install
+
+ADD . /root/src/liblouis
+WORKDIR /root/src/liblouis
+
+# create Makefile
+RUN ./autogen.sh
+RUN ./configure
diff --git a/Doxyfile b/Doxyfile
new file mode 100644
index 0000000..ec92be6
--- /dev/null
+++ b/Doxyfile
@@ -0,0 +1,2453 @@
+# Doxyfile 1.8.13
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME = "Liblouis"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF = Braille Translation and Back-Translation Library
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = doc
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT = YES
+
+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
+# to that level are automatically included in the table of contents, even if
+# they do not have an id attribute.
+# Note: This feature currently applies only to Markdown headings.
+# Minimum value: 0, maximum value: 99, default value: 0.
+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
+
+TOC_INCLUDE_HEADINGS = 0
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = liblouis tools tests python
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
+# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
+
+FILE_PATTERNS = *.c \
+ *.h \
+ *.py
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# generated with the -Duse-libclang=ON option for CMake.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER =
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE = plain
+
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE =
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH =
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: YES.
+
+HAVE_DOT = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
+# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
+# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH =
+
+# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
+# configuration file for plantuml.
+
+PLANTUML_CFG_FILE =
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP = YES
diff --git a/HACKING b/HACKING
new file mode 100644
index 0000000..56d3bc6
--- /dev/null
+++ b/HACKING
@@ -0,0 +1,473 @@
+This HACKING file describes the development environment. -*- org -*-
+
+ Copyright (C) 2008, 2009, 2011 ViewPlus Technologies, Inc. and Abilitiessoft, Inc.
+ Copyright (C) 2012, 2013, 2014,2015 Swiss Library for the Blind, Visually Impaired and Print Disabled
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. This file is offered as-is,
+ without any warranty.
+
+This file attempts to describe the maintainer-specific notes to follow
+when hacking liblouis.
+
+* Table of Contents :TOC:
+- [[#developing][Developing]]
+ - [[#where-to-get-it][Where to get it]]
+ - [[#build-requirements][Build requirements]]
+ - [[#gnulib][Gnulib]]
+ - [[#how-to-build][How to build]]
+ - [[#install-with-homebrew][Install with Homebrew]]
+ - [[#docker][Docker]]
+ - [[#how-to-run-tests][How to run tests]]
+ - [[#how-to-debug][How to debug]]
+ - [[#how-to-find-memory-leaks][How to find memory leaks]]
+ - [[#static-analysis][Static analysis]]
+ - [[#how-to-analyze-performance][How to analyze performance]]
+ - [[#how-to-build-for-windows][How to build for Windows]]
+- [[#release-procedure][Release Procedure]]
+ - [[#update-the-news-entry][Update the NEWS entry]]
+ - [[#set-the-version-number][Set the version number]]
+ - [[#commit-and-tag][Commit and tag]]
+ - [[#make-the-release][Make the release]]
+ - [[#upload][Upload]]
+ - [[#online-documentation][Online documentation]]
+ - [[#web-site-maintenance][Web site maintenance]]
+ - [[#announce][Announce]]
+
+* Developing
+** Where to get it
+The development sources are available through git at github.com:
+
+ https://github.com/liblouis/liblouis
+
+** Build requirements
+To build Automake, Autoconf, and Libtool are used. If you are getting
+the sources from git (or change configure.ac), you'll need to have
+these tools installed to (re)build. Optionally (if you want to
+generate man pages) you'll also need ~help2man~. All of these programs
+are available from ftp://ftp.gnu.org/gnu.
+
+If you want to run the YAML based test suite you will have to install
+~libyaml~.
+
+On Mac OS, the programs can be optained with Homebrew (http://brew.sh):
+
+#+BEGIN_SRC shell
+$ brew install automake libtool pkg-config texinfo
+#+END_SRC
+
+Note that if you are using Homebrew to install liblouis (see below),
+the build dependencies are installed automatically.
+
+** Gnulib
+Gnulib (http://www.gnu.org/software/gnulib) is used to provide
+portable basic functionality to programs and libraries. We use two
+instances of gnulib, one to provide portable functions such as
+~malloc~, ~strndup~, etc to the library and another one to provide
+portable functionality such as ~getopt~, ~progname~ or
+~version-etc~ to the tools.
+
+The first time invocation to import gnulib for the library was
+
+#+BEGIN_SRC shell
+$ gnulib-tool --add-import --lib=libgnu --source-base=gnulib \
+ --m4-base=gnulib/m4 --aux-dir=build-aux --libtool \
+ --macro-prefix=gl --no-vc-files \
+ malloc-gnu realloc-gnu strndup
+#+END_SRC
+
+and for the tools
+
+#+BEGIN_SRC shell
+$ gnulib-tool --add-import --lib=libgnutools --source-base=tools/gnulib \
+ --m4-base=tools/gnulib/m4 --aux-dir=build-aux --libtool \
+ --macro-prefix=gl_tools --no-vc-files \
+ getopt-gnu malloc-gnu progname version-etc
+#+END_SRC
+
+More modules might have been added since. The currently-used gnulib
+modules and other gnulib information are recorded in
+~gnulib/m4/gnulib-cache.m4~ and ~tools/gnulib/m4/gnulib-cache.m4~.
+
+If you want to update from the current gnulib, install gnulib, and
+then run the following commands in the top-level directory.
+
+#+BEGIN_SRC shell
+$ gnulib-tool --add-import --lib=libgnu --source-base=gnulib \
+ --m4-base=gnulib/m4 --aux-dir=build-aux --libtool \
+ --macro-prefix=gl --no-vc-files
+$ gnulib-tool --add-import --lib=libgnutools --source-base=tools/gnulib \
+ --m4-base=tools/gnulib/m4 --aux-dir=build-aux --libtool \
+ --macro-prefix=gl_tools --no-vc-files
+#+END_SRC
+
+** How to build
+After getting the sources from git, with
+
+#+BEGIN_SRC shell
+$ git clone https://github.com/liblouis/liblouis.git
+#+END_SRC
+
+and installing the tools above, change to the liblouis directory and
+and bootstrap the project with the following command
+
+#+BEGIN_SRC shell
+$ ./autogen.sh
+#+END_SRC
+
+to do a fresh build. Then run configure as usual:
+
+#+BEGIN_SRC shell
+$ ./configure
+#+END_SRC
+
+You have the choice to compile liblouis for either 16- or 32-bit
+Unicode. By default it is compiled for the former. To get 32-bit
+Unicode run configure with ~--enable-ucs4~.
+
+After running configure run ~make~ and then ~make install~. You must
+have root privileges for the installation step.
+
+** Install with Homebrew
+Homebrew (http://brew.sh) is a package manager for Mac OS X that
+installs software from source. There is nothing special about the
+installation process in the sense that under the hood it happens
+exactly as described above, with the only difference that Homebrew
+automates it completely.
+
+First, use the ~brew tap~ command to add the repository that includes
+the liblouis formula:
+
+#+BEGIN_SRC shell
+$ brew tap liblouis/liblouis
+#+END_SRC
+
+Now you are ready to install liblouis:
+
+#+BEGIN_SRC shell
+$ brew install liblouis
+#+END_SRC
+
+** Docker
+Docker (https://www.docker.com) can be useful both for creating a
+development environment for liblouis, and for shipping the
+application.
+
+Setting up a developer environment can take long and can be
+problematic especially for Windows. Thanks to Docker we can set up the
+environment for you, we can easily distribute it as an image, which
+can be run by anybody and will behave exactly the same for everybody.
+
+Docker images of liblouis are being built automatically each time
+something changes in the code (see https://registry.hub.docker.com/repos/liblouis).
+In order to use them, first get Docker at
+http://docs.docker.com/introduction/get-docker. Download the latest
+liblouis image with:
+
+#+BEGIN_SRC shell
+$ docker pull liblouis/liblouis
+#+END_SRC
+
+Then, enter the development environment by running the image in a
+Docker container:
+
+#+BEGIN_SRC shell
+$ docker run -it liblouis/liblouis bash
+#+END_SRC
+
+Local files and directories can be "mounted" inside the container, in
+order to make it easier to edit files and to persist changes across
+runs. For example, to use local table files:
+
+#+BEGIN_SRC shell
+$ docker run -it -v $(pwd)/tables:/tmp/liblouis/tables liblouis/liblouis bash
+#+END_SRC
+
+See the Docker documentation for more info.
+
+The same Docker image can be used as a development environment and as
+the application itself. For example, to run the lou_translate tool
+from inside a Docker container:
+
+#+BEGIN_SRC shell
+$ docker run -it liblouis/liblouis lou_translate en-us-g1.ctb
+#+END_SRC
+
+To rebuild the image yourself, run the following command in the root
+directory of the liblouis source:
+
+#+BEGIN_SRC shell
+$ docker build -t liblouis/liblouis .
+#+END_SRC
+
+A ~.dockerignore~ file is required if you want to compile the source
+both on te host and in the Docker container. The ~.dockerignore~ file
+can be updated from ~.gitignore~ with:
+
+#+BEGIN_SRC shell
+$ make .dockerignore
+#+END_SRC
+
+** How to run tests
+Tests are run with
+
+#+BEGIN_SRC shell
+$ make check
+#+END_SRC
+
+** How to debug
+First you have to build liblouis with debugging info enabled.
+
+#+BEGIN_SRC shell
+$ ./configure CFLAGS='-g -O0 -Wall -Wextra'
+$ make
+#+END_SRC
+
+Starting the programs under the tools directory within gdb is a little
+tricky as they are linked with libtool. See the info page of libtool
+for more information. To start ~lou_checktable~ for table
+~wiskunde.ctb~ for example you'd have to issue the following commands:
+
+#+BEGIN_SRC shell
+$ libtool --mode=execute gdb ./tools/lou_checktable
+(gdb) run tables/wiskunde.ctb
+#+END_SRC
+
+** How to find memory leaks
+Valgrind is a tool that can be used to find memory errors. It is
+recommended that you compile liblouis without any optimizations and
+with all warnings enabled before running it through Valgrind:
+
+#+BEGIN_SRC shell
+$ ./configure CFLAGS='-g -O0 -Wall'
+$ make
+#+END_SRC
+
+Then use Valgrind to analyze liblouis. For example you can run
+~lou_translate~ trough Valgrind:
+
+#+BEGIN_SRC shell
+$ libtool --mode=execute valgrind -v --tool=memcheck \
+ --leak-check=full --leak-resolution=high --log-file=valgrind.log \
+ ./tools/lou_translate en-us-g2.ctb
+#+END_SRC
+
+Type a few words at the prompt, check translation and terminate
+~lou_translate~. Now open the file ~valgrind.log~ and see if there are
+any memory leaks reported.
+
+You can also just run lou_checktable for example:
+
+#+BEGIN_SRC shell
+$ libtool --mode=execute valgrind -v --tool=memcheck \
+ --leak-check=full --leak-resolution=high --log-file=valgrind.log \
+ ./tools/lou_checktable tables/nl-BE-g0.utb
+#+END_SRC
+
+Again open valgrind.log to see if any memory leaks were reported.
+
+For the full experience run lou_allround under Valgrind:
+
+#+BEGIN_SRC shell
+$ libtool --mode=execute valgrind -v --tool=memcheck \
+ --leak-check=full --show-reachable=yes \
+ --leak-resolution=high --track-origins=yes \
+ --log-file=valgrind.log ./tools/lou_allround
+#+END_SRC
+
+*** AddressSanitizer
+[[https://github.com/google/sanitizers/wiki/AddressSanitizer][AdressSanitizer]] is a memory error detector for C/C++. It is part of
+both LLVM and gcc. To check liblouis build it as follows:
+
+#+BEGIN_SRC shell
+$ ./autogen.sh
+$ ./configure CFLAGS='-fsanitize=address -O1 -fno-omit-frame-pointer -g'
+$ make
+$ ./tools/lou_translate tables/en-ueb-g2.ctb
+#+END_SRC
+
+Run a few translations, end the program and marvel at the output of
+AddressSanitizer. At the time of this writing it complained pretty
+hard:
+
+#+BEGIN_EXAMPLE
+SUMMARY: AddressSanitizer: 12384 byte(s) leaked in 12 allocation(s).
+#+END_EXAMPLE
+
+*** Electric Fence
+Electric Fence is a tool that helps detect memory access that overruns
+the boundaries of a ~malloc()~ memory allocation, and access to memory
+that has been released with ~free()~.
+
+Under Debian the usage is fairly straightforward:
+
+#+BEGIN_SRC shell
+$ sudo apt install sudo apt install electric-fence
+#+END_SRC
+
+Then compile [[#how-to-debug][as above]] and invoke the debugger [[#how-to-debug][as above]]. Inside ~gdb~
+set up ~LOUIS_TABLEPATH~ and ~LD_PRELOAD~ as follows:
+
+#+BEGIN_SRC shell
+$ libtool --mode=execute gdb ./tools/lou_allround
+(gdb) set environment LOUIS_TABLEPATH ./tables,./tests/tables,./tests/tables/moreTables,./tests/tablesWithMetadata,./tests/tables/emphclass
+(gdb) set environment LD_PRELOAD /usr/lib/libefence.so.0.0
+(gdb) run
+#+END_SRC
+
+If there are problems with memory access the program will run into a
+segmentation fault which you can consequently analyze in the debugger.
+
+** Static analysis
+[[http://clang-analyzer.llvm.org/scan-build.html][scan-build]] is a command line utility to run a static analyzer over the
+codebase. It helps to find problems such as memory leaks, dereference
+of null pointer, etc.
+
+#+BEGIN_SRC shell
+$ make maintainer-clean
+$ ./autogen.sh
+$ scan-build ./configure
+$ scan-build make
+...
+scan-build: 101 bugs found.
+scan-build: Run 'scan-view /tmp/scan-build-2019-08-15-141827-5185-1' to examine bug reports.
+#+END_SRC
+
+then look at the generated reports and fix (or report) the issues.
+
+** How to analyze performance
+Gprof helps you analyze the performance of programs. You have to
+compile liblouis as follows:
+
+#+BEGIN_SRC shell
+$ ./configure --disable-shared
+$ make clean all CFLAGS='-g -O0 -pg' LDFLAGS='-all-static'
+#+END_SRC
+
+Then translate some stuff with a large table:
+
+#+BEGIN_SRC shell
+$ ./tools/lou_translate tests/tables/large.ctb
+#+END_SRC
+
+Finally look at the call profile:
+
+#+BEGIN_SRC shell
+$ libtool --mode=execute gprof ./tools/lou_translate gmon.out
+#+END_SRC
+
+** How to build for Windows
+See the ~README.windows~ file and the windows subdirectory.
+
+*** How to cross-compile for Windows
+To compile for win32, use the MinGW win32 cross-compiler as shown
+below. Use the prefix option to install the binaries to a temporary
+place where you can create a zip file. The ~LDFLAGS='-all-static'~
+ensures that libgcc is linked in statically. Otherwise the users need
+to have ~libgcc_s_sjlj-1.dll~.
+
+Some users want the dlls unversioned. To achieve that add
+~-avoid-version~ to ~LDFLAGS~.
+
+#+BEGIN_SRC shell
+$ ./configure --build=i686-pc-linux-gnu --host=i686-w64-mingw32 --prefix=/tmp/liblouis-mingw32
+$ make LDFLAGS='-avoid-version -Xcompiler -static-libgcc'
+$ make install
+$ zip -r liblouis-mingw32msvc.zip /tmp/liblouis-mingw32
+#+END_SRC
+
+To compile for win64, use the MinGW-w64 cross-compiler:
+
+#+BEGIN_SRC shell
+$ ./configure --build=i686-pc-linux-gnu --host=x86_64-w64-mingw32 --prefix=/tmp/liblouis-w64-mingw32
+$ make LDFLAGS='-avoid-version -Xcompiler -static-libgcc'
+$ make install
+$ zip -r liblouis-w64-mingw32.zip /tmp/liblouis-w64-mingw32
+#+END_SRC
+
+Two makefile rules have been provided to do this automatically for you. Docker will be used if the
+right cross-compiler is not installed. To compile for win32 using the MinGW cross-compiler, run ~make
+distwin32~. This will produce a ZIP file called ~liblouis-<version>-win32.zip~. To compile for win64
+using the MinGW-w64 cross-compiler, run ~make distwin64~. This will produce a ZIP file called
+~liblouis-<version>-win64.zip~.
+
+*** TODO How to build for Windows using Cygwin
+(possibly use a Vagrantfile as demonstration + explain that Cygwin
+binaries can not be used outside the Cygwin environment)
+
+*** TODO How to build for Windows using MinGW
+(possibly use a Vagrant file as demonstration)
+
+* Release Procedure
+These steps describe what a maintainer does to make a release; they
+are not needed for ordinary patch submission.
+
+** Update the NEWS entry
+If any new tables were added, renamed or removed please note them with
+their file name in the NEWS entry. This is usefull for projects like
+NVDA.
+
+** Set the version number
+Update the version number in ~NEWS~ (with version, date, and release
+type), ~configure.ac~ and ~windows/include/config.h~.
+
+Don't forget to update the libtool versioning info in ~configure.ac~,
+i.e. ~LIBLOUIS_REVISION~ and possibly ~LIBLOUIS_CURRENT~ and
+~LIBLOUIS_AGE~. Check the [[https://www.gnu.org/software/libtool/manual/html_node/Interfaces.html#Interfaces][libtool documentation on versioning]] for an
+explanation of these values.
+
+** Commit and tag
+Commit the changes and tag this version
+
+#+BEGIN_SRC shell
+$ git tag -s v2.6.0 -m "Release 2.6.0"
+$ git push origin v2.6.0
+#+END_SRC
+
+If you know the exact version number that needs to be tagged use
+
+#+BEGIN_SRC shell
+$ git tag -s v2.6.0 -m "Release 2.6.0" <commit>
+$ git push origin v2.6.0
+#+END_SRC
+
+** Make the release
+Check out a clean copy in a different directory, like /tmp. Run
+autogen.sh and configure with no special prefixes. Run make distcheck.
+This will make sure that all needed files are present, and do a
+general sanity check. Run make dist. This will produce a tarball.
+
+#+BEGIN_SRC shell
+$ ./autogen.sh && ./configure && make && make distcheck && make dist
+#+END_SRC
+
+** Upload
+Add the tarball to the github liblouis releases page, i.e. add it
+under https://github.com/liblouis/liblouis/releases with the specific
+release and add a link to it in $WEBSITE/downloads/index.md. See below
+for instructions on how to update the web site.
+
+** Online documentation
+The online documentation is part of the liblouis web site. To add it to the
+site simply copy doc/liblouis.html to $WEBSITE/documentation/liblouis.html.
+Make sure you add the proper YAML front matter. Again see below for
+instructions on how to update the web site.
+
+** Web site maintenance
+The liblouis web site at liblouis.org is maintained with the help of
+[[https://pages.github.com/][github pages]]. To edit the site just check out the repo at
+https://github.com/liblouis/liblouis.github.io. You'll need to know a
+few things about [[http://jekyllrb.com/][Jekyll]] and markdown, the markup that is used to edit
+the content. In order to update the site simply edit, commit and push.
+
+For the new release update the project web site.
+
+- Add a post containing the current NEWS to the _posts directory and
+- add the download artifacts to the download page
+
+** Announce
+Send an announcement to the liblouis list
+~liblouis-liblouisxml@freelists.org~. See ~ANNOUNCEMENT~ for an
+example.
+
diff --git a/License.md b/License.md
new file mode 100644
index 0000000..19e3071
--- /dev/null
+++ b/License.md
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+(This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.)
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ {description}
+ Copyright (C) {year} {fullname}
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random
+ Hacker.
+
+ {signature of Ty Coon}, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..f2cf8ad
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,64 @@
+SUBDIRS = gnulib liblouis tools tables man tests python windows
+
+# only build the documentation if we have makeinfo 5
+if HAVE_MAKEINFO_5
+SUBDIRS += doc
+endif
+
+ACLOCAL_AMFLAGS = -I m4 -I gnulib/m4 -I tools/gnulib/m4
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = liblouis.pc
+
+EXTRA_DIST = liblouis.pc README.windows HACKING
+
+distwin32 : distwin32-zip
+
+distwin32-zip : distwin32-dir
+ rm -f liblouis-$(VERSION)-win32.zip
+ zip -r liblouis-$(VERSION)-win32.zip liblouis-$(VERSION)-win32
+
+distwin32-dir :
+ rm -rf liblouis-$(VERSION)-win32/*
+ @if which i586-mingw32msvc-gcc >/dev/null; then \
+ ./configure --host i586-mingw32msvc --prefix=$(CURDIR)/liblouis-$(VERSION)-win32 && \
+ make LDFLAGS="$$LDFLAGS -avoid-version -Xcompiler -static-libgcc" && \
+ make check WINE=wine32&& \
+ make install; \
+ elif which i686-w64-mingw32-gcc >/dev/null; then \
+ ./configure --host i686-w64-mingw32 --prefix=$(CURDIR)/liblouis-$(VERSION)-win32 && \
+ make LDFLAGS="$$LDFLAGS -avoid-version -Xcompiler -static-libgcc" && \
+ make install; \
+ elif which docker >/dev/null; then \
+ gtar --transform='s/Dockerfile.dev/Dockerfile/' --exclude-from=.dockerignore -cz * | docker build -t liblouis-dev - && \
+ mkdir -p liblouis-$(VERSION)-win32 && \
+ docker run --rm -v $(CURDIR)/liblouis-$(VERSION)-win32:/root/src/liblouis/liblouis-$(VERSION)-win32 liblouis-dev \
+ make CPPFLAGS='-I/root/build/win32/libyaml/include/' \
+ LDFLAGS='-L/root/build/win32/libyaml/lib/' \
+ distwin32-dir; \
+ fi
+
+distwin64 : distwin64-zip
+
+distwin64-zip : distwin64-dir
+ rm -f liblouis-$(VERSION)-win64.zip
+ zip -r liblouis-$(VERSION)-win64.zip liblouis-$(VERSION)-win64
+
+distwin64-dir :
+ rm -rf liblouis-$(VERSION)-win64/*
+ @if which x86_64-w64-mingw32-gcc >/dev/null; then \
+ ./configure --host x86_64-w64-mingw32 --prefix=$(CURDIR)/liblouis-$(VERSION)-win64 && \
+ make LDFLAGS='-avoid-version -Xcompiler -static-libgcc' && \
+ make check WINE=wine64&& \
+ make install; \
+ elif which docker >/dev/null; then \
+ gtar --transform='s/Dockerfile.dev/Dockerfile/' --exclude-from=.dockerignore -cz * | docker build -t liblouis-dev - && \
+ mkdir -p liblouis-$(VERSION)-win64 && \
+ docker run --rm -v $(CURDIR)/liblouis-$(VERSION)-win64:/root/src/liblouis/liblouis-$(VERSION)-win64 liblouis-dev \
+ make distwin64-dir; \
+ fi
+
+# .dockerignore
+.dockerignore : .gitignore
+ sed -e 's|^\([^/#]\)|# \1|' -e 's|^/||' -e 's|\+|\\+|g' $< >$@
+
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..1494b8b
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,2060 @@
+liblouis NEWS -- history of user-visible changes. -*- org -*-
+
+* Noteworthy changes in release 3.12.0 (2019-12-02)
+This release contains major updates to the UEB, Afrikaans, Chinese,
+Danish and Polish tables. Aside from that there have been many code
+cleanups, such as the elimination of many global vars and bug fixes
+such as an endless loop or a crash in ~lou_translate~.
+
+For a detailed list of all the changes refer to [[https://github.com/liblouis/liblouis/milestone/22?closed=1][the list of closed
+issues]].
+
+** New features
+None
+** Bug fixes
+- Fix a memory leak when several tables are specified and some of them
+ that can't be resolved. Thanks to André-Abush Clause.
+- Fix an endless loop with multipass rules where ~endReplace~ is
+ smaller or equal to ~startMatch~. Thanks to Bert Frees and Bue
+ Vester-Andersen.
+** Braille table improvements
+- Punctuation corrections in Ethiopic Braille thanks to Dr. Tamru E.
+ Belay.
+- Fixes to the Norwegian 8dot braille table in regards to 4 Sami
+ characters, capital and small letters S and Z with caron. Thanks to
+ Oddvar Øyan and Lars Bjørndal.
+- Improvements to Afrikaans contracted braille thanks to Christo de Klerk
+ - Over 50 cases have been corrected where braille rules were not
+ correctly applied in words, mainly in those cases where
+ contractions depend on pronunciation; for example, ui or ie must
+ not be contracted in requiem.
+ - Corrected contraction errors caused by start or end of input not
+ properly taken into account.
+ - Words are no longer contracted into lower word contractions when
+ they are adjacent to lower punctuation, for example: "hier.
+ - Words are now contracted into their lower contractions when they
+ are adjacent to upper punctuation, for example: (hier.
+- New draft table for Dutch 8-dot computer braille thanks to Leonard
+ de Ruijter.
+- Updates to the Chinese braille table (~zh-tw.ctb~) thanks to
+ Bo-Cheng Jhan, Coscell Kao, 特種兵, 黃偉豪, and Victor Cai.
+- Fixes to Polish grade 1, thanks to Łukasz Golonka
+ - Removes some unneeded ~midnum~ symbols from the Polish Grade 1.
+ - Fixes some symbols which weren't defined according to the
+ specification.
+ - Makes it possible to type dot from a braille keyboard.
+ - Adds Greek letters and some commonly used math operators to both
+ the Grade 1 and the computer braille table.
+- Fix several conflicts in ~fr-bfu-comp68.cti~ with regards to the IPA
+ Unicode range. These had been especially noticed when
+ ~compbrlAtCursor~ mode flag was used. Thanks to André-Abush Clause.
+- Major Improvements to contraction use in UEB thanks to James Bowden.
+- Updates to the Danish Tables thanks to Bue Vester-Andersen:
+ - Added miscelaneous Unicode characters to 8 dots grade 1 and 2
+ (accented letters, punctuation, arrows and some math signs).
+ Most of these characters have not been defined in the Danish
+ Braille standard. This implementation is purely experimental,
+ and the characters may be changed later.
+ - Updated the 6 dots tables with more Unicode characters
+ (no arrows or math signs).
+ - Corrected a bug in 8 dots grade 2, which resulted in the
+ "var" contraction not always being properly applied.
+** Other changes
+- Make sure the log callback uses the same calling convention as all
+ the other exported functions. Thanks to Leonard de Ruijter.
+- Fix a problem with Non-ASCII characters in file paths in the Python
+ bindings, thanks to André-Abush Clause.
+- Eliminate some of the globals variables thanks to Bert Frees.
+- The display and the translation are now separated at least
+ internally, thanks to Bert Frees. As a reminder, there are two
+ phases to a braille conversion:
+ - translation :: liblouis uses the rules in the translation table to
+ convert characters to dots
+ - display :: display the dots as characters. Usually liblouis uses
+ the characters defined in display rules (in display
+ tables) but as a fallback it uses mappings defined in
+ the translation table, e.g. letter rules.
+- No longer install ~lou_compare~, a tool that is used to run
+ regression tests for UEB. As it is only run during testing it will
+ no longer be installed by default on a users machine.
+- Remove a hidden feature of ~lou_translate~ that would cause it to
+ crash if passed an invalid file name. Thanks to Christian Egli.
+- Raise an error if a dot pattern can not be displayed instead of
+ silently ignoring it thanks to Bert Frees.
+** Deprecation notice
+None
+
+** Backwards incompatible changes
+None
+
+** Invisible changes
+
+** New, renamed or removed tables
+*** New
+- nl-comp8.utb
+
+*** Renamed
+None
+
+*** Removed
+None
+
+* Noteworthy changes in release 3.11.0 (2019-09-02)
+A tremendous amount of work by Dave Mielke and Bert Frees has gone
+into this release. They have improved liblouis for use on note taker
+devices, for backwards translation and a number of languages. Many
+other contributors (listed below) have also helped in fixing bugs and
+improving braille tables, such as Dutch, Mongolian, Polish, Ancient
+Greek, Danish, Irish, Chinese, and American Braille Computer Code.
+
+For a detailed list of all the changes refer to [[https://github.com/liblouis/liblouis/milestone/21?closed=1][the list of closed
+issues]].
+
+** New features
+- Enable ~always~ rules with a single character and a single braille
+ cell for back-translation. Thanks to Bue Vester-Andersen.
+- Implement ~noUndefined~ mode for forward translation, thanks to Dave
+ Mielke.
+- Use fallback braille representations (NABCC) for rendering undefined
+ characters in hexadecimal notation, thanks to Dave Mielke.
+- Always render undefined characters, also ASCII characters, in
+ hexadecimal notation.
+- Add a new metadata field ~index-name~ for selecting a table from a
+ list fast and efficiently. It has the most important information
+ first and no redundant information. It should look nice when sorted.
+ This in contrast to the existing ~display-name~ field which is for
+ describing a table accurately and should sound good. Thanks to Dave
+ Mielke and Bert Frees.
+
+** Bug fixes
+- Don't let a caps passage end on a word with no letters. Thanks to
+ Bert Frees.
+- Handle word resets in the last word of an caps or emphasis passage
+ if the end indicator was placed before the word. Thanks to Bert
+ Frees.
+- Never convert to lowercase if ~capsletter~ is not defined. Thanks to
+ Bert Frees.
+- Fix position mapping for back-translation when ~noUndefined~ mode is
+ active. Thanks to Dave Mielke.
+- Fix bug where a translation would hang on words that match both a
+ ~nocont~ and a ~repeated~ rule. Thanks to Dave Mielke.
+- Fix bug where the effect of ~capsnocont~ would leak to the next word
+ if that word starts with a capital. Thanks to Bue Vester-Andersen.
+
+** Braille table improvements
+- Fix an issue with ordinal numbers inside caps passages in Dutch
+ braille. Thanks to Bert Frees.
+- Improved back-translation for Mongolian thanks to Angaragerdene.
+- Fixes to Polish grade 1 and Polish computer braille thanks to Łukasz
+ Golonka.
+- Improvements to Ancient Greek braille, which has been renamed "Greek
+ international braille". A version with composed accents is made
+ available as a .uti table. Thanks to Dave Mielke and Μαρια
+ Γεωργακαράκου (Maria Georgakarakou).
+- Various improvements to modern Greek thanks to Dave Mielke.
+- Improvements and fixes to Spanish contracted braille. Details in
+ #741. Thanks to Juan Pablo Bello.
+- Improvements and fixes to the Danish tables. Thanks to Bue
+ Vester-Andersen.
+- Add a display table to match Word CX which is used in Norway and
+ Sweden, and maybe also in other countries thanks to Lars Bjørndal.
+- Fix handling of colon within number in Dutch braille, thanks to Jake
+ Kyle.
+- Fix translation of bullet and dot operators in Dutch braille, thanks
+ to Paul Rambags
+- Added North American Braille Computer Code table (~en-nabcc.utb~)
+ which is the counterpart of the ~text_nabcc.dis~ display table.
+ Thanks to Dave Mielke.
+- Add support for the International Phonetic Alphabet (IPA) to the
+ Chinese bopomofo braille table, thanks to Hurt Huang and Sponge
+ Jhan. Various improvements, including dot patterns and test cases, to
+ the Chinese bopomofo braille table, thanks to Sponge Jhan.
+- Unified English Braille no longer displays a single underscore when
+ multiple underscores are in the text, thanks to André-Abush Clause.
+- Update to Afrikaans uncontracted braille and new table for contracted
+ braille. Thanks to Christo de Klerk and Greg Kearney.
+- Update Irish braille (contracted and uncontracted) to the May 2019
+ version of the specification, thanks to Ronan McGuirk
+
+** Other changes
+- The python wrapper now encodes and decodes strings to/from UTF-16
+ and UTF-32 using the surrogatepass error handler. This ensures that
+ single UTF-16 surrogate characters are processed correctly by the
+ wrapper and don't raise an encoding/decoding error. Thanks to
+ Leonard de Ruijter.
+- Metadata keys and values are now case insensitive, thanks to Dave
+ Mielke.
+- Remove ~unicodedefs.cti~. It was obsolete and never meant to be
+ included by any tables. Instead use the online references as
+ mentioned in the documentation now. See also #696.
+- ~lou_checkyaml~ test reporting has been improved, thanks to Bert
+ Frees. For example it now has a ~--verbose~ option so that printing
+ of expected failures can be enabled.
+- Hyphenation tables have been removed from tables except those needed
+ for ~nocross~ rules, thanks to Bert Frees.
+
+ The idea is that the caller (for example ~odt2braille~ or
+ ~liblouisutdml~) should be able to decide for themselves which
+ hyphenation table to use. The case in which a table contains nocross
+ rules is an exception. In this case the hyphenation patterns are a
+ real part of the table. Because it is not recommended to append an
+ own hyphenation table in this case, a ~#-has-nocross~ metadata field
+ was added to indicate that a table contains nocross rules.
+- ~lou_hyphenate~ can now handle more than just words (sequences of
+ letters), e.g compound words, thanks to Bert Frees.
+
+** Deprecation notice
+- The ~noUndefinedDots~ mode has been renamed to ~noUndefined~. For
+ backwards compatibility ~noUndefinedDots~ is still available in the
+ header file and in the Python bindings, as an alias for
+ ~noUndefined~.
+
+** Backwards incompatible changes
+None
+
+** Invisible changes
+ - Internally separate more clearly the display and translation
+ phases.
+
+** New, renamed or removed tables
+*** New
+- grc-international-common.uti
+- grc-international-composed.uti
+- grc-international-decomposed.uti
+- en-nabcc.utb
+
+*** Renamed
+- gr-bb.ctb -> grc-international-en.utb
+
+*** Removed
+- unicodedefs.cti
+- fi-fi.ctb
+
+* Noteworthy changes in release 3.10.0 (2019-06-03)
+This release comes across as quiet, containing just the usual
+assortment of braille table improvements, cleanups, bug fixes and the
+classic buffer overflow patches. But beware, a lot has happened behind
+the scenes. Bert and Davy have been adding a new opcode to handle
+special emphasis situations. A number of annoying restrictions with
+regards to names, such as class names have been removed thank to Bert.
+And lastly also thanks to Bert it is now possible to define inline
+display tables in your YAML tests.
+
+For a detailed list of all the changes refer to [[https://github.com/liblouis/liblouis/milestone/20?closed=1][the list of closed
+issues]].
+
+** New features
+- Add a new opcode ~emphmodechars~. Thanks to Bert Frees and Davy
+ Kager.
+
+** Bug fixes
+- Remove memoization in ~checkAttr~. It wasn't implemented correctly,
+ caused some weird bugs and probably didn't do much for performance.
+ Thanks to Bert Frees.
+- Fix multiple buffer overflows in ~compilePassOpcode~. Thanks to
+ Cheng Wen for the report and to Christian Egli for the fix.
+- Fix a build problem when building without libyaml thanks to Bert
+ Frees.
+
+** Braille table improvements
+- Added modified letters to UEB thanks to Mike Gray.
+- Complete overhaul of the U.S. six-dot computer braille tables to
+ align with the CBC standard thanks to Timothy Wynn. There is now a
+ sub-table for EBAE (~en-us-compbrl.uti~) and a stand-alone table
+ (~en-us-comp6.ctb~).
+ - Conforms to the CBC standard from BANA for character definitions
+ that differ from the 8-dot ASCII braille (11 punctuation marks).
+ - Added rules for braille indicators, emphasis indicators, and
+ isolated lower-cell signs to the stand-alone table.
+ - Uncontracted and contracted EBAE tables no longer use dot 7 when
+ in computer braille mode.
+ - ~en-us-compbrl.ctb~ was deleted because it was identical to
+ ~en-us-comp6.ctb~.
+- Update Bopomofo-based Chinese Braille thanks to Sponge Jhan
+ - Correct various dot patterns of Chinese characters.
+ - Add more known pattern exceptions of Chinese characters.
+ - Apply ~word~ opcode to 倔 and 据.
+ - Change dot pattern of & to 456-12346.
+- ~de-de-comp8.ctb~ now has definitions for musical Unicode characters
+ thanks to Daniel Mayr
+- Emphasis improvements in Unified French 6 dots Braille thanks to
+ Ludovic Oger.
+- Improvements to Unified English braille, Grade 2 thanks to James
+ Datray from Freedom Scientific.
+- Numerous back-translation fixes to Grade 2 of UK English and Unified
+ English Braille thanks to Anthony Tibbs.
+- Updates to Dutch Braille thanks to Bert Frees
+ - Hyphen cancels the effect of emphasis indicator
+ - Left/right curly brackets
+ - Write currency symbols in full if they come after the number
+
+** Other changes
+- Remove various restrictions on which characters and braille cells
+ can be used in translation rules, thanks to Bert Frees.
+- Remove some code duplication in ~pattern.c~ thanks to Bert Frees
+- It is now also possible to define inline tables when a display table
+ has been defined thanks to Bert Frees
+- Nightly snapshots of liblouis are now also built for win64 thanks to
+ Bert Frees
+
+** Deprecation notice
+None
+
+** Backwards incompatible changes
+None
+
+** New, renamed or removed tables
+*** New
+- en-us-compbrl.uti
+
+*** Renamed
+- chardefs.cti -> en-chardefs.cti
+
+*** Removed
+- en-us-compbrl.ctb
+
+* Noteworthy changes in release 3.9.0 (2019-03-04)
+This release has seen a tremendous amount of work by Bert Frees. He
+was instrumental in pushing the improvements for Latvian, Norwegian
+and Slovenian. But most prominently he pushed the big change for space
+and control character handling through the door. These characters are
+now no longer hard coded in liblouis. This should solve a few long
+standing issues. Other than that there is the usual assortment of code
+improvements and cleanups.
+
+For a detailed list of all the changes refer to [[https://github.com/liblouis/liblouis/milestone/19?closed=1][the list of closed
+issues]].
+
+** New features
+- None
+
+** Bug fixes
+- Fix a problem in the callback registration in the Python bindings
+ thanks to Leonard de Ruijter.
+- Fixed memory leaks created by block scope compound literals thanks
+ to Martin Gieseking.
+- The hard coded rules dealing with white space have been replaced
+ with a normal table that is included in all tables. This fixes a
+ number of bugs to do with space and control characters. This (big)
+ change has been brewing for a couple of releases and has finally
+ landed. Thanks to Christian Egli and Bert Frees.
+
+** Braille table improvements
+- Major extension of the German 8 dot computer braille table thanks to
+ Ali-Riza Ciftcioglu. For example the Euro sign or quote characters
+ are finally defined.
+- Fix a few issues with Hungarian grade1 and grade2 Braille thanks to
+ Attila Hammer.
+- Various improvements to Norwegian thanks to Lars Bjørndal, Jostein
+ Austvik Jacobsen, Ammar Usama and Bert Frees.
+- Updates to Bopomofo-based Chinese Braille thanks to Sponge Jhan:
+ Improved Braille representation of Chinese characters, and rewritten
+ Kana rules using multipass statements.
+- Implement the new Slovenian Braille standard thanks to Robert Merič
+ and Bert Frees.
+- Updates to Latvian Grade 1 Braille thanks to Artis Raugulis and Bert
+ Frees.
+- Fixes to English, U.S. Grade 2 (ABAE) thanks to jdatray.
+
+** Other changes
+- Don't search for tables in ~/usr/local/share/liblouis/tables~ (or
+ the Windows equivalent) if ~LOUIS_TABLEPATH~ is set.
+- The log levels in ~liblouis.h~ are no longer exposed as ~LOG_FOO~
+ but instead are now prefixed. So ~LOG_WARN~ becomes ~LOU_LOG_WARN~
+ for example to issue a warning from a C program using liblouis. The
+ actual values remain the same, so the ABI remains stable.
+
+** Deprecation notice
+- The ~locale~ opcode was never implemented and was just silently
+ ignored. It is now removed from the tables and a warning will be
+ issued if it is found in a table.
+
+** Backwards incompatible changes
+
+** New, renamed or removed tables
+*** New
+- None
+
+*** Renamed
+- spaces.ctb -> spaces.uti
+
+*** Removed
+- None
+
+* Noteworthy changes in release 3.8.0 (2018-12-03)
+The major focus of this release is on braille table updates. There are
+major updates to German, Arabic, Chinese, Turkish, Dutch, Czech,
+Latvian, Spanish and Ethiopic. Some of these new tables have only been
+possible because Bert Frees fixed some nasty long standing bugs behind
+the scene. Also there is the usual assortment of code improvements and
+cleanups.
+
+For a detailed list of all the changes refer to [[https://github.com/liblouis/liblouis/milestone/18?closed=1][the list of closed
+issues]].
+
+** New features
+- None
+
+** Bug fixes
+- Fix support more than 4 classes thanks to Bert Frees.
+- Fix capitalization of words that match ~nocont~ rules thanks to Bert
+ Frees.
+
+** Braille table improvements
+- Defined the undefined character for the Czech tables thanks to Jan
+ Hegr.
+- Improvements to Unified English braille thanks to Mike Gray
+- Updated the Dutch table to the new 2017.1 braille standard thanks to
+ Davy Kager.
+- Improvements to the Polish grade 1 table, to make back-translations
+ of diacritics working
+- Fixes to Latvian braille table thanks to Gatis Grintals and Artis
+ Raugulis.
+- Improvements to traditional Mainland Chinese braille and two-cell
+ Chinese Braille thanks to Sunian Loomee.
+- Update Bopomofo-based Chinese Braille to version 2018-11 thanks to
+ Bo-Cheng Jhan
+ - Correct the default braille pattern of many Chinese characters
+ - Add various Chinese phrases involving exceptions of braille
+ patterns
+ - Modify dot patterns of dashes for readability reasons
+- Added a table for Turkish grade 2 thanks to Uğur Gürbüz and Simon
+ Aittamaa
+- Major upgrade to the German tables. They have been upgraded to /Das
+ System der deutschen Brailleschrift/ (2018). They are much smaller
+ now as they are based on ~lou_maketable~. As they now work for any
+ locale (be it Switzerland or Germany) they have been merged into one
+ set of tables for the different grades. Thanks to Christian
+ Waldvogel.
+- New table for Arabic contracted braille thanks to Ikrami Ahmad.
+- New table for Arabic computer braille thanks to Ikrami Ahmad.
+- Improvements to Arabic uncontracted braille thanks to Ikrami Ahmad.
+- Improvements to Ethiopic thanks to Tamru E. Belay.
+- New table for Spanish contracted braille thanks to Juan Pablo Bello.
+
+** Other changes
+- Updated the ~lou_allround~ and ~lou_trace~ test tools to include all
+ the mode flags described in the documentation of the
+ ~lou_translateString()~ function, thanks to Bue Vester-Andersen
+
+** Deprecation notice
+- None
+
+** Backwards incompatible changes
+- The ~pass1Only~ flag has been deprecated for a while and is now
+ removed from the code, thanks to Bue Vester-Andersen.
+
+** New, renamed or removed tables
+*** New
+- tr-g2.ctb
+- ar-ar-g2.ctb
+- ar-ar-comp8.utb
+- es-g2.ctb
+
+*** Renamed
+- de-de-accents.cti -> de-accents.cti
+- de-de-g0.utb -> de-g0.utb
+- de-de-g1.ctb -> de-g1.ctb
+- de-de-g2.ctb -> de-g2.ctb
+- de-ch-g0.utb -> de-g0.utb
+- de-ch-g1.ctb -> de-g1.ctb
+- de-ch-g2.ctb -> de-g2.ctb
+
+*** Removed
+- ar-fa.utb
+- Es-Es-g1.utb
+
+* Noteworthy changes in release 3.7.0 (2018-09-03)
+This release implements major improvements for back-translation thanks
+to concerted efforts by Bue Vester-Andersen, Bert Frees, Timothy Lee
+and others. In particular the input/output positions are now correct
+also for back-translation. There are new and improved Chinese Braille
+tables and some long awaited improvements to UEB. The release also has
+some code cleanups and documentation improvements.
+
+For a detailed list of all the changes refer to [[https://github.com/liblouis/liblouis/milestone/17?closed=1][the list of closed
+issues]].
+
+** New features
+- Added a new opcode ~midendnumericmodechars~. Characters defined with
+ this opcode can appear in the middle or at the end of a number
+ without canceling numeric mode. Thanks to Bue Vester-Andersen.
+
+** Bug fixes
+- Fix another stack-based buffer overflow in input parsing reported by
+ Henri Salo thanks to Christian Egli.
+- Fix input/output positions for back-translation. Thanks to excellent
+ bug reports and patches by Timothy Lee, Bert Frees heroically sat down and
+ reworked the handling of the input/output positions for
+ back-translation. This solves numerous issues with backward
+ translation.
+- The returned ~inlen~ and ~outlen~ now always match thanks to the
+ above work on input/output positions by Bert Frees.
+- Major improvements in the back-translation of capitalized words
+ (~capsword~) in conjunction with punctuation and numbers. Thanks to
+ Bue Vester-Andersen
+- Fixed a problem in the back-translation of numbers in conjunction
+ with punctuation and letters. Thanks to Rimas Kudelis and Bue
+ Vester-Andersen
+- Fix a buffer overflow in ~matchCurrentInput~. Thanks to Hongxu Chen
+ for reporting and to Christian Egli for fixing it.
+
+** Braille table improvements
+- Danish grade 2 tables: Reduced hyphenation to only the hyphens
+ necessary for correct Braille translation. Replaced the longer rules
+ with hyphenation for better cursor positioning. Corrected some words.
+ Thanks to Bue Vester-Andersen.
+- New Chinese Mandarin Braille Codes (Grade 1) and (Grade 2) thanks to
+ Sunian Loomee. The first one is for Chinese Common Braille, commonly
+ known as the old Braille where a Chinese character is composed of
+ three Braille Symbols, consonants, vowels and tones. The second
+ table is for Chinese double spelling Braille, commonly known as the
+ new Braille where Chinese character is composed of two Braille
+ Symbols, consonants and vowels, ( the tones are included in vowels ).
+- Major update to the Urdu tables thanks to Jake Kyle.
+- Back-translation of numbers in Latvian, Polish, Portuguese, Serbian,
+ and Swedish has been fixed thanks to Bue Vester-Andersen.
+- Improvements to UEB such as handling of /BLT/, /BLVD/ and /LLC/,
+ number sign placement, final-letter groupsign usage and final-letter
+ back-translation thanks to Mike Gray.
+- Significant changes to Bopomofo-based Chinese Braille. Among other
+ things there is now complete the support of /CJK Unified Ideographs
+ Extension A/ and some symbols were added for Nemeth. Thanks to
+ Sponge Jhan and 黃偉豪. With this change we can now properly handle
+ duoyinzi, Chinese words that have more than one pronunciation. The
+ granularity of the cursor movement can now reflect positions of all
+ Chinese characters.
+
+** Other changes
+- Added documentation of opcodes which were previously introduced as
+ part of the UEB work. Thanks to Bue Vester-Andersen.
+- Test suite improvements: In addition to checking the translation the
+ tests now also check if the provided ~inlen~ is the same as the
+ returned ~inlen~ and retry the test with a larger output buffer.
+- Fix a problem in the Makefiles that prevented liblouis from being
+ built with automake 1.16. This is fixed now thanks to a patch from
+ Samuel Thibault.
+- Removal of the code for the /scripting language/ for multipass
+ opcodes. This code was originally introduced in 2012 but never
+ documented. Consequently it was never used. Meanwhile the original
+ code for multipass opcodes was much improved. So there is no more
+ need for this (duplicate) code and we are removing it.
+- The nightly snapshots of pre-built windows binaries are now built
+ with UCS4 enabled.
+
+** Deprecation notice
+- None
+
+** Backwards incompatible changes
+- None
+
+** New, renamed or removed tables
+*** New
+- zhcn-g1.ctb
+- zhcn-g2.ctb
+*** Renamed
+- None
+*** Removed
+Tables that are only useful in the context of liblouisutdml were moved
+there
+- marburg.ctb
+- marburg_edit.ctb
+- nemeth.ctb
+- nemeth_edit.ctb
+- ukmaths.ctb
+- ukmaths_edit.ctb
+- wiskunde-translation.cti
+- wiskunde.ctb
+
+* Noteworthy changes in release 3.6.0 (2018-06-04)
+This release contains the usual assortment of braille table
+improvements, cleanups and bug fixes. The most prominent change is the
+refactoring of the call APIs by Bert Frees that makes the code much
+more manageable and solid and will help us in the future to evolve the
+library.
+
+For a detailed list of all the changes refer to [[https://github.com/liblouis/liblouis/milestone/16?closed=1][the list of closed
+issues]].
+
+** New features
+- Add metadata fields =name= and =display-name= to tables thanks to
+ Bert Frees. The =name= contains a description of the table in the
+ native language. =display-name= contains an English description.
+- YAML test enhancements
+ - You can now test both forward and backwards translation with in
+ the same YAML file and for the same set of tables tests thanks to
+ Bue Vester-Andersen. See the documentation for the
+ ~bothDirections~ testmode.
+ - Add =maxOutputLength= option in YAML tests.
+
+** Bug fixes
+- Fix a bunch of buffer overflow errors in table parsing thanks to
+ Samuel Thibault and Christian Egli (CVE-2018-11410 and
+ CVE-2018-11440).
+- Fix input-output mapping of context rules thanks to Bert Frees.
+- Fix back tracking with all caps words thanks to Bert Frees.
+- Fix context rules with lookback thanks to Bert Frees.
+- Fix a memory leak in default table resolver thanks to Timothy Lee.
+- Fix an array out of bounds error which caused a crash on i386 thanks
+ to Samuel Thibault.
+- Fix numerous stack-based buffer overflow in table parsing reported
+ by Henri Salo and Edward-L thanks to Christian Egli (CVE-2018-11577,
+ CVE-2018-11683, CVE-2018-11684 and CVE-2018-11685).
+
+** Braille table improvements
+- Fix some forward- and back-translation errors in Unified French Grade
+ 2 thanks to André-Abush Clause.
+- Updates to the Simplified-Chinese Braille Translation Table thanks
+ to Roshanson
+ - Added many polygraphs to distinguish different meanings of a word
+ - Letter identifiers have been modified. In China's school for the
+ blind, when many visually impaired students learn, the lowercase
+ letters often do not have to mark the identifiers deliberately. So
+ in this version, we this item has been deleted.
+ - Fixed a bug in the braille code that revises the space and 0
+- Updates to Bopomofo-based Chinese Braille Table thanks to Bo-Cheng Jhan
+ - Redefine some Chinese words and phrases
+ - Add various Nemeth symbols such as arrows and parenthesis
+ - Complete the support of CJK Compatibility block
+ - Fix the support of various parentheses, brackets, and braces
+ - Minor fixes (kana rules, punctuation marks, Greek alphabets)
+- New 8 dot computer braille table for Czech thanks to Jan Hegr.
+- Fixes to Czech 6 dot table thanks to Jan Hegr
+ - Fixed curly brackets representation
+ - Fixed number sign representation
+ - Added copyright sign
+- Minor fixes to Hebrew thanks to Erez Kugler.
+
+** Other changes
+- Refactoring thanks to Bert Frees
+ - Simplify the emphasis class handling by combining all related vars
+ in a struct =EmphasisClass=
+ - Simplify input/output buffer handling
+ - Combine =emphasisBuffer= and =transnoteBuffer=
+ - Group match related vars in a struct =PassRuleMatch=
+ - Remove dead code
+- Fixed many warnings thanks to Christian Egli
+
+** Deprecation notice
+- The =mode= parameter in =lou_dotsToChar= never had any effect and is
+ now deprecated.
+- In 2012 a new way to specify the test and action part in context and
+ multipass opcodes was introduced. It was never documented and has no
+ known usage in the wild. However it opens up the attack surface to
+ the table parsing code. Therefore it is deprecated and will be
+ removed in the next release.
+
+** Backwards incompatible changes
+- None
+
+** New, renamed or removed tables
+*** New
+- cs-comp8.utb
+*** Renamed
+- None
+*** Removed
+- Cz-Cz-g1.utb
+
+* Noteworthy changes in release 3.5.0 (2018-03-05)
+This release has a number of Braille table improvements, cleanups and
+meta data enhancements. The most prominent new feature however is
+probably the much improved test coverage. This has helped in tracing
+and fixing a number of long standing bugs.
+
+For a detailed list of all the changes refer to [[https://github.com/liblouis/liblouis/milestone/15?closed=1][the list of closed
+issues]].
+
+** New features
+- The same name can now be used in more than one ~class~ rule. The
+ effect is that both set of characters become part of that one class.
+
+** Bug fixes
+- Fix a regression in inputPositions thanks to Bert Frees
+- Treat characters within the range ~compbrlStart~ and ~compbrlEnd~ as
+ a special case. This fixes many if not most of the problems with
+ cursor position and the ~compbrlAtCursor~ mode. Thanks to Dave Mielke.
+- Fix ~swapdd~ opcode thanks to Bert Frees
+- Fix negation of attribute matcher in multipass expressions thanks to
+ Bert Frees
+
+** Braille table improvements
+- Add a display table that maps braille dots to brl/brf character set.
+ For an in depth explanation see the corresponding [[https://github.com/liblouis/liblouis/issues/503][github issue]].
+ Thanks to Rimas Kudelis
+- Major Improvements to Unified French Grade 2 thanks to André-Abush
+ Clause
+- Fix braille number input for Greek Braille thanks to Dave Mielke
+- Add a fix for "phad" according to UEB Rule 10.7.3 thanks to Anthony
+ Tibbs
+- Updates to the Urdu tables thanks to Jake Kyle from Compass Braille
+- Updates to the Chinese braille table (~zh-tw.ctb~) thanks to
+ Bo-Cheng Jhan
+- ~IPA.utb~ now contains a more complete list of phonetic symbols,
+ including some that might conflict with other tables. For this
+ reason it is not suitable for inclusion in other tables. A separate
+ table ~IPA-unicode-range.uti~ has been added for this
+ purpose. Thanks to Ludovic Oger.
+- The Mongolian table has been improved and there is now also support
+ for grade 2 thanks to Tsengel Maidar.
+- Minor updates to the Danish tables thanks to Bue Vester-Andersen
+- Fix back translation of numbers in Dutch, Finnish and Canadian
+ French, thanks to Leonard de Ruijter.
+- New table for Ukrainian thanks to Sergiy Moskalets.
+
+** Other changes
+*** Improved documentation
+- Extend the documentation on multipass opcodes. Thanks to Dave Mielke
+ and Christian Egli.
+- Remove the deprecation note of the '=' dots operand. While there are
+ still problems with back-translation we will not remove support for
+ it. See also the discussion in the [[https://github.com/liblouis/liblouis/issues/500][github issue]].
+
+*** Improved meta data information in tables
+The meta data in the tables such as locale, contraction grade, etc has
+been improved and is now also used when testing from a YAML test.
+Thanks to Bert Frees.
+
+*** Major overhaul of the YAML test suite
+**** Support for proper testing of cursor positions
+Due to problems in the cursor position computation the YAML test
+suite was improved to support proper testing of cursor position also
+in combination with input, output position and modes. In essence all
+of the liblouis API is now supported and can be tested via the YAML
+tests. Thanks to Christian Egli.
+
+**** Support for table selection via meta data query
+The tables to be tested can now be specified via a meta data query in
+addition to specifying them by filename. See the documentation for
+more details. Internally the YAML tests have been split up into tests
+that test the braille translation for a particular locale (now located
+in ~tests/braille_specs~) and tests that check a specific feature of
+liblouis. Thanks to Bert Frees.
+
+** Deprecation notice
+None
+
+** Backwards incompatible changes
+- The translation mode ~comp8Dots~ has been removed as it was never
+ really implemented anyway
+- Support for the ~pass1Only~ flag has now been removed. Thanks to Bue
+ Vester-Andersen.
+- The old UEB tables ~UEBC-g1.ctb~ and ~UEBC-g2.ctb~ have been removed
+ as the have been superseded by ~en-ueb-g1.ctb~ and ~en-ueb-g2.ctb~.
+- The french tables ~fr-2007.ctb~, ~fr-fr-g1.utb~, ~fr-fr-g2.ctb~,
+ ~fr-ca-g1.utb~ and ~fr-ca-g2.ctb~ have been removed. Use
+ ~fr-bfu-comp6.utb~ for 6 dots literary, ~fr-bfu-comp8.utb~ for 8
+ dots computer and ~fr-bfu-g2.ctb~ for contracted braille instead.
+
+** New, renamed or removed tables
+*** New
+- IPA-unicode-range.uti
+- mn-MN-g2.ctb
+- uk.utb
+*** Renamed
+- mn-MN.utb -> mn-MN-g1.utb
+*** Removed
+- fr-2007.ctb
+- fr-ca-g1.utb
+- Fr-Ca-g2.ctb
+- fr-fr-g1.utb
+- Fr-Fr-g2.ctb
+- UEBC-g1.ctb
+- UEBC-g2.ctb
+
+* Noteworthy changes in release 3.4.0 (2017-12-04)
+This release brings together a lot of work by lots of different
+people. Probably the most prominent fix is the work on output
+positions by Bue and Bert. NVDA should benefit from this. Then there
+are new and massively improved tables like the Lithuanian 6-dot table
+by Rimas or the improved back-translation for French by Michel and
+André-Abush to name just a few. There are too many contributors to
+name them here, thanks to them all.
+
+For a detailed list of all the changes refer to [[https://github.com/liblouis/liblouis/milestone/14?closed=1][the list of closed
+issues]].
+
+** New features
+- Add support for ~inputPos~ and ~outputPos~ checking in
+ ~lou_checkyaml~ thanks to Bue Vester-Andersen. See the manual for
+ details and examples.
+** Bug fixes
+- output positions (~outputPos~) are now calculated based on input
+ positions (~inputPos~) thanks to Bert Frees. This avoids a whole
+ class of bugs that previously plagued the output positions. This fix
+ also obviates the need for the ~pass1Only~ flag. See below for the
+ deprecation notice.
+** Braille table improvements
+- Addition of Nemeth and Kangxi radical characters and other
+ improvements to Chinese braille (~zh-tw.ctb~) thanks to Bo-Cheng
+ Jhan and 黃偉豪.
+- Improvements to the Spanish chardefs table thanks to Luis Lorente
+ Barajas and Simon Aittamaa.
+- Fixed a lowercase ó in Spanish first reported for NVDA thanks to
+ Sukil Etxenike.
+- New Norwegian 6-dot display braille table for Braillo embossers
+ thanks to Lars Bjørndal
+- Added a bunch of whitespace-like codepoints as spaces thanks to
+ Rimas Kudelis
+- Added Lithuanian 6-dot table thanks to Rimas Kudelis.
+- Addition of more characters to the French tables thanks to Samuel
+ Thibault
+- Improvements to the Hungarian tables thanks to Attila Hammer
+- Improvements to the Mongolian tables thanks to Tsengel Maidar
+- Fix some math signs in Czech Braille (~cs-chardefs.cti~). Thanks to
+ Christian Herden of ViewPlus for reporting this.
+- Updates to the SEB British Braille Tables thanks to Paul Wood
+- Massive improvements to French back-translation thanks to Michel
+ Such and André-Abush Clause
+** Other changes
+*** Improved documentation
+- Bue Vester-Andersen added some notes about back-translation and
+ documented all possible values of the ~mode~ parameter. Also the
+ description of ~decpoint~ and ~litdigit~ was improved.
+- The ~match~ opcode is now documented thanks to Mike Gray and
+ Christian Egli.
+
+*** lou_maketable
+Numerous bug fixes and performance enhancements thanks to Bert Frees
+
+*** Code refactoring
+Many global variables have been removed thanks to Bert Frees
+
+*** Code formatting
+Thanks to clang-format There is now a uniform coding style over the
+whole code base
+
+*** Fix broken NMakefile
+Thanks to Davy Kager building with nmake should work again
+
+** Deprecation notice
+The ~pass1Only~ flag has been deprecated. Its use should be avoided,
+and it will be completely removed from the code in the next version of
+Liblouis. When using the ~pass1Only~ flag in this release you will get
+a warning.
+
+** Backwards incompatible changes
+None
+
+** New, renamed or removed tables
+*** New
+- no-no-braillo-047-01.dis
+- lt-6dot.utb
+*** Renamed
+None
+*** Removed
+None
+
+* Noteworthy changes in release 3.3.0 (2017-09-04)
+This release brings a slew of Braille table improvements, fixes a
+number of security related bugs and introduces a new tool to generate
+liblouis Braille tables based on a corpus of know good Braille
+translations. For a detailed list of all the changes refer to [[https://github.com/liblouis/liblouis/milestone/13?closed=1][the list
+of closed issues]].
+
+** New features
+*** maketable tool
+A new tool ~lou_maketable~ enables the creation of tables based on a
+corpus of known good Braille translations. This has huge potential to
+simplify table maintenance for tables that have so far been dominated
+by large exception lists. Thanks to Bert Frees.
+*** Meta data query API
+A new API and a corresponding command line tool to query table meta
+data thanks to Bert Frees
+
+** Bug fixes
+*** Back translation
+- UEB grade 2
+ - Fix back-translation of whole word contractions followed by other
+ contractions thanks to James Teh.
+ - Fix back-translation for contractions followed by punctuation
+ thanks to James Teh.
+*** Security
+- Fix a number of CVEs (illegal address access, buffer overflow and
+ use-after-free or in terms of CVEs: CVE-2017-13738, CVE-2017-13739,
+ CVE-2017-13740, CVE-2017-13741, CVE-2017-13742 and CVE-2017-13744)
+ thanks to Mike Gorse.
+- Fix CVE-2017-13743 thanks to Christian Egli.
+
+** Braille table improvements
+- New table for Croatian grade 1 Braille thanks to Zlatko Sobočan.
+- Fixes and tests for Slovak Braille thanks to Simon Aittamaa
+- Numerous fixes in the character definitions of the Spanish tables
+ thanks to Simon Aittamaa
+- Unified French 6 dots and 8 dots improvements for back-translation
+ thanks to Michel Such
+- Updates to the Chinese braille table thanks to Coscell Kao
+- Updates to Nemeth character definitions thanks to Attila Hammer
+- The Hungarian tables now conform to the new 2017 standard thanks to
+ Attila Hammer
+
+** Backwards incompatible changes
+- The constant ~otherTrans~ has been removed in both the C API and the
+ corresponding Python bindings.
+- The constants ~ucBrl~, ~noUndefinedDots~ and ~partialTrans~ have
+ different values now in both the C API and the corresponding Python
+ bindings.
+
+** New, renamed or removed tables
+*** New
+- hr-g1.ctb
+*** Renamed
+- hr.ctb -> hr-comp8.utb
+*** Removed
+
+* Noteworthy changes in release 3.2.0 (2017-06-06)
+Aside from the usual improvements to Braille tables this release
+focuses on improving the internal infrastructure. Numerous bugs have
+been fixed, the CI infrastructure also checks mingw builds now and MSVC
+compatibility has been massively improved. For a detailed list of all
+the changes refer to [[https://github.com/liblouis/liblouis/milestone/10?closed=1][the list of closed issues]].
+
+** Bug fixes
+- Fix capsnocont opcode. Also mark capital letters with capsletter
+ symbol when capsnocont is defined but no begcapsword indicator is
+ defined. Thanks to Bue Vester-Andersen.
+- Fix the syllable opcode. It had been broken under some circumstances
+ since 3.0. Thanks to Bert Frees and Christian Egli.
+** Other changes
+- Fix building of Python bindings when cross-compiling. Thanks to
+ Chris Brannon
+- lou_checkyaml is now only installed if libyaml is available. Thanks
+ to Christian Egli
+- Major internal changes to improve MSVC compatibility. Thanks to Davy
+ Kager
+- Enhance documentation on usage of display tables in particular
+ in conjunction with Unicode dot patterns. Thanks to Bert Frees
+** Braille table improvements
+- Improvements to the Swedish 8-dots table (~se-se.ctb~) thanks to
+ Kevin Derome
+- Improvements to the Simplified-Chinese Braille table thanks to
+ Roshanson
+- Fixes for the International Phonetic Alphabet Braille table thanks
+ to Ludovic Oger
+- Added more Unicode symbols (fractions and not equal) to the UEB
+ tables. Thanks to Paul Wood and James Bowden.
+- Fixes to UEB grade 2 (en-ueb-g2.ctb) thanks to Mike Gray.
+- Vastly improved Danish tables thanks to Bue Vester-Andersen.
+ - New literary tables for 6 dots, mainly for embossing (no
+ back-translation).
+ - Improved back-translation in 6 dots tables, all grades.
+ - New support for many Unicode characters in all 6 dots tables.
+ - Strengthened internal tests to prevent breaking of tables due to
+ changes in the code.
+ - Fixed 8 dots tables which were broken in the previous version.
+- New Braille tables for Sinhala script thanks to Ashoka Bandula
+ Weerawardhana.
+- New Hungarian grade 2 Braille table thanks to Attila Hammer.
+- Improvements to UEB in particular to symbols specified mostly on the
+ Appendix 3 (Symbols List) from the Rules of Unified English Braille
+ Second Edition 2013 document thanks to Victor Montalvão.
+- Improvements to Persian 8 dot computer Braille table thanks to
+ Mohammadreza Rashad.
+** Backwards incompatible changes
+- The old Greek table gr-gr-g1.utb is gone. Use el.ctb instead
+- The doctests are gone. They have been superseded by the YAML tests.
+- The internal API which was previously in louis.h has been made
+ internal, i.e. the file is renamed to internal.h and the function
+ names are prepended with underscores ('_').
+
+** New, renamed or removed tables
+*** New
+- sin.cti
+- sin.utb
+- hu-hu-g2.ctb (new)
+- da-dk-6miscChars.cti (new)
+- da-dk-g16-lit.ctb (new)
+- da-dk-g26-lit.ctb (new)
+- da-dk-g26l-lit.ctb (new)
+*** Renamed
+- gr-gr-g1.utb (removed and replaced by el.ctb)
+*** Removed
+- da-chardefs6.cti
+- da-dk-common6.uti
+- da-dk-g26-patches.cti
+- da-dk-g2core.cti
+- da-dk-nocaps.uti
+
+* Noteworthy changes in release 3.1.0 (2017-03-06)
+An influx of new contributors have made sure that liblouis continues
+to improve. Back translation has seen major improvements, there are
+some additional modes to help screen readers, for many tables meta
+data has been added, the Python bindings are more robust, Windows
+support has been improved, the YAML test suite has been generalized
+and as usual new and improved braille tables have been included. On
+the licensing front we managed to get almost all tables re-licensed to
+LGPLv2.1+.
+
+** New features
+*** Meta data
+Most of the translation tables now contain meta data. This makes them
+discoverable. Programs can use the lou_findTable function to find a
+table based on a query.
+
+*** noUndefinedDots mode
+Add a noUndefinedDots mode to disable the output of dot numbers when
+back-translating undefined patterns. Thanks to James Teh.
+
+When back translating input from a braille keyboard cell by cell, it is
+desirable to output characters as soon as they are produced.
+Similarly, when back translating contracted braille, it is desirable to
+provide a "guess" to the user of the characters they typed. To achieve
+this, liblouis needs to have the ability to produce no text when
+indicators (which don't produce a character by themselves) are not
+followed by another cell. This works already for indicators liblouis
+knows about such as capital sign, number sign, etc., but it does not
+work for indicators which are not (and cannot be) specifically defined
+as indicators. For example, in UEB, dots 4 5 6 alone produces the text
+"\456/". Setting the noUndefinedDots mode suppresses this dot number
+output.
+
+*** partialTrans mode
+Add a partialTrans mode to specify that back-translation input should
+be treated as an incomplete word. Thanks to James Teh.
+
+If this mode is set, rules that apply only for complete words or at
+the end of a word will not take effect. This is intended to be used
+when translating input typed on a braille keyboard to provide a rough
+idea to the user of the characters they are typing before the word is
+complete.
+
+*** YAML test framework
+The YAML framework has been extended and is much more useful now. You
+can test multiple tables within one YAML file, you can define test
+tables directly inline and you can test multiple tables using the same
+test data. Refer to the documentation for the details.
+
+If really not wanted the YAML tests can be disabled by specifying
+~configure --without-yaml~.
+
+** Bug fixes
+- Fixes implicit declaration of 'pattern_check' thanks to Reiner Dolp
+- Fix a stackoverflow crash on applications with smaller stack size.
+ Thanks to Victor Montalvão.
+- Fix the \v escape sequence. Thanks to Davy Kager.
+- The Python bindings now give a helpful error if liblouis has been
+ compiled with a different character size than Python. Thanks to Matt
+ Wenn.
+- Massive bug fixes in multipass rules. Dave Mielke has done a
+ tremendous job improving the multipass machinery also in the
+ context of back-translation. Where needed nofor/noback has been
+ added to the multipass rules.
+
+** Other changes
+- Improvements to the Emacs mode for editing liblouis tables thanks to
+ Christian Egli
+- Documenting lou_charSize thanks to Reiner Dolp
+- Support for relative table paths in the tests. This will make sure
+ you always know which table a test actually uses.
+- Infrastructure to build windows binaries in a Docker container,
+ thanks to Bert Frees
+
+** Braille table improvements
+- UEB improvements, thanks to Mike Gray
+ - Fixed apostrophe and back translation
+ - Added rules for Unicode apostrophe handling
+ - Improvements to UEB and Nemeth math
+- Complete overhaul of Lithuanian 8-dots table, thanks to Rimas
+ Kudelis
+- New Urdu 6 Dot Grade 1 and 2 Braille tables thanks to Jake Kyle
+- Improvements to Italian 8 dots computer braille, thanks to Simone
+ Dal Maso.
+- New table ~unicode-braille.utb~ that helps to back translate braille
+ input to Unicode braille output, thanks to Leonard de Ruijter.
+- Improvements to the Chinese braille table thanks to Coscell Kao.
+- New Turkish braille table for grade 1 that should replace the
+ old ~tr.ctb~ table, thanks to Arend Arends.
+- New Persian grade 1 table and 8-dots computer table thanks to
+ Mohammadreza Rashad.
+- New table for the International Phonetic Alphabet thanks to Ludovic
+ Oger
+- Fixes for the French 6 and 8 dots tables thanks to Michel Such. Some
+ errors have been fixed and many Unicode characters have been added.
+- Add an extended 8-dot computer braille table for U.S. English thanks
+ to Davy Kager. The table is tailored for use on Windows (CP-1252)
+ and uses dot patterns from Windows screen readers, but should be
+ useful on other platforms too.
+- New Greek table that is better than the existing Greek Grade 1
+ Braille Table (gr-gr-g1.utb) thanks to Dave Mielke.
+- Improved number back-translations on fr-fr-g1 and vi-g1 tables
+ thanks to Victor Montalvao.
+- New Chinese Braille table for use in the mainland of China thanks to
+ Kaifang Bao of RejoinTech.
+- The Black Circle character is commonly used for displaying password
+ characters. The absence of its definition leads to users not being
+ able to know how many characters were typed in such fields. This has
+ been improved for many tables thanks to Victor Montalvao.
+
+** License changes
+- DocArch has agreed to re-license their tables, so we have 8 more
+ tables under the LGPLv2.1+.
+
+** Backwards incompatible changes
+- The naming in the YAML test framework has changed slightly from
+ `tables:` to `table:`.
+
+* Noteworthy changes in release 3.0.0 (2016-07-14)
+This is the biggest release of liblouis in years. The major news are
+that we now have proper support for UEB and secondly that liblouis is
+now licensed under [[https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html][LGPLv2.1+]].
+
+In order to support UEB the internals of liblouis have seen a major
+rewrite. New Opcodes have been added to support the requirements for
+proper UEB for example for emphasis handling or to handle proper
+translation of numbers. Changes to the opcodes are described in the
+documentation. Some of these changes are not backwards compatible. All
+tables that come with liblouis have been migrated. If you have private
+tables look at the section on upgrading from previous versions in the
+[[https://github.com/liblouis/liblouis/wiki/Emphasis-Opcodes#upgrade-from-previous-versions][wiki]].
+
+This release also changes the C API. External applications will have
+to adapt the way they call liblouis. In particular the typeform
+parameter has changed.
+
+The license of the library and most of the tables has been changed to
+LGPLv2.1. For a detailed list which tables are still in the process of
+migrating the license refer to the [[https://github.com/liblouis/liblouis/wiki/Licensing-of-liblouis-tables][wiki page about the license change]].
+
+** New features
+- Numerous features to support UEB properly. Thanks to Mike Gray,
+ William Freeman, Davy Kager, Keith Creasy and the American Printing
+ House for the Blind for sponsoring this work.
+ - support the many emphasis classes needed for UEB.
+ - support translation of numbers according to the rules of UEB.
+ - Capitalization is now handled just like emphasis.
+ - support for numeric mode
+- UTF-8 support for all tools thanks to Christian Egli.
+- The YAML tests now allow for an optional test description. See the
+ documentation for more details.
+- Add ~lou_checkTable~ and ~lou_getTypeformForEmphClass~ to the C API
+ and to the Python bindings
+** Bug fixes
+- Stop buffer overrun in ~lou_getProgramPath~, and also free memory
+ after usage. Thanks to Michael Curran.
+** Other changes
+- The license of the library and most of the tables has been changed
+ to [[https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html][LGPLv2.1+]].
+- Improvements to the test suite:
+ - Output is printed to ~stderr~. This helps with locating errors when
+ testing with the YAML test suite.
+ - typeform is included in output.
+** Braille table improvements
+- Improved Finish 6-dot braille thanks to Jukka Eerikäinen
+- Improvements to the Chinese braille table thanks to Coscell Kao
+- Improvements to Mongolian thanks to Tsengel Maidar and Sreeja Param
+- Added new Slovak tables based off the official Slovak braille
+ standard thanks to Peter Vagner
+- Changes to the Norwegian tables. There are now three Norwegian 8-dot
+ tables
+ - ~no-no-comp8.ctb~: Norwegian 8-dot computer braille table
+ - ~no-no-8dot.utb~: Norwegian 8-dot braille table
+ - ~no-no-8dot-fallback-6dot-g0.utb~: Norwegian 8-dot braille table
+ with uncontracted 6-dot fallback
+- Changes to the Dutch tables
+ - Conforms better to the standard.
+ - ~nl-BE-g1.ctb~ renamed to ~nl-BE-g0.utb~
+ - ~nl-NL-g1.ctb~ renamed to ~nl-NL-g0.utb~
+- Improvements to Danish tables: Added grade 2 with limited
+ contractions to 6 and 8 dots. Corrected contraction of many words.
+ - Renamed:
+ - ~da-ansi8.dis~ -> ~da-dk-octobraille.dis~
+ - ~da-dk-g16.utb~ -> ~da-dk-g16.ctb~
+ - ~da-dk-g18.utb~ -> ~da-dk-g18.ctb~
+ - ~hyph_da_DK.dic~ -> ~hyph_brl_da_dk.dic~
+ - Removed: ~da-dk-g28caps.cti~, ~da-dk-g28-patches.cti~ and
+ ~da-chardefs8.cti~
+** Backwards incompatible changes
+- The json based harness test suite has been removed as its
+ functionality has been superceded by the YAML tests. Please use
+ these from now on.
+- A number of opcodes to handle emphasis have been renamed.
+- The C API regarding the typeform parameter has changed.
+
+* Noteworthy changes in release 2.6.5 (2015-12-1)
+This minor release introduces new tables (Mongolian and Norwegian 8
+dot) and new features to the tracing tool. But the most exiting news
+about this release is probably the fact that 12 developers have
+contributed to it, showing how widely used liblouis is and how
+actively the development progresses.
+
+** New features
+- A DEF file is now generated automatically for the windows builds.
+ Thanks to Christian Egli
+- lou_trace supports backtranslation now. Thanks to Bert Frees
+
+** Bug fixes
+- Fix a bug in the findtable code. Thanks to Michael Katzmann for the
+ report.
+- Fix some compile time warnings on Windows, thanks to Bue
+ Vester-Andersen.
+- Fixes to the logging code by Arend Arends.
+
+** Other changes
+- Add test data for EUB symbols, thanks to Paul Wood
+- Clean up dead code i.e. remove support for (undocumented) nobreak
+ opcode. Thanks to Bue Vester-Andersen.
+
+** Braille table improvements
+- New Mongolian table thanks to Tsengel Maidar and Sreeja Param.
+- Improvements to the Chinese braille table thanks to Coscell Kao.
+- Massive improvements to Norwegian, thanks to Lars Bjørndal, Ammar
+ Usama and Jostein Austvik Jacobsen. They added a 8 dot table and
+ lots of test data.
+- Improvements to Hungarian, thanks to Attila Hammer
+
+* Noteworthy changes in release 2.6.4 (2015-08-31)
+This is a minor release in terms of features. But in terms of test
+coverage and stability it is a vast improvement over previous versions
+of Liblouis. The new YAML based test suite contains more than a
+million of validated translations. Every change in Liblouis is tested
+against this corpus ensuring the change doesn't break anything.
+
+** New features
+- YAML based harness tests. Harness tests can now be written in simple
+ YAML notation and they are integrated with the normal `make check`
+ command. They can be used for both ucs2 and ucs4 and no Python is
+ required. Thanks to Christian Egli.
+
+** Bug fixes
+- Use a separate gnulib instance for the library and the tools. Use
+ the strndup module to avoid build problems on windows.
+- Fix a problem with the nocross opcode when used in combination with
+ the opcodes nocont and compbrl, thanks to Bue Vester-Andersen.
+- Fix a problem with the decoding of the harness test files. Thanks to
+ Bert Frees.
+- Fix numerous problems in the way braille indicators are handled.
+ There is now a safe version of the checkAttr function which makes
+ sure that no attributes are checked beyond the boundaries of the
+ currentInput. This fixes the random behavior with tests where the
+ emphasis extends to the end of the input string. Thanks to Christian
+ Egli.
+
+** Other changes
+- if found use texi2any to build the documentation, thanks to Martin
+ Michlmayr.
+- Fix permissions of Korean tables, thanks to Peter Lundblad.
+- Update the windows build instructions, thanks to Bue
+ Vester-Andersen.
+
+** Braille table improvements
+- Improvements to Hungarian, thanks to Attila Hammer
+- Improvements to Hungarian 8 dot and Serbian grade 1, thanks to
+ Zvonimir Stanecic
+
+* Noteworthy changes in release 2.6.3 (2015-06-01)
+Given the release number you might think this is only a minor release.
+However looking at the number of developers who contributed to it and
+the number of pull requests and issues that were solved this turns out
+to be a very impressive and solid release. Most prominently we have a
+new function to discover tables based on meta data in table headers.
+Also makeinfo is no longer required to build liblouis. And lastly we
+have numerous improvements in Braille tables such as Korean,
+Vietnamese and UEB to name just a few.
+
+** New features
+- [beta] The new function lou_findTable can be used for table
+ discovery based on meta data in table headers. Thanks to Bert Frees.
+- The Python API now has a new function to check tables aptly named
+ ~checkTable~. Thanks to Davy Kager.
+
+** Bug fixes
+- Fixed a problem in resolveTable when using a Java resolver, thanks
+ to Bert Frees
+
+** Other changes
+- The build dependency on makeinfo is now optional. If it is not
+ installed we simply do not build the documentation.
+
+** Braille table improvements
+- Improvements to Bengali, Devanagari, Kannada, Gujarati, Malayalam,
+ Telugu and Oriya, thanks to Sreeja Param
+- Corrections and improvements made to en-GB tables thanks to Paul
+ Wood
+- Vast restructuring to Korean tables. In 2006 the Institute for Korean
+ Braille modified some dots in Korean Braille. Specifically, some
+ punctuation dots are now based on English. To accommodate this change
+ and to retain the old tables, the Korean table set was revised as
+ follows:
+ - Added three files: ko-chars, the Korean characters dictionary, and
+ rules for g1 and g2.
+ - ko-g1 and ko-g2 are now interface files that includes needed
+ files.
+ - Added three files for Korean Braille 2006 revision along with a
+ test harness.
+- New table for Polish 8 dot computer braille. Thanks to Karol Pecyna.
+- New table for Vietnamese 6 dot. Thanks to Harri Pasanen.
+- Corrections and improvements made to UEB tables thanks to Paul Wood
+ - Typeform passage indicators
+ - Degree sign
+ - Dash signs
+ - Math signs
+ - Accent modifiers
+ - Accented letters
+
+* Noteworthy changes in release 2.6.2 (2015-03-02)
+This release, which was mostly pushed out the door by Bert and Mesar,
+fixes a long standing emphasis bug, adds more functionality to the
+harness test suite and improves, as usual, on Braille tables. Notably
+there is a brand new finish table backed by Celia.
+
+** New features
+- Harness tests now can test for typeform differences.
+
+** Bug fixes
+- Fix for emphasis bug, thanks to Michael Gray
+
+** Braille table improvements
+- Correction to comments in Norwegian generic tables, thanks to Lars
+ Bjørndal
+- Corrections to dot patterns in no-no-g0.utb thanks to Lars Bjørndal
+- Corrections and additional test cases for Hungarian grade 1, thanks
+ to Hammer Attila.
+- New 6-dot table for Finnish thanks to Jukka Eerikäinen from
+ Celia. The existing tables for Finnish were 8-dot, but there is an
+ official specification only for 6-dot braille in Finnish.
+
+* Noteworthy changes in release 2.6.1 (2014-12-01)
+This release focuses on table and documentation improvements. The
+documentation has been restructured to cater to people starting with
+writing Braille tables. End users will see improvements to Braille for
+Danish, Dutch, Hungarian, Irish and UK English.
+
+** New features
+*** New Braille tables
+- New grade 1 and grade 2 Gaeilge tables implementing the 2014 UIB
+ standard. Including tests, thanks to Ronan McGuirk, Mesar Hameed.
+
+** Braille table improvements
+- Updates and correction to Hungarian braille tables, thanks to Hammer
+ Attila.
+- Correction to English UK grade 2 braille tables and new tests,
+ thanks to Paul Wood, Mesar Hameed
+- Vastly improved Danish tables thanks to Bue Vester-Andersen
+ - back-translation, both in 6 dots grade 2 and 8 dots grade 2.
+ - Better handling of dash, slash, and other punctuation within words
+ in 8 dots grade 2.
+- New table for Dutch (Netherlands) thanks to Henri Apperloo from CBB
+
+** Bug fixes
+- fix a compiler warning in the logging code. Thanks Peter Lundblad
+ for reporting it and Michael Whapples for fixing the problem.
+
+** Documentation updates
+- The documentation has been restructured to be more beginner friendly
+ and a short introduction to translation table writing has been
+ added. Thanks to Joseph Lee and Christian Egli
+
+** Other changes
+- When compiling with mingw or cygwin resulting dll is liblouis.dll.
+- runHarness.py: add new output format, compact output mode suitable
+ for grepping.
+
+** Backwards incompatible changes
+- Deleted ga.ctb now superseded by ga-g1.utb and ga.g2.ctb.
+- Nl-Nl-g1.utb has been removed. It is superseded by nl-NL-g1.ctb.
+- nl-be-g1.utb has been removed. It is superseded by nl-BE-g1.ctb.
+
+* Noteworthy changes in release 2.6.0 (2014-09-01)
+This is the first release by the new maintainer team. A lot of work by
+people from across the community contributed to this release. There
+are massive additions and updates to the Braille tables (e.g.
+Afrikaans, Hebrew, many Indian languages, Korean) and also changes to
+the C API to enable call backs for error messages and warnings.
+
+** New features
+*** New Braille tables
+- Tables for Afrikaans, Cherokee, Hawaiian, Maori, Sotho and Tswana
+ were donated by Greg Kearney. Afrikaans, Cherokee, Maori and Hawaiian
+ all are grade 1 tables and with the exception of Cherokee were
+ derived from World Braille Usage 2013. The Cherokee was taken from
+ the specification published at www.cbtbc.org/cherokee/.
+*** Logging callback
+There is now a callback system in place to get error messages and
+warnings. This can be used from programs that use liblouis to log
+warnings for example.
+
+** Bug fixes
+- fix back translation problems when word gets split in unusual places
+ causing back translation of whole words for example K5 back
+ translates to Knowledgeen, M>k back translates to Moreark, and M5
+ back translates to Moren. This caused over 8400 extra back
+ translation errors in en-us-g2 and 5000 in en-ueb-g2. Thanks to Ken
+ Perry.
+- Fixed bug to prevent removal of \xffff between largesign rules. This
+ solves a Liblouisutdml bug where \xffff is used as a segment
+ delimiter.
+- Fixed a bug in back translation, when a letsign was encountered, the
+ letsign was being applied beyond the element it applied to.
+- Fix memory leaks in the default table resolver introduced in the
+ previous release.
+- Fixes to the build system by Simon Aittamaa
+
+** Braille table improvements
+- Major improvements to Indian tables thanks to the Indian National
+ Institute for Visually Handicapped, in particular Dipendra Manocha,
+ Mesar Hameed, Dinesh Kaushall and Sreeja Parameswaran:
+ - Corrected opcodes for letters, punctuation marks, digits, signs
+ etc.
+ - Updated braille codes according to prescribed braille codes for
+ each Unicode character by the Braille Council of India for all
+ Indian languages.
+ - defined rules for dealing with Nukhta character in Hindi table
+ - defined rule to insert dot-1 between consonant followed by full
+ vowel character in all Indian Languages
+ - defined rules for shifting of halant character before the
+ consonant. This character is placed after the consonant in normal
+ typing but need to be before the consonant in braille. This rule
+ is applicable for all Indian languages.
+ - defined rules for two conjunct characters "ksha and gya" used in
+ all Indian Languages for which there are specific codes in
+ Braille.
+- New Hebrew table that is based on the new unified Hebrew Braille
+ code standard that was put together on January 2014 after a
+ conference with all of the specialists in this field in Israel. It
+ includes improved representation of Hebrew letters, special letters
+ that are called Nikud, and punctuation symbols. The old Braille
+ standard is not relevant any more. Thanks to Adi Kushnir.
+- UEB table fixes: Fix ity contraction, fixed the missing end word
+ contraction ;n ;d sign 46. thanks to Ken Perry.
+- Fix for Norwegian where letsign is affecting some extra characters
+ thanks to Lars Bjørndal
+- Much improved hyphenation for Norwegian thanks to Lars Bjørndal
+- Korean Grade 2 now includes support for reading English text using
+ grade 2.
+- en-us-g1.ctb and en-ueb.g1.ctb are now able to display 8 dot Unicode
+ braille.
+
+* Noteworthy changes in release 2.5.4 (2014-03-03)
+This release contains nine months worth of braille table improvements
+for example for Danish, UEB, en-us, Nemeth, Bulgarian, Slovenian and
+many more. Also there are fixes to the core for table path resolving
+and back-translation.
+
+** New features
+ - Added function lou_registerTableResolver for plugging in a table
+ resolver callback from your host language.
+
+** Bug fixes
+ - Fixed ENDSEGMENT indicator in computer Braille thanks to John
+ Boyer.
+ - Emphasized words should now be contracted consistently thanks to
+ John Boyer.
+ - Fixed several problems with back-translation. A slash within a
+ number and strings such as 5-inch-diameter and 25-year-old-man
+ should now back-translate correctly. Thanks to John Boyer.
+ - Fixed a problem with syllable opcode. Thanks to John Boyer.
+ - Fix warnings with gcc 4.8.2. Thanks to Peter Lundblad.
+ - When a table is specified with an absolute or relative path, the
+ "includes" in that table will now work as expected, meaning files
+ in the same directory will be found.
+
+** Braille table improvements
+ - fr-bfu-comp8.utb: corrections, zero was wrongly displayed in some
+ instances.
+ - en-us-g2.ctb, en-ueb-g2.ctb: Fixes for that's, can't and s'
+ thanks to Ken Perry.
+ - en-us-g2.ctb: Fix for back-translation of things like
+ http://address.com, words including after, capsigns. thanks to
+ Ken Perry.
+ - Further corrections and testcases to the Hungarian tables thanks
+ to Hammer Attila
+ - Fixed letter sign in en-us and en-ueb tables. Thanks to John
+ Boyer and Ken Perry.
+ - UEB Fixes thanks to Mesar Hameed, Ken Perry and Joseph Lee:
+ - chardefs - correct title and fixed a long standing bug
+ where dots 46 was inserted between letters (especially for web
+ addresses).
+ - Fix problem with at sign.
+ - Removed section of accented letters, that were left behind from
+ US table.
+ - Added todo for accents, to define according to the formal docs.
+ - Corrected mathematical forall symbol.
+ - Modified emphasis dot combinations to follow UEB standard.
+ - Corrected the display of period when used as a midword.
+ - Ensure 'inin' is correctly back-translated in words such as
+ asinine, feminine and others.
+ - Bulgarian bg.ctb: updated to meet modern standards (added Latin
+ letters, corrected punctuation/mathematical symbols, misc typos).
+ Thanks to Rumiana Kamenska
+ - en-gb-g1.utb: Fixes thanks to Paul Wood
+ - Fix for the lich sign in the German tables. Thanks to Halim
+ Sahin.
+ - Nemeth improvements thanks to John Boyer.
+ - Spaces in nemethdefs.cti were changed to unbreakable spaces.
+ This was done so that Nemeth expressions would not be broken
+ between lines.
+ - The number sign is now inserted between the minus sign and the
+ number at the beginning of an expression. Some problems with
+ pass2 opcodes have also been corrected.
+ - The Esperanto table has additional punctuation characters and a
+ test harness. Thanks to Aaron Cannon.
+ - Added missing symbols to the US English BRF display table. Thanks
+ to Aaron Cannon.
+ - Improvements to the Slovenian table and a new Slovenian eight dot
+ computer table provided by Jožef Gregorc.
+ - Fixes to the Norwegian tables thanks to Lars Bjørndal
+ - Fixes for less than / greater than.
+ - Add entries for URLs, domains and file names.
+ - Added ne.utb, an alternative Nepali braille table. One of ne.utb
+ or ne.ctb will be removed/merged in a future version. Keeping
+ both for the time being so that users can test and give feedback
+ on which is most correct. Thanks to Him Prasad Gautam, and Mesar
+ Hameed
+ - Much improved danish grade 1 and grade 2 6 and 8 dot braille,
+ thanks to Bue Vester-Andersen and Mesar Hameed
+
+** Backwards incompatible changes
+ - Delete the table chardefs-ueb.cti as these rules are now provided
+ by en-ueb-chardefs.uti
+
+** Invisible changes
+ - Refactoring in compileTranslationTable.c: separated more clearly
+ the compilation from the table resolving, removed duplicate code,
+ etc.
+
+* Noteworthy changes in release 2.5.3 (2013-06-21)
+** New features
+*** New Braille tables
+ - Korean grade 1 and grade 2 thanks to Joseph Lee
+ - U.K. English 8 dot computer braille table thanks to David
+ Reynolds
+ - New Russian literary and computer braille tables thanks to Igor
+ B. Poretsky. These replace the older Russian tables which are
+ left for backwards compatibility.
+ - New hyphenation dictionary for Russian thanks to Igor B.
+ Poretsky.
+ - Updated hyphenation tables for the Norwegian language (nynorsk
+ and bokmål) thanks to Lars Bjørndal.
+ - New hyphenation dictionary for Esperanto thanks to Aaron Cannon.
+ - New Esperanto grade 1 table, using the x system for accented
+ letters, thanks to Aaron Cannon.
+
+*** runHarness.py:
+ Accept filename globs on the commandline to run specific harness files.
+ In tests/harness, one can do make <filename> or make runall
+ Removed from make check because these checks are checking the validity
+ of our tables, rather than validity of the code.
+
+** Braille Table Improvements
+ - da-dk-g2.ctb, mostly rewritten to use nocross and hyphenation
+ table.
+ - Most tables: removed the default collapse whitespace statements,
+ if you need to compress whitespace, consider adding compress.ctb
+ to the list of tables when processing.
+ - Corrections to Unified English Braille Code (Grade 1 and 2),
+ thanks to Joseph Lee
+ - Corrections to apostrophes in the Computer Spanish 8 dots Braille
+ table (Es-Es-G0.utb). Thanks to Juan C. Buno.
+ - Corrections for double angle quotation marks and emphasis marks
+ in the Norwegian Grade 0 Braille Table. Thanks to Knut Arne
+ Bjørndal.
+ - Fixes for a minor problem regarding the noletsign in Norwegian
+ contracted braille. Thanks to Lars Bjørndal.
+ - Corrections to the Italian table thanks to Igor B. Poretsky.
+ - Corrections to the Hungarian grade 1 table thanks to Hammer
+ Attila
+ - Corrections to English, U.S. Grade 2 (ABAE) table. Thanks to Ken
+ Perry for reporting the bug and John J. Boyer for fixing it.
+ - Further reorganization of the tables to remove duplication. Move
+ litdigit opcode common parts and include where needed.
+ - Removed obsolete en-us-g1.utb, which has been replaced by
+ en-us-g1.ctb.
+ - Added dictionary harness tests for: en-ueb-g2.ctb, en-us-g2.ctb.
+ - Corrections to Nemeth character definitions thanks to Neil
+ Soiffer.
+ - Corrections to the Esperanto table thanks to Aaron Cannon.
+
+** Bug Fixes
+ - Cursor position calculation is now based on the same code that
+ calculates inpos and outpos. This probably solves a number of
+ bugs.
+ - Fix nocross opcode processing.
+ - Fix several buffer over/under runs in
+ lou_translateString.c:hyphenate.
+ - Fix the '=' problem, i.e. fix inputPositions calculation for the
+ case where the equals sign is used as the dots operand. Thanks to
+ Bert Frees
+ - Fix a bug when resizing a table. Previously not all references to
+ this table were updated.
+
+** Backwards incompatible changes
+ - The feature that allowed a mapping between language code and
+ Braille table was removed as it contained a out-of-bounds access
+ bug, was never documented and probably never used. Thanks to
+ Peter Nilsson Lundblad and Jeremy Roman for analyzing this
+ problem and providing a patch.
+
+* Noteworthy changes in release 2.5.2 (2012-12-18)
+
+While initially planned as mainly a bug fix release this release
+contains some notable new features: There is a new tool to trace which
+rules have been used to perform a translation. Also along with other
+new tables the long awaited table for UEB is finally here.
+
+** New features
+*** New tool to trace rule application
+ There is a new tool (lou_trace) which helps to trace which rules
+ have been used to perform a Braille translation. This is helpful
+ for writing Braille tables. See the documentation for more
+ information.
+*** New Braille tables
+ - Inuktitut grade 1, thanks to Greg Kearney.
+ - UEB grade 1 and 2, thanks to Joseph Lee. These tables replace
+ the old UEB tables (UEBC-g1.utb and UEBC-g2.ctb).
+ - Korean table thanks to Joseph Lee
+
+** Braille Table Improvements
+ - da-dk-g2.ctb, fixes for transposed â, å, æ, ä, ø and ö,
+ corrected/improved harness tests.
+ - Corrections for en-GB-g2.ctb thanks to Paul Wood
+ - Corrections to the Hungarian grade 1 table thanks to Hammer
+ Attila
+
+** Bug Fixes
+ - Update gnulib
+ - Fix a bug in the correct opcode which causes sometimes random
+ results when translating. Thanks to Bert Frees.
+ - Fixes for compiler warnings.
+ - Fix some Valgrind warnings about invalid reads
+
+* Noteworthy changes in release 2.5.1 (2012-9-24)
+
+** Braille Table Improvements
+- Fix encoding problem in italian table and added more character
+ definitions. Thanks to Simone Dal Maso <simone.dalmaso@juvox.it>.
+- Rename it-it-g1.utb to it-it-comp6.utb and it-it-g1.utb2 to
+ it-it-comp8.utb.
+
+** Bug fixes
+- Fix outputPos and inlen where an input character generates multiple
+ output characters.
+
+* Noteworthy changes in release 2.5.0 (2012-9-10)
+
+This release contains a tremendous amount of work many developers.
+Many long standing bugs have been fixed. The tables can finally be in
+UTF-8. A grand table cleanup removed duplication from the tables.
+There are now two extensive test frameworks for table writers. A
+number of new tables have been contributed on top of the usual
+assortment of table improvements. Thanks to all of this liblouis has
+already seen quite a bit of uptake in a number of places, notably the
+new DAISY pipeline will ship with this release of liblouis.
+
+NOTE: If you have private tables you might want to migrate them to
+utf-8. To do this just use iconv as follows:
+
+ $ iconv -f latin-1 -t utf-8 <input >output
+
+** New features
+*** New Braille tables
+ - Estonian grade 0, thanks to Jürgen Dengo.
+ - Portuguese 8 dot Computer braille, Thanks to Rui Fontes
+*** UTF-8 support in tables
+ Braille tables can now contain UTF-8 in the opcode arguments.
+*** Improvements to the python bindings
+ All constants defined in liblouis.h are now exposed in the bindings.
+*** Add a doctest infrastructure
+ These tests are based on the Python doctest framework and are only
+ run if there is a Python interpreter on the system
+*** Add a test harness
+ This test infrastructure allows the user to do table tests in a
+ simple and concise syntax. These tests are based on the Python
+ nose testing framework and are only run if either Python 2.x or
+ 3.x with the related nose python module is installed on the
+ system. See the documentation for more information. Thanks to
+ Mesar Hameed.
+*** Add a test harness generator
+ A harness generator that uses simple text files with a little
+ formatting to help to generate the json harness files. The purpose
+ of this tool is to make it much easier and faster to add checks
+ for a given table. You are expected to read the generated harness
+ file and make necessary changes, the tool only helps you to get
+ the tests into the harness format, not check their validity.
+*** Support for Python 3 in the Python bindings
+ The Python bindings now work for both Python 2 and Python 3.
+ Thanks to Michael Whapples.
+
+** Improved C-based test framework
+ - Improved the test framework to be able to test translations
+ involving Unicode.
+ - Added numerous tests, e.g. for lowercase and Unicode, for the
+ input position, for repeated, etc.
+
+** Improved the documentation
+ - Document the test harness (json format, fields, flags).
+ - Document the use of Valgrind to find memory leaks
+ - Improve the documentation on the display opcode
+
+** Bug fixes
+ - lou_allround and lou_translate now properly handle Unicode
+ characters
+ - Fix some issues reported by Valgrind
+ - Fix inputPos for situation where context and multipass opcodes
+ are involved
+ - Fixed a number of bugs with the letter, uppercase and lowercase
+ opcodes when dealing with Unicode
+ - Fixed a couple of bugs with hyphenation (documentation, Python
+ bindings and a number of buffer overruns in the C library).
+ Thanks Milan Zamazal <pdm@brailcom.org> for reporting this.
+ - Fix a bug in the $a. matcher in the multipass rules where only 32
+ chars were matched. It now matches 0xffff chars.
+ - Fix a bug reported by James Teh related to pass1Only
+
+** Braille Table Improvements
+ - all table files have consistent encoding, UTF-8.
+ - The grand table cleanup: Reorganize the tables to remove
+ duplication. Move common parts such as Latin letter, eight and
+ six dot digit definitions to separate files which are then
+ included. This should ease table maintenance. Thanks to Mesar Hameed.
+ - Fixes to de-de-comp8.ctb thanks to Aliminator83@gmail.com
+ - hu1.ctb renamed to hu-hu-g1.ctb
+ - hu.ctb renamed to hu-hu-comp8.ctb
+ - eo.ctb renamed to eo-g1.ctb
+ - Fixes to eo-g1.ctb thanks to Aaron Cannon <cannona@fireantproductions.com>
+ - hu-hu-g1.ctb: improvements and extensive test harness, with
+ working back-translation, Thanks to Hammer Attila
+ - Fixes to fr-bfu-comp6.utb and fr-bfu-comp8.utb thanks to Michel
+ Such <michel.such@free.fr>
+ - Reworked and extended Ethiopic braille table ethio-g1.ctb,
+ superseeds gez*, thanks to Dr. Tamru E. Belay
+ <g.braille@sympatico.ca>
+ - Fixes to no-no-g3.ctb thanks to Lars Bjørndal <lars@lamasti.net>
+
+* Noteworthy changes in release 2.4.1 (2012-2-22)
+
+** New features
+ - Czech hyphenation table thanks to Jan Hegr
+ - Spanish grade 1 table provided by José Enrique Fernández del
+ Campo and Juan Carlos Buño Suárez
+ - New Tamil table thanks to Mesar Hameed
+
+** Braille Table Improvements
+ - Improvements to the Portuguese grade1 braille tables
+ - Updates and additions to Icelandic 8-dot braille table.
+ - Improvements to the uncontracted Spanish computer braille table.
+ - Improvements to the Norwegian braille table thanks to David Hole.
+
+* Noteworthy changes in release 2.4.0 (2012-01-31)
+
+** New features
+ - New Generic Farsi Grade 1 table: A new table for Generic Farsi
+ Grade 1 braille has been provided by Mesar Hameed.
+ - Emacs mode for editing Braille tables thanks to Christian Egli
+
+** Braille Table Improvements
+ - Improvements to the French comp6 and comp8 braille tables
+ - Improvements to the Romanian braille table
+ - Improvements to the Generic Arabic Grade 1 table
+ - Improvements to the Czech tables thanks to Jan Halousek and to
+ Jan Hegr
+
+* Noteworthy changes in release 2.3.0 (2011-05-09)
+
+This release contains support for many more languages than before
+(Swedish, Kurdish, Ethiopic, Serbian, many Indian languages). The
+search path for tables is now a list of paths. Finally there is the
+usual assortment of bug fixes.
+
+** New features
+*** Multiple table search path
+ The environment variable LOUIS_TABLEPATH can now contain a list of
+ paths (separated by commas) where liblouis should look for tables.
+ This allows the user to keep local tables.
+*** New --quiet option for lou_checktable
+ lou_checktable writes to stderr even in the case of success. This
+ can now be suppressed with the new option --quiet.
+*** New Swedish table
+ A new table for Swedish braille has been provided by Samuel
+ Thibault.
+*** New table for Sorani (Kurdish)
+ A new table for Sorani (Kurdish) Braille has been donated by Peter
+ Engström from Index Braille
+*** New table for Ethiopic
+ A new table for Ethiopic Braille has been donated by Tamru E.
+ Belay PH.D from Adaptive Technology Center for the Blind (ATCB)
+*** New table for Serbian
+ A new table for Serbian Braille has been donated by Peter Engström
+ from Index Braille
+
+** Improved the documentation
+ The deprecated opcodes have been moved to a separate section
+
+** Bug fixes
+ - Fixed a long standing bug with an infinite loop in the table
+ compiler
+
+** Braille Table Improvements
+ - Improvements to the Chinese braille table
+ - Improvements to the Flemish Braille Math Code tables
+ - Improvements to the Dutch Braille tables
+ - Improvements to the Spanish Braille tables.
+ - Fixes for the uncontracted French 6 and 8 dot tables
+ - Improved support for Italian 8 dot
+ - Improvements to the Generic Arabic Grade 1 table
+
+* Noteworthy changes in release 2.2.0 (????-??-??)
+
+** New features
+*** New tables
+ - Support for many indian languages
+ - Support for Icelandic 6- and 8-dot
+ - Support for Catalan
+ - Support for Dutch Braille (for Belgium and the Netherlands)
+ - Support for Flemish Braille Math Code (a.k.a. Woluwe code)
+
+
+*** New functions to make libraries relocatable
+ Two new functions, to set the search path for tables and files.
+ They make the library relocatable. See the in the documentation
+ for lou_setDataPath and lou_getDataPath.
+
+** Bug fixes
+ - Improved support for Spanish
+ - Improved Norwegian tables
+
+* Noteworthy changes in release 2.1.1 (2010-8-23)
+
+** Bug fixes
+ - Fixed problems with the Danish grade 2 table
+ - Fixed problems with the Marburg maths table for mathematics and
+ the UK maths table for mathematics
+
+* Noteworthy changes in release 2.1.0 (2010-8-19)
+
+** New features
+*** New tables
+ - Added tables for Portuguese grade 1 and 2
+ - Added unicode.dis for Unicode braille
+*** Modified tables
+ - Updated Danish tables
+*** Implemented language to table mapping
+*** New format of error messages
+ The error messages are now reported in a format similar to the one
+ used in gcc.
+*** New opcode
+ - added undefined opcode
+*** Python bindings
+ - Allow the user to configure the maximum output length by
+ specifying a number by which the input length is multiplied
+ using the outlenMultiplier module variable. The default will
+ handle the case where every input character is undefined in the
+ translation table. Previously, this was hard-coded to 2, which
+ was insufficient in some cases.
+ - Add compbrlLeftCursor mode constant.
+ - Add compileString function which wraps lou_compileString.
+ - Corrections/clarifications to docstrings.
+ - Add python binding for the lou_hyphenate function.
+ - Added python wrapper for lou_backTranslateString and lou_backTranslate.
+
+*** liblouisxslt as an example
+ Add liblouisxslt as an example to python/examples. This is
+ basically an extension of libxslt that lets you invoke liblouis
+ from an xslt stylesheet to do Braille translation on text nodes
+ for example.
+*** compbrlLeftCursor
+ Added a patch provided by Volker Bijewitz to implement
+ compbrlLeftCursor.
+
+** Bug fixes
+*** output cursorPos
+ Fix the output cursorPos when the compbrlAtCursor mode is enabled
+ and the characters around the cursor translate to multiple braille
+ cells, such as in the Chinese braille tables.
+*** outpos when doing back translation
+ Include a patch by Timothy Lee to fix outpos when doing back translation
+ (issue 11)
+*** inputPos/outputPos for undefined characters
+ Fix the input/output position arrays for characters in the input
+ which are undefined in the translation table.
+*** table fixes
+ - Fixed a bug with back translation of '*n'. (issue 13)
+ - Fixes to the en-us-g2.ctb table
+*** Python bindings
+ - Remove unnecessary imports, allowing the bindings to run in Python
+ 2.7. (issue 12)
+ - lou_translate* writes output information in typeform, so
+ allocate enough bytes for it. Fixes possible buffer overruns and
+ resultant crashes.
+*** Miscellaneous
+ - Fixes to the man page generation to fix issues that were
+ reported by the Debian packaging builder
+ - Do not invoke help2man when cross-compiling
+ - Documentation updates (issue 10)
+ - Removing noletsign defaults
+ - Many small fixes
+
+* Noteworthy changes in release 2.0.0 (2010-7-6)
+
+** New features
+*** New functions
+ - Adding lou_charSize function
+
+* Noteworthy changes in release 1.9.0 (2010-6-29)
+
+** New features
+*** New functions
+ - lou_dotsToChar and lou_charToDots function
+ - Added lou_compileString for adding entries to tables at
+ run-time.
+
+* Noteworthy changes in release 1.8.0 (2009-11-23)
+
+This release contains a number of improvements notably the integration
+of gnulib, the automatic generation of man pages and the addition of
+tables for German grade 2.
+
+** New features
+*** New tables
+ - Tables German Grade 2
+ - Swiss German
+ - Swedish (1989 standard)
+ - Swedish (1996 standard)
+
+*** Modified tables
+ - Updated Norwegian tables
+ - Updated Chinese braille table
+
+*** man pages
+ All tools accept the --version and --help options and are
+ documented in man pages
+
+*** Corpus based test cases for tables
+ You can now have corpus based tests for tables. See the README in
+ tests/table_test_corpuses.
+
+** Bug fixes
+ - config.h is no longer exported
+ - Many small fixes
+
+* Noteworthy changes in release 1.7.0 (2009-08-21)
+
+The main new feature of this release is the support for UK and Marburg
+math. Other changes include a new tool to check hyphenation and the
+usual improvement and addition of tables. Also The test suite has been
+enhanced and finally passes.
+
+** New features
+*** New tables
+ - Tables for UK and Marburg math
+ - Hong Kong Cantonese
+ - Hebrew
+ - Hungarian
+ - Slovene
+ - Tibetan
+ - Irish
+ - Maltese
+
+*** Modified tables
+ - Updated Norwegian tables
+ - Bug fixes in Russian tables
+ - Updated French tables
+
+*** lou_checkhyphens tool
+ New tool to check hyphenation
+*** rpm spec file
+*** Test cases for tables
+ The tables can now be tested with `make check'
+*** New opcodes
+ - noback and nofor opcode prefixes
+ - grouping opcode
+ - multipass subopcodes
+
+** Bug fixes
+ - Fix for library name and Python bindings
+ - Documentation fixes
+ - Many small fixes
+
+* Noteworthy changes in release 1.6.2 (2009-05-01)
+
+This release contains a new opcode for Malaysian Braille. See the
+documentation for a description of the new opcode.
+
+** New features
+
+*** repword opcode
+The repword opcode is needed for Malaysian Braille
+
+* Noteworthy changes in release 1.6.1 (2009-04-21)
+
+This is mostly a bug fix release. It contains many bug fixes that were
+discovered in the course of developing UK Math tables.
+
+** Bug fixes
+
+*** bug fixes for correct, context and multipass opcodes
+*** bug fixes for largesign opcode
+*** fixed bug with French back-translation
+*** fixed the installation path for docs
+*** documentation improvement
+
+* Noteworthy changes in release 1.6 (2009-03-04)
+
+This release features support for Danish and Russian and updated
+tables for French and Norwegian. The search path for tables can now be
+specified using an environment variable. Finally there is the usual
+assortment of bug fixes.
+
+** New features
+
+*** exactdots opcode
+The exactdots opcode is intended for use in liblouisxml
+semantic-action files to specify exact dot patterns, as in
+mathematical codes.
+*** LOUIS_TABLEPATH env variable
+You can now specify where liblouis is to look for tables with the
+LOUIS_TABLEPATH environment variable.
+*** New Tables for Danish and Russian
+There is now support for Danish and Russian.
+
+** Bug fixes
+
+*** Updated French and Norwegian tables
+*** Use stdcall calling convention if building for Windows
+
+** Changes in behavior
+
+None
+
+* Noteworthy changes in release 1.5 (2009-01-21)
+
+This is a big release for liblouis. It's the first time that it is
+done from the Google code page. A number of people have contributed,
+namely John Boyer (table debugger, bug fixes), Eitan Isaacson (Python
+bindings), James Teh (Python bindings, bug fixes), Christian Egli
+(documentation) and Michel Such (table for French grade 2).
+
+
+** New features
+
+*** Python bindings
+The liblouis library can now be used from Python. For more info
+consult the README file in the python directory.
+
+*** Table debugger
+liblouis now comes with a debugger that can help to find problems with
+translation tables.
+
+*** French table for grade 2
+There is now a translation table for French grade 2.
+
+*** pass1Only mode bit
+The new pass1Only mode bit will help developers of screen readers as
+the cursor will stay where it is expected to.
+
+** Bug fixes
+
+Fix the inpos array values for the case where a rule has an output
+length which is larger than its input length.
+
+fixed multi-word phrases
+
+fixed bug in character display
+
+fixed bug in findOpcodeName
+
+lou_version now returns the correct liblouis version
+
+** Changes in behavior
+
+None
+
+#+OPTIONS: toc:nil num:nil
diff --git a/README b/README
new file mode 100644
index 0000000..76a9712
--- /dev/null
+++ b/README
@@ -0,0 +1,111 @@
+# Introduction
+
+[](https://travis-ci.org/liblouis/liblouis)
+
+Liblouis is an open-source braille translator and back-translator
+named in honor of [Louis Braille][]. It features support for computer
+and literary braille, supports contracted and uncontracted translation
+for [many languages][] and has support for hyphenation. New languages
+can easily be added through tables that support a rule- or dictionary
+based approach. Tools for testing and debugging tables are also
+included. Liblouis also supports math braille (Nemeth and Marburg).
+
+Liblouis has features to support screen-reading programs. This has led
+to its use in two open-source screenreaders, [NVDA][] and [Orca][]. It
+is also used in some commercial assistive technology applications for
+example by [ViewPlus][].
+
+Liblouis is based on the translation routines in the [BRLTTY][]
+screenreader for Linux. It has, however, gone far beyond these
+routines. In Linux and Mac OSX it is a shared library, and in Windows
+it is a DLL.
+
+Liblouis is free software licensed under the [GNU LGPLv2.1+][] (see
+the file COPYING.LESSER).
+
+The command line tools, are licensed under the [GNU GPLv3+][] (see the
+file COPYING).
+
+# Documentation
+
+For documentation, see the [liblouis documentation][] (either as info
+file, html, txt or pdf) in the doc directory. For examples
+of translation tables, see `en-us-g2.ctb`, `en-us-g1.ctb`,
+`chardefs.cti`, and whatever other files they may include in the
+tables directory. This directory contains tables for many languages.
+The Nemeth files will only work with the sister library
+[liblouisutdml][].
+
+# Installation
+
+After unpacking the distribution tarball from [releases][] go to the directory it creates.
+You now have the choice to compile liblouis for either 16- or 32-bit
+unicode. By default it is compiled for the former. To get 32-bit Unicode
+run configure with `--enable-ucs4`.
+
+After running `./configure` run `make` and then `make install`. You
+must have root privileges for the installation step.
+(For other ways of installation, see the file HACKING)
+
+This will produce the liblouis library and the programs `lou_allround`
+(for testing the library), `lou_checkhyphens`, `lou_checktable` (for
+checking translation tables), `lou_debug` (for debugging translation
+tables), `lou_translate` (for extensive testing of forward and
+backwards translation) and `lou_trace` (for tracing if individual
+translations). For more details see the liblouis documentation.
+
+If you wish to have man pages for the programs you might want to
+install `help2man` before running configure.
+
+If you want to run the test suite with `make check` you should install
+`libyaml` as that will enable extensive tests on the tables. If you
+want to skip those tests you can do so by running `configure --without-yaml`.
+
+# Participating
+
+You can contribute to Liblouis in several different ways:
+
+ - If you have comments, questions, or want to use your knowledge to
+ help others, come join the conversation on either the mailing list
+ or on IRC. You can reach us at liblouis-liblouisxml@freelists.org
+ or in channel #liblouis on irc:irc.oftc.net.
+
+ - To report a problem or request a feature, please file an issue.
+
+ - Of course, we welcome pull requests and patches.
+
+Finally, if you want to see what we have for the future and learn more
+about our release cycles, all this information is detailed on the
+[wiki](https://github.com/liblouis/liblouis/wiki/Release-schedule)
+
+# Release Notes
+
+For notes on the newest and older releases see the file NEWS.
+
+# History
+
+Liblouis was begun in 2002 largely as a business decision by
+[ViewPlus][]. They believed that they could never have good braille
+except as part of an open source effort and knew that John Boyer was
+dying to start just such a project. So ViewPlus did start it on the
+agreement that they would give a small monthly stipend to John Boyer
+that allowed him to pay for sighted assistants. While ViewPlus has not
+contributed much to the coding, it certainly has contributed and
+continues to contribute to liblouis through that support of John
+Boyer.
+
+[Louis Braille]: http://en.wikipedia.org/wiki/Louis_Braille
+[many languages]: https://github.com/liblouis/liblouis/tree/master/tables
+[NVDA]: http://www.nvda-project.org/
+[Orca]: http://live.gnome.org/Orca
+[ViewPlus]: http://www.viewplus.com
+[BRLTTY]: http://mielke.cc/brltty/
+[GNU LGPLv2.1+]: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+[GNU GPLv3+]: https://www.gnu.org/licenses/gpl.html
+[liblouisutdml]: http://www.liblouis.org/
+[liblouis documentation]: http://www.liblouis.org/documentation/liblouis.html
+[releases]: https://github.com/liblouis/liblouis/releases
+
+<!-- Local Variables: -->
+<!-- mode: markdown -->
+<!-- End: -->
diff --git a/README.md b/README.md
new file mode 120000
index 0000000..100b938
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+README
\ No newline at end of file
diff --git a/README.windows b/README.windows
new file mode 100644
index 0000000..6547c4d
--- /dev/null
+++ b/README.windows
@@ -0,0 +1,30 @@
+This file describes how to build liblouis.dll That is the only binary
+file needed by someone who wishes to use liblouis in an application. The
+tables are in the tables subdirectory of the liblouis distribution. For
+an overview of liblouis see README.
+
+First, obtain the liblouis source, either by downloading the latest
+tarball or from the Git repository. See HACKING for instructions.
+If you downloaded the tarball, unpack it.
+
+To build liblouis.dll you will need the Microsoft command-line C/C++
+tools. You will also have to set environment variables correctly. You
+can download the Community version of Microsoft Visual Studio, including
+Visual C++, and the Microsoft Windows SDK for free. It has a batch file
+that sets environment variables and then displays a command prompt.
+
+You might have to add the Visual Studio path
+(C:\Program Files (x86)\Microsoft Visual Studio\2017\Community) to the
+"Path" of the environment variables manually.
+
+Next, go to the subdirectory windows. Edit the file configure.mk. If you
+want 32-bit Unicode change the 2 in the line UCS=2 to a 4.
+
+Open the "VS 2017 Developer Command Prompt" from the Start menu and use the
+"cd" command goto the "\liblouis-x.x.x\windows" folder, then type:
+
+nmake /f Makefile.nmake
+
+The directory will contain liblouis.dll and liblouis.lib, along with
+object files. Note that those liblouis.dll and liblouis.lib only are for
+32-bit usage.
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..9b766af
--- /dev/null
+++ b/TODO
@@ -0,0 +1,71 @@
+This file describes the TODO items for the liblouis project. -*- org -*-
+
+When a task is done and accepted, consider moving it into the NEWS
+file, with a bit of extra info.
+
+* 2.6
+** Document the changes to LOUIS_TABLEPATH
+** Extend and document the scripting language
+http://www.freelists.org/post/liblouis-liblouisxml/Very-preliminary-documentation-of-scripting-language
+
+* near term
+** (google issue 9) bindings should provide variable to pick up table location at runtime.
+
+** Fix the problem that LOUIS_TABLEPATH always looks in the standard PATH
+even if that was not in the environment var
+
+** fix bug described by squash_space.c
+
+** Esperanto table should not be blacklisted, work out whats wrong and make sure it is usable.
+
+* unallocated
+** (google issue 16) infinite loop in lou_backtranslate.
+
+** (google issue 6) italword opcode not documented
+
+** (google issue 4) problem with contraction cursor position and compBrlAtCursor.
+
+** Add java bindings
+It would be nice to have some canonical java bindings. There are
+several potential candidates:
+- Bindings by Michael Whapples
+- Minimal jna bindings by SBS
+- port jni bindings from utdml
+- new jna bindings by Bert Frees
+
+** Enhance the API to handle pre-hyphenated text
+This basically just means to port the code which is in the java
+bindings to C so that it can be used from other bindings
+
+** Add readline support to all the tools
+
+** Use portable malloc from gnulib
+to get rid of the windows #ifdefs
+
+** Enhance translation table compiler to issue warnings
+[jb]: It should be an error to define the same single-cell dot pattern
+for two different characters. I am considering issuing an error
+message and rejecting the table if this happens.
+
+[mh]: It would also be very helpful if we could issue a warning when a
+character has been defined as two or more braille representations.
+Could we have these as warnings, not errors please.
+
+** followup to above enhancement, either at the terminal or when called by
+bindings, we should be able to give more useful feedback, i.e. could
+not translate because table not found, or table found but has errors,
+or characters undefined, etc. also see:
+http://www.nvda-project.org/ticket/2448
+
+** Optimize for use with large tables
+When used with dictionary based tables liblouis is very slow. The
+issue is probably that the hash key is not very well suited for this
+use case and there will be tons of collisions, making the lookup
+essentially linear.
+
+There was a discussion about this on the mailing list
+(http://www.freelists.org/post/liblouis-liblouisxml/Improved-hash-function-for-tables).
+
+** apply the the patch by Igor B. Poretsky
+
+** apply the jptest_patch
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..e0eadec
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+#
+# Copyright 2008 Eitan Isaacson
+# Copyright 2008 Christian Egli
+# Copyright 2012 Michael Whapples
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# autogen.sh glue for liblouis
+#
+# Requires: automake 1.9, autoconf 2.57+
+# Conflicts: autoconf 2.13
+set -e
+
+# Refresh GNU autotools toolchain.
+echo Cleaning autotools files...
+find -type d -name autom4te.cache -print0 | xargs -0 rm -rf \;
+find -type f \( -name missing -o -name install-sh -o -name mkinstalldirs \
+ -o -name depcomp -o -name ltmain.sh -o -name configure \
+ -o -name config.sub -o -name config.guess -o -name config.h.in \
+ -o -name mdate-sh -o -name texinfo.tex \
+ -o -name Makefile.in -o -name aclocal.m4 \) -print0 | xargs -0 rm -f
+
+echo Running autoreconf...
+autoreconf --force --install
+
+exit 0
diff --git a/build-aux/link-warning.h b/build-aux/link-warning.h
new file mode 100644
index 0000000..fda0194
--- /dev/null
+++ b/build-aux/link-warning.h
@@ -0,0 +1,28 @@
+/* GL_LINK_WARNING("literal string") arranges to emit the literal string as
+ a linker warning on most glibc systems.
+ We use a linker warning rather than a preprocessor warning, because
+ #warning cannot be used inside macros. */
+#ifndef GL_LINK_WARNING
+ /* This works on platforms with GNU ld and ELF object format.
+ Testing __GLIBC__ is sufficient for asserting that GNU ld is in use.
+ Testing __ELF__ guarantees the ELF object format.
+ Testing __GNUC__ is necessary for the compound expression syntax. */
+# if defined __GLIBC__ && defined __ELF__ && defined __GNUC__
+# define GL_LINK_WARNING(message) \
+ GL_LINK_WARNING1 (__FILE__, __LINE__, message)
+# define GL_LINK_WARNING1(file, line, message) \
+ GL_LINK_WARNING2 (file, line, message) /* macroexpand file and line */
+# define GL_LINK_WARNING2(file, line, message) \
+ GL_LINK_WARNING3 (file ":" #line ": warning: " message)
+# define GL_LINK_WARNING3(message) \
+ ({ static const char warning[sizeof (message)] \
+ __attribute__ ((__unused__, \
+ __section__ (".gnu.warning"), \
+ __aligned__ (1))) \
+ = message "\n"; \
+ (void)0; \
+ })
+# else
+# define GL_LINK_WARNING(message) ((void) 0)
+# endif
+#endif
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..927aa61
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,221 @@
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.68)
+AC_INIT([Liblouis], [3.12.0], [liblouis-liblouisxml@freelists.org], [liblouis], [http://www.liblouis.org])
+AC_CONFIG_SRCDIR([liblouis/lou_backTranslateString.c])
+AM_CONFIG_HEADER(liblouis/config.h)
+
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_MACRO_DIR([m4])
+AM_INIT_AUTOMAKE([-Wall dist-zip])
+
+# Checks for programs.
+# Try to compile using C99
+AC_PROG_CC_C99
+
+# gnulib for the library
+gl_EARLY
+# gnulib for the tools
+gl_tools_EARLY
+
+gl_INIT
+gl_tools_INIT
+
+# Checks for more programs.
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AM_PROG_AR
+
+# Check if the user wants to enable yaml tests
+AC_ARG_WITH([yaml],
+ [AS_HELP_STRING([--with-yaml], [enable YAML-based tests @<:@default=yes@:>@])],
+ [with_yaml=$withval],
+ [])
+
+# Checks for libraries.
+if test "x$with_yaml" == xno; then
+ AC_DEFINE([WITHOUT_YAML],[1],[Disable YAML tests])
+else
+ AC_CHECK_LIB([yaml], [yaml_parser_initialize])
+fi
+
+AM_CONDITIONAL([WITH_YAML], [test "x$ac_cv_lib_yaml_yaml_parser_initialize" == xyes -a "x$with_yaml" != xno])
+
+# If libyaml is missing warn or die depending on --with-yaml
+if test x$ac_cv_lib_yaml_yaml_parser_initialize != xyes; then
+ case "$with_yaml" in
+ yes) AC_MSG_ERROR([--with-yaml was given, but libyaml was not found]);;
+ no) ;;
+ *) AC_MSG_WARN([libyaml was not found. YAML tests will be skipped]);;
+ esac
+fi
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([stddef.h stdlib.h string.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+
+# Checks for library functions.
+AC_FUNC_MEMCMP
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS([memset])
+
+# This is for stuff that absolutely must end up in pyconfig.h.
+# Please use pyport.h instead, if possible.
+AH_TOP([
+#ifndef LOUISCFG_H
+#define LOUISCFG_H
+])
+AH_BOTTOM([
+#endif /*LOUISCFG_H*/
+])
+
+# increment if the interface has additions, changes, removals.
+LIBLOUIS_CURRENT=20
+
+# increment any time the source changes; set to 0 if you increment
+# CURRENT
+LIBLOUIS_REVISION=0
+
+# increment if any interfaces have been added; set to 0 if any
+# interfaces have been changed or removed. removal has precedence over
+# adding, so set to 0 if both happened.
+LIBLOUIS_AGE=0
+
+AC_SUBST(LIBLOUIS_CURRENT)
+AC_SUBST(LIBLOUIS_REVISION)
+AC_SUBST(LIBLOUIS_AGE)
+
+# needed to build the liblouis.def
+DLL_VERSION=`expr ${LIBLOUIS_CURRENT} - ${LIBLOUIS_AGE}`
+AC_SUBST(DLL_VERSION)
+
+AC_ISC_POSIX
+AC_HEADER_STDC
+AC_LIBTOOL_WIN32_DLL
+AC_PROG_LIBTOOL
+
+# catch as many warnings as possible with the help of the gnulib manywarnings module
+gl_MANYWARN_ALL_GCC([warnings])
+# Set up the list of the pointless, undesired warnings.
+nw=
+nw="$nw -Wsystem-headers" # Don't let system headers trigger warnings
+nw="$nw -Wsuggest-attribute=pure" # ignore recommendations to use
+nw="$nw -Wsuggest-attribute=format" # attributes, most of these only
+nw="$nw -Wsuggest-attribute=const" # work in gcc
+nw="$nw -Wsuggest-attribute=noreturn"
+# Enable all GCC warnings not in this list.
+gl_MANYWARN_COMPLEMENT([warnings], [$warnings], [$nw])
+for w in $warnings; do
+ gl_WARN_ADD([$w])
+done
+
+# define an additional recursive make target to format the sources.
+# Also check if clang-format is installed
+AM_EXTRA_RECURSIVE_TARGETS([format-sources])
+AC_CHECK_PROG([SOURCE_FORMATTER], [clang-format], [clang-format])
+AM_CONDITIONAL([HAVE_SOURCE_FORMATTER], [test x$SOURCE_FORMATTER = xclang-format])
+
+# GNU help2man creates man pages from --help output; in many cases,
+# this is sufficient, and obviates the need to maintain man pages
+# separately. However, some developers do not have it so we do not
+# make its use mandatory.
+if test "x$cross_compiling" = xyes; then
+ AC_MSG_WARN([cannot generate manual pages while cross compiling])
+else
+ AC_CHECK_PROG([HELP2MAN], [help2man], [help2man])
+fi
+AM_CONDITIONAL([HAVE_HELP2MAN], [test x$HELP2MAN = xhelp2man])
+
+# Only run parts of the tests if we are cross compiling
+AM_CONDITIONAL([CROSS_COMPILING], [test "x$cross_compiling" = xyes])
+
+# Check for makeinfo version >= 5, required for building documentation.
+have_makeinfo_5=false
+AC_PROG_SED
+AC_CHECK_PROG([MAKEINFO_FOUND], [makeinfo], [yes])
+if test x"${MAKEINFO_FOUND}" = xyes
+then
+ MAKEINFO_VERSION_REQ=5
+ AC_MSG_CHECKING([for makeinfo version >= $MAKEINFO_VERSION_REQ])
+ MAKEINFO_VERSION=`makeinfo --version | sed -ne 's/^\(makeinfo\|texi2any\) .* \([[0-9]][[0-9]]*\)\.[[0-9]][[0-9]]*.*$/\2/p'`
+ if test x$MAKEINFO_VERSION = x -o 0$MAKEINFO_VERSION -lt $MAKEINFO_VERSION_REQ
+ then
+ AC_MSG_RESULT([no])
+ AC_MSG_WARN([Program 'makeinfo' version >= $MAKEINFO_VERSION_REQ is required. Documentation will not be built.])
+ else
+ AC_MSG_RESULT([yes])
+ have_makeinfo_5=true
+ fi
+else
+ AC_MSG_WARN([Missing program 'makeinfo', Documentation will not be built. Please install you you want documentation or refer to online resources.])
+fi
+AM_CONDITIONAL([HAVE_MAKEINFO_5], [test x$have_makeinfo_5 = xtrue])
+
+AC_ARG_ENABLE(ucs4,
+ AC_HELP_STRING(--enable-ucs4, Enable 4 byte-wide characters),
+ [AC_DEFINE([WIDECHARS_ARE_UCS4], [1], [Define if widechars are ucs4])],
+ [enable_ucs4=no])
+
+AC_MSG_CHECKING([whether 4 byte-wide characters should be supported])
+AC_MSG_RESULT($enable_ucs4)
+
+case "$enable_ucs4" in
+yes) WIDECHAR_TYPE='unsigned int';;
+*) WIDECHAR_TYPE='unsigned short int';;
+esac
+AC_SUBST(WIDECHAR_TYPE)
+AM_CONDITIONAL([HAVE_UCS4], [test x$enable_ucs4 = xyes])
+
+case $host in
+ *mingw* | *cygwin*)
+ CFLAGS="$CFLAGS -Wl,--add-stdcall-alias"
+ LDFLAGS="$LDFLAGS -avoid-version"
+ ;;
+esac
+
+AC_CANONICAL_HOST
+build_macosx=no
+case $host_os in
+ darwin*)
+ build_macosx=yes
+ ;;
+esac
+AM_CONDITIONAL([OSX], [test "$build_macosx" = "yes"])
+
+AC_CONFIG_FILES([
+ Makefile
+ doc/Makefile
+ man/Makefile
+ liblouis/Makefile
+ liblouis/liblouis.h
+ windows/Makefile
+ windows/include/Makefile
+ windows/utils/Makefile
+ tables/Makefile
+ liblouis.pc
+ tests/Makefile
+ tests/braille-specs/Makefile
+ tests/resolve_table.h
+ tests/tables/Makefile
+ tests/tables/emphclass/Makefile
+ tests/tables/moreTables/Makefile
+ tests/tables/resolve_table/Makefile
+ tests/tables/resolve_table/dir_1/Makefile
+ tests/tables/resolve_table/dir_1/dir_1.1/Makefile
+ tests/tables/resolve_table/dir_2/Makefile
+ tests/tablesWithMetadata/Makefile
+ tests/ueb_test_data/Makefile
+ tests/yaml/Makefile
+ python/Makefile
+ python/setup.py
+ python/louis/Makefile
+ tools/Makefile
+ tools/gnulib/Makefile
+ tools/lou_maketable.d/Makefile
+ tools/lou_maketable.d/lou_maketable
+ gnulib/Makefile])
+AC_OUTPUT
diff --git a/contrib/braille-input.el b/contrib/braille-input.el
new file mode 100644
index 0000000..df7c46a
--- /dev/null
+++ b/contrib/braille-input.el
@@ -0,0 +1,291 @@
+;;; braille-input.el --- A simple input method for braille
+
+;; Copyright (C) 2013 Swiss Library for the Blind, Visually Impaired and Print Disabled
+
+;; 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 the Free Software Foundation, either version 3 of the License,
+;; or (at your option) any later version.
+
+;; This file is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+
+;;; Code:
+
+;; This code is inspired by Vim unicode braille () and http://benizi.com/vim/braille.vim
+
+(robin-define-package "braille-numerical"
+ "A simple input method for braille."
+
+ ("b0" ?⠀)
+ ("b1" ?⠁)
+ ("b2" ?⠂)
+ ("b12" ?⠃)
+ ("b3" ?⠄)
+ ("b13" ?⠅)
+ ("b23" ?⠆)
+ ("b123" ?⠇)
+ ("b4" ?⠈)
+ ("b14" ?⠉)
+ ("b24" ?⠊)
+ ("b124" ?⠋)
+ ("b34" ?⠌)
+ ("b134" ?⠍)
+ ("b234" ?⠎)
+ ("b1234" ?⠏)
+ ("b5" ?⠐)
+ ("b15" ?⠑)
+ ("b25" ?⠒)
+ ("b125" ?⠓)
+ ("b35" ?⠔)
+ ("b135" ?⠕)
+ ("b235" ?⠖)
+ ("b1235" ?⠗)
+ ("b45" ?⠘)
+ ("b145" ?⠙)
+ ("b245" ?⠚)
+ ("b1245" ?⠛)
+ ("b345" ?⠜)
+ ("b1345" ?⠝)
+ ("b2345" ?⠞)
+ ("b12345" ?⠟)
+ ("b6" ?⠠)
+ ("b16" ?⠡)
+ ("b26" ?⠢)
+ ("b126" ?⠣)
+ ("b36" ?⠤)
+ ("b136" ?⠥)
+ ("b236" ?⠦)
+ ("b1236" ?⠧)
+ ("b46" ?⠨)
+ ("b146" ?⠩)
+ ("b246" ?⠪)
+ ("b1246" ?⠫)
+ ("b346" ?⠬)
+ ("b1346" ?⠭)
+ ("b2346" ?⠮)
+ ("b12346" ?⠯)
+ ("b56" ?⠰)
+ ("b156" ?⠱)
+ ("b256" ?⠲)
+ ("b1256" ?⠳)
+ ("b356" ?⠴)
+ ("b1356" ?⠵)
+ ("b2356" ?⠶)
+ ("b12356" ?⠷)
+ ("b456" ?⠸)
+ ("b1456" ?⠹)
+ ("b2456" ?⠺)
+ ("b12456" ?⠻)
+ ("b3456" ?⠼)
+ ("b13456" ?⠽)
+ ("b23456" ?⠾)
+ ("b123456" ?⠿)
+ ("b7" ?⡀)
+ ("b17" ?⡁)
+ ("b27" ?⡂)
+ ("b127" ?⡃)
+ ("b37" ?⡄)
+ ("b137" ?⡅)
+ ("b237" ?⡆)
+ ("b1237" ?⡇)
+ ("b47" ?⡈)
+ ("b147" ?⡉)
+ ("b247" ?⡊)
+ ("b1247" ?⡋)
+ ("b347" ?⡌)
+ ("b1347" ?⡍)
+ ("b2347" ?⡎)
+ ("b12347" ?⡏)
+ ("b57" ?⡐)
+ ("b157" ?⡑)
+ ("b257" ?⡒)
+ ("b1257" ?⡓)
+ ("b357" ?⡔)
+ ("b1357" ?⡕)
+ ("b2357" ?⡖)
+ ("b12357" ?⡗)
+ ("b457" ?⡘)
+ ("b1457" ?⡙)
+ ("b2457" ?⡚)
+ ("b12457" ?⡛)
+ ("b3457" ?⡜)
+ ("b13457" ?⡝)
+ ("b23457" ?⡞)
+ ("b123457" ?⡟)
+ ("b67" ?⡠)
+ ("b167" ?⡡)
+ ("b267" ?⡢)
+ ("b1267" ?⡣)
+ ("b367" ?⡤)
+ ("b1367" ?⡥)
+ ("b2367" ?⡦)
+ ("b12367" ?⡧)
+ ("b467" ?⡨)
+ ("b1467" ?⡩)
+ ("b2467" ?⡪)
+ ("b12467" ?⡫)
+ ("b3467" ?⡬)
+ ("b13467" ?⡭)
+ ("b23467" ?⡮)
+ ("b123467" ?⡯)
+ ("b567" ?⡰)
+ ("b1567" ?⡱)
+ ("b2567" ?⡲)
+ ("b12567" ?⡳)
+ ("b3567" ?⡴)
+ ("b13567" ?⡵)
+ ("b23567" ?⡶)
+ ("b123567" ?⡷)
+ ("b4567" ?⡸)
+ ("b14567" ?⡹)
+ ("b24567" ?⡺)
+ ("b124567" ?⡻)
+ ("b34567" ?⡼)
+ ("b134567" ?⡽)
+ ("b234567" ?⡾)
+ ("b1234567" ?⡿)
+ ("b8" ?⢀)
+ ("b18" ?⢁)
+ ("b28" ?⢂)
+ ("b128" ?⢃)
+ ("b38" ?⢄)
+ ("b138" ?⢅)
+ ("b238" ?⢆)
+ ("b1238" ?⢇)
+ ("b48" ?⢈)
+ ("b148" ?⢉)
+ ("b248" ?⢊)
+ ("b1248" ?⢋)
+ ("b348" ?⢌)
+ ("b1348" ?⢍)
+ ("b2348" ?⢎)
+ ("b12348" ?⢏)
+ ("b58" ?⢐)
+ ("b158" ?⢑)
+ ("b258" ?⢒)
+ ("b1258" ?⢓)
+ ("b358" ?⢔)
+ ("b1358" ?⢕)
+ ("b2358" ?⢖)
+ ("b12358" ?⢗)
+ ("b458" ?⢘)
+ ("b1458" ?⢙)
+ ("b2458" ?⢚)
+ ("b12458" ?⢛)
+ ("b3458" ?⢜)
+ ("b13458" ?⢝)
+ ("b23458" ?⢞)
+ ("b123458" ?⢟)
+ ("b68" ?⢠)
+ ("b168" ?⢡)
+ ("b268" ?⢢)
+ ("b1268" ?⢣)
+ ("b368" ?⢤)
+ ("b1368" ?⢥)
+ ("b2368" ?⢦)
+ ("b12368" ?⢧)
+ ("b468" ?⢨)
+ ("b1468" ?⢩)
+ ("b2468" ?⢪)
+ ("b12468" ?⢫)
+ ("b3468" ?⢬)
+ ("b13468" ?⢭)
+ ("b23468" ?⢮)
+ ("b123468" ?⢯)
+ ("b568" ?⢰)
+ ("b1568" ?⢱)
+ ("b2568" ?⢲)
+ ("b12568" ?⢳)
+ ("b3568" ?⢴)
+ ("b13568" ?⢵)
+ ("b23568" ?⢶)
+ ("b123568" ?⢷)
+ ("b4568" ?⢸)
+ ("b14568" ?⢹)
+ ("b24568" ?⢺)
+ ("b124568" ?⢻)
+ ("b34568" ?⢼)
+ ("b134568" ?⢽)
+ ("b234568" ?⢾)
+ ("b1234568" ?⢿)
+ ("b78" ?⣀)
+ ("b178" ?⣁)
+ ("b278" ?⣂)
+ ("b1278" ?⣃)
+ ("b378" ?⣄)
+ ("b1378" ?⣅)
+ ("b2378" ?⣆)
+ ("b12378" ?⣇)
+ ("b478" ?⣈)
+ ("b1478" ?⣉)
+ ("b2478" ?⣊)
+ ("b12478" ?⣋)
+ ("b3478" ?⣌)
+ ("b13478" ?⣍)
+ ("b23478" ?⣎)
+ ("b123478" ?⣏)
+ ("b578" ?⣐)
+ ("b1578" ?⣑)
+ ("b2578" ?⣒)
+ ("b12578" ?⣓)
+ ("b3578" ?⣔)
+ ("b13578" ?⣕)
+ ("b23578" ?⣖)
+ ("b123578" ?⣗)
+ ("b4578" ?⣘)
+ ("b14578" ?⣙)
+ ("b24578" ?⣚)
+ ("b124578" ?⣛)
+ ("b34578" ?⣜)
+ ("b134578" ?⣝)
+ ("b234578" ?⣞)
+ ("b1234578" ?⣟)
+ ("b678" ?⣠)
+ ("b1678" ?⣡)
+ ("b2678" ?⣢)
+ ("b12678" ?⣣)
+ ("b3678" ?⣤)
+ ("b13678" ?⣥)
+ ("b23678" ?⣦)
+ ("b123678" ?⣧)
+ ("b4678" ?⣨)
+ ("b14678" ?⣩)
+ ("b24678" ?⣪)
+ ("b124678" ?⣫)
+ ("b34678" ?⣬)
+ ("b134678" ?⣭)
+ ("b234678" ?⣮)
+ ("b1234678" ?⣯)
+ ("b5678" ?⣰)
+ ("b15678" ?⣱)
+ ("b25678" ?⣲)
+ ("b125678" ?⣳)
+ ("b35678" ?⣴)
+ ("b135678" ?⣵)
+ ("b235678" ?⣶)
+ ("b1235678" ?⣷)
+ ("b45678" ?⣸)
+ ("b145678" ?⣹)
+ ("b245678" ?⣺)
+ ("b1245678" ?⣻)
+ ("b345678" ?⣼)
+ ("b1345678" ?⣽)
+ ("b2345678" ?⣾)
+ ("b12345678" ?⣿))
+
+(register-input-method
+ "braille-numerical"
+ "braille"
+ 'robin-use-package
+ "braille"
+ "A simple numerical braille input method")
+
diff --git a/contrib/liblouis.el b/contrib/liblouis.el
new file mode 100644
index 0000000..3a9bafa
--- /dev/null
+++ b/contrib/liblouis.el
@@ -0,0 +1,141 @@
+;;; liblouis.el --- mode for editing liblouis translation tables
+
+;; Copyright (C) 2009, 2011 Christian Egli
+
+;; 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 the Free Software Foundation, either version 3 of the License,
+;; or (at your option) any later version.
+
+;; This file is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+
+;;; Code:
+
+(defvar liblouis-mode-hook nil
+ "Normal hook run when entering liblouis mode.")
+
+(defvar liblouis-mode-abbrev-table nil
+ "Abbrev table in use in liblouis mode buffers.")
+(define-abbrev-table 'liblouis-mode-abbrev-table ())
+
+(eval-after-load "compile"
+ '(add-to-list 'compilation-error-regexp-alist
+ ;; WARNING: foo.txt: line 13: section title out of sequence: expected level 3, got level 4
+ ;; ERROR: foo.txt: line 18: only book doctypes can contain level 0 sections
+ '("^\\(ERROR\\|WARNING\\|DEPRECATED\\): \\([^:]*\\): line \\([0-9]+\\):" 2 3)))
+
+(defconst liblouis-comment-regexp "\\(\\s-+.*\\)??")
+
+(defconst liblouis-font-lock-keywords
+ (list
+
+ ;; Comment Lines
+ (cons "^#.*$" 'font-lock-comment-face)
+
+ ;; Opcodes (with one word arg)
+ (list
+ (concat "^"
+ (regexp-opt
+ '("include" "locale" "noletsign" "noletsignbefore" "noletsignafter"
+ "nocont" "compbrl" "contraction" "emphclass") 'words)
+ "\\s-+\\([^ ]+\\)" liblouis-comment-regexp "$")
+ '(1 font-lock-keyword-face)
+ '(2 font-lock-constant-face)
+ '(3 font-lock-comment-face nil t))
+
+ ;; Opcodes (with one dot pattern arg)
+ (list
+ (concat "^"
+ (regexp-opt
+ '("numsign" "capsletter" "firstwordital"
+ "lastworditalbefore" "lastworditalafter"
+ "firstletterital" "lastletterital" "singleletterital"
+ "firstwordbold" "lastwordboldbefore" "lastwordboldafter"
+ "firstletterbold" "lastletterbold" "singleletterbold"
+ "firstwordunder" "lastwordunderbefore" "lastwordunderafter"
+ "firstletterunder" "lastletterunder" "singleletterunder"
+ "begcomp" "endcomp"
+ "begcaps" "endcaps" "letsign" "nocontractsign"
+ "exactdots") 'words)
+ "\\s-+\\([0-9-@]+\\)" liblouis-comment-regexp "$")
+ '(1 font-lock-keyword-face)
+ '(2 font-lock-constant-face)
+ '(3 font-lock-comment-face nil t))
+
+ ;; Opcodes (with two args)
+ (list
+ (concat "^"
+ (regexp-opt
+ '("comp6" "after" "before" "space" "punctuation" "digit" "lowercase" "uppercase"
+ "letter" "uplow" "litdigit" "sign" "math" "display" "repeated" "always"
+ "nocross" "syllable" "largesign" "word" "partword" "joinnum" "joinword"
+ "lowword" "sufword" "prfword" "begword" "begmidword" "midword" "midendword"
+ "endword" "prepunc" "postpunc" "begnum" "midnum" "endnum" "decpoint" "hyphen"
+ "begemphword" "endemphword" "begemphphrase" "lenemphphrase") 'words)
+ "\\s-+\\([^ ]+?\\)\\s-+\\([-0-9=@a-f]+\\)" liblouis-comment-regexp "$")
+ '(1 font-lock-keyword-face)
+ '(2 font-lock-string-face)
+ '(3 font-lock-constant-face)
+ '(4 font-lock-comment-face nil t))
+
+ ;; Opcodes (with three args)
+ (list
+ (concat "^"
+ (regexp-opt
+ '("endemphphrase") 'words)
+ "\\s-+\\([^ ]+?\\)\\s-+\\([^ ]+?\\)\\s-+\\([-0-9=@a-f]+\\)" liblouis-comment-regexp "$")
+ '(1 font-lock-keyword-face)
+ '(2 font-lock-string-face)
+ '(3 font-lock-string-face)
+ '(4 font-lock-constant-face)
+ '(5 font-lock-comment-face nil t))
+
+ ;; Opcodes (with two args where the second one is not a dot pattern)
+ (list
+ (concat "^"
+ (regexp-opt
+ '("class" "replace" "context" "correct" "pass2" "pass3" "pass4" ) 'words)
+ "\\s-+\\([^ ]+?\\)\\s-+\\([^ ]+\\)" liblouis-comment-regexp "$")
+ '(1 font-lock-keyword-face)
+ '(2 font-lock-string-face)
+ '(3 font-lock-constant-face)
+ '(4 font-lock-comment-face nil t))
+ ; FIXME: "multind" "lenitalphrase" lenboldphrase lenunderphrase "swapcd" "swapdd" "capsnocont"
+ )
+ "Default expressions to highlight in liblouis mode.")
+
+;;###autoload
+(define-derived-mode liblouis-mode prog-mode "liblouis"
+ "Major mode for editing liblouis translation tables.
+Turning on liblouis mode runs the normal hook `liblouis-mode-hook'.
+"
+ (modify-syntax-entry ?\' ".")
+ (modify-syntax-entry ?# "< b")
+ (modify-syntax-entry ?\n "> b")
+
+ (set (make-local-variable 'compile-command)
+ (concat "lou_checktable " buffer-file-name))
+
+ (set (make-local-variable 'require-final-newline) t)
+
+ (set (make-local-variable 'font-lock-defaults)
+ '(liblouis-font-lock-keywords
+ nil ; KEYWORDS-ONLY: no
+ nil ; CASE-FOLD: no
+ ((?_ . "w")) ; SYNTAX-ALIST
+ ))
+
+ (set (make-local-variable 'comment-start) "#")
+
+ (run-hooks 'liblouis-mode-hook))
+
+(provide 'liblouis-mode)
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..afefb06
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,19 @@
+doc_DATA = \
+ liblouis.html \
+ liblouis.txt
+
+EXTRA_DIST = \
+ liblouis.html \
+ liblouis.txt
+
+CLEANFILES = $(EXTRA_DIST)
+
+info_TEXINFOS = liblouis.texi
+
+# generate one big html file
+AM_MAKEINFOHTMLFLAGS = --no-headers --no-split
+
+SUFFIXES = .txt
+
+.texi.txt:
+ $(MAKEINFO) --plaintext $< -o $@
diff --git a/doc/liblouis.texi b/doc/liblouis.texi
new file mode 100644
index 0000000..fecfe65
--- /dev/null
+++ b/doc/liblouis.texi
@@ -0,0 +1,3821 @@
+\input texinfo
+@c %**start of header
+@setfilename liblouis.info
+@documentencoding UTF-8
+@include version.texi
+@settitle Liblouis User's and Programmer's Manual
+
+@dircategory Misc
+@direntry
+* Liblouis: (liblouis). A braille translator and back-translator
+@end direntry
+
+@finalout
+
+@c Macro definitions
+
+@defindex opcode
+
+@c Opcode.
+@macro opcode{name, args}
+@opcodeindex \name\
+@anchor{\name\ opcode}
+@item \name\ \args\
+@end macro
+
+@macro opcoderef{name}
+@code{\name\} opcode (@pxref{\name\ opcode,\name\,@code{\name\}})
+@end macro
+
+@c Opcode.
+@macro deprecatedopcode{name, args, replacement}
+@opcodeindex \name\
+@anchor{\name\ opcode}
+@item \name\ \args\
+This opcode is deprecated. Use the @opcoderef{\replacement\} instead.
+@end macro
+
+@copying
+This manual is for liblouis (version @value{VERSION}, @value{UPDATED}),
+a Braille Translation and Back-Translation Library derived from the
+Linux screen reader @acronym{BRLTTY}.
+
+@vskip 10pt
+
+@noindent
+Copyright @copyright{} 1999-2006 by the BRLTTY Team.
+
+@noindent
+Copyright @copyright{} 2004-2007 ViewPlus Technologies, Inc.
+@uref{www.viewplus.com}.
+
+@noindent
+Copyright @copyright{} 2007, 2009 Abilitiessoft, Inc.
+@uref{www.abilitiessoft.org}.
+
+@noindent
+Copyright @copyright{} 2014, 2016 Swiss Library for the Blind, Visually
+Impaired and Print Disabled. @uref{www.sbs.ch}.
+
+@vskip 10pt
+
+@quotation
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser (or library) General Public License
+(LGPL) as published by the Free Software Foundation; either version 3,
+or (at your option) any later version.
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser (or Library) General Public License LGPL for more details.
+
+You should have received a copy of the GNU Lesser (or Library) General
+Public License (LGPL) along with this program; see the file COPYING.
+If not, write to the Free Software Foundation, 51 Franklin Street,
+Fifth Floor, Boston, MA 02110-1301, USA.
+@end quotation
+@end copying
+
+@titlepage
+@title Liblouis User's and Programmer's Manual
+
+@subtitle for version @value{VERSION}, @value{UPDATED}
+@author by John J. Boyer
+
+@c The following two commands start the copyright page.
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@c Output the table of contents at the beginning.
+@contents
+
+@ifnottex
+@node Top
+@top Liblouis User's and Programmer's Manual
+
+@insertcopying
+@end ifnottex
+
+@menu
+* Introduction::
+* How to Write Translation Tables::
+* Notes on Back-Translation::
+* Table Metadata::
+* Testing Translation Tables interactively::
+* Automated Testing of Translation Tables::
+* Programming with liblouis::
+* Concept Index::
+* Opcode Index::
+* Function Index::
+* Program Index::
+
+@detailmenu
+ --- The Detailed Node Listing ---
+
+How to Write Translation Tables
+
+* Overview::
+* Hyphenation Tables::
+* Character-Definition Opcodes::
+* Braille Indicator Opcodes::
+* Emphasis Opcodes::
+* Special Symbol Opcodes::
+* Special Processing Opcodes::
+* Translation Opcodes::
+* Character-Class Opcodes::
+* Swap Opcodes::
+* The Context and Multipass Opcodes::
+* The correct Opcode::
+* The match Opcode::
+* Miscellaneous Opcodes::
+
+Emphasis Opcodes
+
+* Emphasis class::
+* Contexts::
+* Fallback behavior::
+* Computer braille::
+
+Contexts
+
+* None::
+* Letter::
+* Word::
+* Phrase::
+* Symbol::
+
+Testing Translation Tables interactively
+
+* lou_debug::
+* lou_trace::
+* lou_checktable::
+* lou_allround::
+* lou_translate (program)::
+* lou_checkhyphens::
+* lou_checkyaml::
+
+Programming with liblouis
+
+* Overview (library)::
+* Data structure of liblouis tables::
+* How tables are found::
+* Deprecation of the logging system::
+* lou_version::
+* lou_translateString::
+* lou_translate::
+* lou_backTranslateString::
+* lou_backTranslate::
+* lou_hyphenate::
+* lou_compileString::
+* lou_getTypeformForEmphClass::
+* lou_dotsToChar::
+* lou_charToDots::
+* lou_registerLogCallback::
+* lou_setLogLevel::
+* lou_logFile::
+* lou_logPrint::
+* lou_logEnd::
+* lou_setDataPath::
+* lou_getDataPath::
+* lou_getTable::
+* lou_findTable::
+* lou_indexTables::
+* lou_checkTable::
+* lou_readCharFromFile::
+* lou_free::
+* lou_charSize::
+* Python bindings::
+
+@end detailmenu
+@end menu
+
+@node Introduction
+@chapter Introduction
+
+Liblouis is an open-source braille translator and back-translator
+derived from the translation routines in the BRLTTY screen reader for
+Linux. It has, however, gone far beyond these routines. It is named in
+honor of Louis Braille. In Linux and Mac OSX it is a shared library,
+and in Windows it is a DLL. For installation instructions see the
+README file. Please report bugs and oddities to the mailing list,
+@email{liblouis-liblouisxml@@freelists.org}
+
+This documentation is derived from the BRLTTY manual, but
+it has been extensively rewritten to cover new features.
+
+@section Who is this manual for
+
+This manual has two main audiences: People who want to write or
+improve a braille translation table and people who want to use the
+braille translator library in their own programs. This manual is
+probably not for people who are looking for some turn-key braille
+translation software.
+
+@section How to read this manual
+
+If you are mostly interested in writing braille translation tables
+then you want to focus on @ref{How to Write Translation Tables}. You
+might want to look at @ref{Notes on Back-Translation} if you are
+interested in back-translation. Read @ref{Table Metadata} if you want
+to find out how you can augment your tables with metadata in order to
+make them discoverable by programs. Finally @ref{Testing Translation
+Tables interactively} and @ref{Automated Testing of Translation
+Tables} will show how your braille translation tables can be tested
+interactively and also in an automated fashion.
+
+If you want to use the braille translation library in your own program
+or you are interested in enhancing the braille translation library
+itself then you will want to look at @ref{Programming with liblouis}.
+
+@node How to Write Translation Tables
+@chapter How to Write Translation Tables
+
+For many languages there is already a translation table, so before
+creating a new table start by looking at existing tables to modify
+them as needed.
+
+Typically, a braille translation table consists of several parts.
+First are header and includes, in which you write what the table is
+for, license information and include tables you need for your table.
+
+Following this, you'll write various translation rules and lastly you
+write special rules to handle certain situations.
+
+@cindex Opcode
+A translation rule is composed of at least three parts: the opcode
+(translation command), character(s) and braille dots. An opcode is a
+command you give to a machine or a program to perform something on
+your behalf. In liblouis, an opcode tells it which rule to use when
+translating characters into braille. An operand can be thought of as
+parameters for the translation rule and is composed of two parts: the
+character or word to be translated and the braille dots.
+
+For example, suppose you want to read the word @samp{world} using
+braille dots @samp{456}, followed by the letter @samp{W} all the time.
+Then you'd write:
+
+@example
+always world 456-2456
+@end example
+
+The word @code{always} is an opcode which tells liblouis to always
+honor this translation, that is to say when the word @samp{world} (an
+operand) is encountered, always show braille dots @samp{456} followed
+by the letter @samp{w} (@samp{2456}).
+
+When you write any braille table for any language, we'd recommend
+working from some sort of official standard, and have a device or a
+program in which you can test your work.
+
+@menu
+* Overview::
+* Hyphenation Tables::
+* Character-Definition Opcodes::
+* Braille Indicator Opcodes::
+* Emphasis Opcodes::
+* Special Symbol Opcodes::
+* Special Processing Opcodes::
+* Translation Opcodes::
+* Character-Class Opcodes::
+* Swap Opcodes::
+* The Context and Multipass Opcodes::
+* The correct Opcode::
+* The match Opcode::
+* Miscellaneous Opcodes::
+@end menu
+
+@node Overview
+@section Overview
+
+Many translation (contraction) tables have already been made up. They
+are included in the distribution in the tables directory and can be
+studied as part of the documentation. Some of the more helpful (and
+normative) are listed in the following table:
+
+@table @file
+@item chardefs.cti
+Character definitions for U.S. tables
+@item compress.ctb
+Remove excessive whitespace
+@item en-us-g1.ctb
+Uncontracted American English
+@item en-us-g2.ctb
+Contracted or Grade 2 American English
+@item en-us-brf.dis
+Make liblouis output conform to BRF standard
+@item en-us-comp8.ctb
+8-dot computer braille for use in coding examples
+@item en-us-comp6.ctb
+6-dot computer braille
+@item nemeth.ctb
+Nemeth Code translation for use with liblouisutdml
+@item nemeth_edit.ctb
+Fixes errors at the boundaries of math and text
+
+@end table
+
+The names used for files containing translation tables are completely
+arbitrary. They are not interpreted in any way by the translator.
+Contraction tables may be 8-bit ASCII files, UTF-8, 16-bit big-endian
+Unicode files or 16-bit little-endian Unicode files. Blank lines are
+ignored. Any leading and trailing whitespace (any number of blanks
+and/or tabs) is ignored. Lines which begin with a number sign or hatch
+mark (@samp{#}) are ignored, i.e.@: they are comments. If the number
+sign is not the first non-blank character in the line, it is treated
+as an ordinary character. If the first non-blank character is
+less-than (@samp{<}) the line is also treated as a comment. This makes
+it possible to mark up tables as xhtml documents. Lines which are not
+blank or comments define table entries. The general format of a table
+entry is:
+
+@example
+opcode operands comments
+@end example
+
+Table entries may not be split between lines. The opcode is a mnemonic
+that specifies what the entry does. The operands may be character
+sequences, braille dot patterns or occasionally something else. They
+are described for each opcode, please @pxref{Opcode Index}. With some
+exceptions, opcodes expect a certain number of operands. Any text on
+the line after the last operand is ignored, and may be a comment. A
+few opcodes accept a variable number of operands. In this case a
+number sign (@samp{#}) begins a comment unless it is preceded by a
+backslash (@samp{\}).
+
+Here are some examples of table entries.
+
+@example
+# This is a comment.
+always world 456-2456 A word and the dot pattern of its contraction
+@end example
+
+Most opcodes have both a "characters" operand and a "dots" operand,
+though some have only one and a few have other types.
+
+@cindex Characters operand
+The characters operand consists of any combination of characters and
+escape sequences proceeded and followed by whitespace. Escape
+sequences are used to represent difficult characters. They begin with
+a backslash (@samp{\}). They are:
+
+@table @kbd
+@item \
+backslash
+@item \f
+form feed
+@item \n
+new line
+@item \r
+carriage return
+@item \s
+blank (space)
+@item \t
+horizontal tab
+@item \v
+vertical tab
+@item \e
+"escape" character (hex 1b, dec 27)
+@item \xhhhh
+4-digit hexadecimal value of a character
+
+@end table
+
+If liblouis has been compiled for 32-bit Unicode the following are
+also recognized.
+
+@table @kbd
+@item \yhhhhh
+5-digit (20 bit) character
+@item \zhhhhhhhh
+Full 32-bit value.
+
+Please take a look at the
+@url{https://unicode.org/Public/UNIDATA/,public directory of the
+Unicode Character Database} as well as at the
+@url{https://unicode.org/Public/UNIDATA/NamesList.txt,Unicode names
+list with their code points} to figure out the corresponding Unicode
+code point for a given Unicode character.
+
+@end table
+
+@cindex Dots operand
+The dots operand is a braille dot pattern. The real braille dots, 1
+through 8, must be specified with their standard numbers.
+
+@cindex Virtual dots
+@anchor{virtual dots}
+liblouis recognizes @emph{virtual dots}, which are used for special
+purposes, such as distinguishing accent marks. There are seven virtual
+dots. They are specified by the number 9 and the letters @samp{a}
+through @samp{f}.
+
+@cindex Multi-cell dot pattern
+For a multi-cell dot pattern, the cell specifications must be
+separated from one another by a dash (@samp{-}). For example, the
+contraction for the English word @samp{lord} (the letter @samp{l}
+preceded by dot 5) would be specified as @samp{5-123}. A space may be
+specified with the special dot number 0.
+
+An opcode which is helpful in writing translation tables is
+@code{include}. Its format is:
+
+@example
+include filename
+@end example
+
+It reads the file indicated by @code{filename} and incorporates or
+includes its entries into the table. Included files can include other
+files, which can include other files, etc. For an example, see what
+files are included by the entry @code{include en-us-g1.ctb} in the table
+@file{en-us-g2.ctb}. If the included file is not in the same directory
+as the main table, use a full path name for filename. Tables can also be
+specified in a table list, in which the table names are separated by
+commas and given as a single table name in calls to the translation
+functions.
+
+The order of the various types of opcodes or table entries is
+important. Character-definition opcodes should come first. However, if
+the optional @opcoderef{display} is used it should precede
+character-definition opcodes. Braille-indicator opcodes should come
+next. Translation opcodes should follow. The @opcoderef{context} is a
+translation opcode, even though it is considered along with the
+multipass opcodes. These latter should follow the translation opcodes.
+The @opcoderef{correct} can be used anywhere after the
+character-definition opcodes, but it is probably a good idea to group
+all @code{correct} opcodes together. The @opcoderef{include} can be
+used anywhere, but the order of entries in the combined table must
+conform to the order given above. Within each type of opcode, the
+order of entries is generally unimportant. Thus the translation
+entries can be grouped alphabetically or in any other order that is
+convenient. Hyphenation tables may be specified either with an
+@code{include} opcode or as part of a table list. They should come after
+everything else.
+
+@node Hyphenation Tables
+@section Hyphenation Tables
+
+Hyphenation tables are necessary to make opcodes such as the
+@opcoderef{nocross} function properly. There are no opcodes for
+hyphenation table entries because these tables have a special format.
+Therefore, they cannot be specified as part of an ordinary table.
+Rather, they must be included using the @opcoderef{include} or as part
+of a table list. The liblouis hyphenation algorithm was adopted from the
+one used by OpenOffice. Note that Hyphenation tables must follow
+character definitions and should preferably be the last. For an example
+of a hyphenation table, see @file{hyph_en_US.dic}.
+
+@node Character-Definition Opcodes
+@section Character-Definition Opcodes
+
+These opcodes are needed to define attributes such as digit,
+punctuation, letter, etc. for all characters and their dot patterns.
+liblouis has no built-in character definitions, but such definitions
+are essential to the operation of the @opcoderef{context}, the
+@opcoderef{correct}, the multipass opcodes and the back-translator. If
+the dot pattern is a single cell, it is used to define the mapping
+between dot patterns and characters, unless a @opcoderef{display} for
+that character-dot-pattern pair has been used previously. If only a
+single-cell dot pattern has been given for a character, that dot
+pattern is defined with the character's own attributes.
+
+You may have multiple definitions of a character using the same or
+different dot patterns. If you use different dot patterns for the same
+character, only the first dot pattern will be used during forward
+translation. However, during back-translation, all the relevant dot
+patterns will back-translate to the character you defined.
+
+You can also define a character multiple times using the same dot
+pattern for the character, but using different character classes. The
+following example would define the character @samp{*} (star) as both
+@opcoderef{math} and @opcoderef{sign}.
+
+@example
+math * 16
+sign * 16
+@end example
+
+Likewise, you can define multiple characters as the same dot pattern.
+The characters you define this way will be forward translated to the
+same dot pattern. However, when back-translating, the dot pattern will
+always back-translate to the first character that was defined with
+this pattern.
+
+This technique may be useful when defining characters that have one
+representation in the Windows character set (CP1252) and another
+representation in the Unicode character set, e.g. the Euro sign,
+@samp{€}. It may also be of use when you have to define several
+variants of the same letter with different accents, which may be
+represented in your Braille code by the same dot pattern. This is a
+very common practice for accented letters that are foreign to the
+Braille code. In the following example using the @opcoderef{uplow}
+opcode, both e acute (@samp{é}) and e grave (@samp{è}) are defined as
+dot 4 followed by dots 1 and 5.
+
+@example
+uplow \x00c9\x00e9 4-15 # E acute
+uplow \x00c8\x00e8 4-15 # E grave
+@end example
+
+In this example, the dot pattern would always back-translate to e
+acute, since this is the first definition. You could use the
+@opcoderef{correct} opcode to correct at least the most common errors
+on that account. However, there is no fail-safe way to know what
+accented letter to use when you back-translate from a dot pattern
+representing more than one variant.
+
+@table @code
+@opcode{space, character dots}
+Defines a character as a space and also defines the dot pattern as
+such. for example:
+
+@example
+space \s 0 \s is the escape sequence for blank; 0 means no dots.
+@end example
+
+@opcode{punctuation, character dots}
+Associates a punctuation mark in the particular language with a
+braille representation and defines the character and dot pattern as
+punctuation. For example:
+
+@example
+punctuation . 46 dot pattern for period in NAB computer braille
+@end example
+
+@opcode{digit, character dots}
+Associates a digit with a dot pattern and defines the character as a
+digit. For example:
+
+@example
+digit 0 356 NAB computer braille
+@end example
+
+@opcode{uplow, characters dots [@comma{}dots]}
+The characters operand must be a pair of letters, of which the first
+is uppercase and the second lowercase. The first dots suboperand
+indicates the dot pattern for the upper-case letter. It may have more
+than one cell. The second dots suboperand must be separated from the
+first by a comma and is optional, as indicated by the square brackets.
+If present, it indicates the dot pattern for the lower-case letter. It
+may also have more than one cell. If the second dots suboperand is not
+present the first is used for the lower-case letter as well as the
+upper-case letter. This opcode is needed because not all languages
+follow a consistent pattern in assigning Unicode codes to upper and
+lower case letters. It should be used even for languages that do. The
+distinction is important in the forward translator. for example:
+
+@example
+uplow Aa 17,1
+@end example
+
+@opcode{grouping, name characters dots @comma{}dots}
+This opcode is used to indicate pairs of grouping symbols used in
+processing mathematical expressions. These symbols are usually
+generated by the MathML interpreter in liblouisutdml. They are used in
+multipass opcodes. The name operand must contain only letters (a-z and
+A-Z). The letters may be upper or lower-case but the case matters. The
+characters operand must contain exactly two Unicode characters. The
+dots operand must contain exactly two braille cells, separated by a
+comma. Note that grouping dot patterns also need to be declared with
+the @opcoderef{exactdots}. The characters may need to be declared with
+the @opcoderef{math}.
+
+@example
+grouping mrow \x0001\x0002 1e,2e
+grouping mfrac \x0003\x0004 3e,4e
+@end example
+
+@opcode{letter, character dots}
+Associates a letter in the language with a braille representation and
+defines the character as a letter. This is intended for letters which
+are neither uppercase nor lowercase.
+
+@opcode{lowercase, character dots}
+Associates a character with a dot pattern and defines the character as
+a lowercase letter. Both the character and the dot pattern have the
+attributes lowercase and letter.
+
+@opcode{uppercase, character dots}
+Associates a character with a dot pattern and defines the character as
+an uppercase letter. Both the character and the dot pattern have the
+attributes uppercase and letter. @code{lowercase} and @code{uppercase}
+should be used when a letter has only one case. Otherwise use the
+@opcoderef{uplow}.
+
+@opcode{litdigit, digit dots}
+Associates a digit with the dot pattern which should be used to
+represent it in literary texts. For example:
+
+@example
+litdigit 0 245
+litdigit 1 1
+@end example
+
+@opcode{sign, character dots}
+Associates a character with a dot pattern and defines both as a sign.
+This opcode should be used for things like at sign (@samp{@@}),
+percent (@samp{%}), dollar sign (@samp{$}), etc. Do not use it to
+define ordinary punctuation such as period and comma. For example:
+
+@example
+sign % 4-25-1234 literary percent sign
+@end example
+
+@opcode{math, character dots}
+Associates a character and a dot pattern and defines them as a
+mathematical symbol. It should be used for less than (@samp{<}),
+greater than(@samp{>}), equals(@samp{=}), plus(@samp{+}), etc. For
+example:
+
+@example
+math + 346 plus
+@end example
+
+@end table
+
+@node Braille Indicator Opcodes
+@section Braille Indicator Opcodes
+
+Braille indicators are dot patterns which are inserted into the
+braille text to indicate such things as capitalization, italic type,
+computer braille, etc. The opcodes which define them are followed only
+by a dot pattern, which may be one or more cells.
+
+@table @code
+@opcode{capsletter, dots}
+The dot pattern which indicates capitalization of a single letter. In
+English, this is dot 6. For example:
+
+@example
+capsletter 6
+@end example
+
+@opcode{begcapsword, dots}
+The dot pattern which begins a block of capital letters at the
+beginning or within a word. The block is automatically terminated
+by any character that is not a capital letter, e.g. small letters,
+punctuation, numbers etc.
+
+Apart from capital letters, you can define a list of characters that
+can appear within a word in capitals without terminating the block.
+Do this by using the @opcoderef{capsmodechars} opcode.
+
+Example:
+
+@example
+begcapsword 6-6
+@end example
+
+@opcode{endcapsword, dots}
+The dot pattern which ends a block of capital letters within a word.
+It is used in cases where the block is not terminated automatically
+by a word boundary, a number or punctuation. A common case is when
+an uppercase block is followed directly by a lowercase letter.
+
+For example:
+
+@example
+endcapsword 6-3
+@end example
+
+@opcode{capsmodechars, characters}
+
+Normally, any character other than a capital letter will cancel the
+@opcoderef{begcapsword} indicator. However, by using the
+@code{capsmodechars} opcode, you can specify a list of characters
+that are legal within a capitalized word. In some Braille codes,
+this might be the case for the hyphen character, @samp{-}.
+
+Example:
+
+@example
+capsmodechars -
+@end example
+
+@opcode{begcaps, dots}
+The dot pattern which begins a block of capital letters defined by the
+provided @code{typeform} without regard for any other rules.
+This construct is sometimes also called a capsphrase. It is used
+in some Braille codes to mark a whole phrase or sentence as capital
+letters. The block can contain capital letters as well as
+none-alphabetic characters, punctuation, numbers etc. The
+block is terminated when a small letter is encountered or at the end of the input string.
+
+Example:
+
+@example
+begcaps 6-6-6
+@end example
+
+@opcode{endcaps, dots}
+The dot pattern which ends a block of capital letters defined by the
+provided @code{typeform} without regard for any other rules. For
+example:
+
+@example
+endcaps 6-3
+@end example
+
+@opcode{letsign, dots}
+This indicator is needed in Grade 2 to show that a single letter is
+not a contraction. It is also used when an abbreviation happens to be
+a sequence of letters that is the same as a contraction. For example:
+
+@example
+letsign 56
+@end example
+
+@opcode{noletsign, letters}
+
+The letters in the operand will not be proceeded by a letter sign.
+More than one @code{noletsign} opcode can be used. This is equivalent
+to a single entry containing all the letters. In addition, if a single
+letter, such as @samp{a} in English, is defined as a @code{word}
+(@pxref{word opcode,word,@code{word}}) or @code{largesign}
+(@pxref{largesign opcode,largesign,@code{largesign}}), it will be
+treated as though it had also been specified in a @code{noletsign}
+entry.
+
+@opcode{noletsignbefore, characters}
+If any of the characters proceeds a single letter without a space a
+letter sign is not used. By default the characters apostrophe
+(@samp{'}) and period (@samp{.}) have this property. Use of a
+@code{noletsignbefore} entry cancels the defaults. If more than one
+@code{noletsignbefore} entry is used, the characters in all entries
+are combined.
+
+@opcode{noletsignafter, characters}
+If any of the characters follows a single letter without a space a
+letter sign is not used. By default the characters apostrophe
+(@samp{'}) and period (@samp{.}) have this property. Use of a
+@code{noletsignafter} entry cancels the defaults. If more than one
+@code{noletsignafter} entry is used the characters in all entries are
+combined.
+
+@opcode{nocontractsign, dots}
+
+The dots in this opcode are used to indicate a letter or a sequence of
+letters that are not a contraction, e.g. @samp{CD}. The opcode is
+similar to the @opcoderef{letsign}.
+
+@c FIXME: In what way is the nocontractsign opcode different from the
+@c letsign opcode, apart from apparently being a more focused version of
+@c letsign?
+
+@opcode{numsign, dots}
+The translator inserts this indicator before numbers made up of digits
+defined with the @opcoderef{litdigit} to show that they are a number
+and not letters or some other symbols. A number is terminated when a
+space, a letter or any other none-@opcoderef{litdigit} character is
+encountered.
+
+You can define characters or strings to be part of a number by using
+the @opcoderef{midnum} opcode, the @opcoderef{numericmodechars} opcode
+or the @opcoderef{midendnumericmodechars} opcode.
+
+Example:
+
+@example
+numsign 3456
+@end example
+
+@opcode{numericnocontchars, characters}
+
+This opcode specifies the characters that require a
+@opcoderef{nocontractsign} if they appear after a number with no
+intervening space, e.g. @samp{1a} or @samp{2-B}.
+
+These characters will typically be the letters a-j, which usually
+constitute the literary digits (see @opcoderef{litdigit}). However,
+in some Braille codes, all letters fall in this category.
+
+Please, note that this opcode is case sensitive. So, if you need a
+@opcoderef{nocontractsign} to also appear before the capital letters
+A-j, you should include these letters in the definition. This is
+especially relevant if you are also using the @opcoderef{begcaps}
+and @opcoderef{endcaps} opcodes. In this case, you might otherwise
+end up having numbers immediately followed by capital letters with no
+indicator between.
+
+Example:
+
+@example
+numericnocontchars abcdefghij
+@end example
+
+@opcode{numericmodechars, characters}
+
+@opcode{midendnumericmodechars, characters}
+
+Any of these characters can appear within a number without terminating
+the effect of the number sign (@pxref{numsign
+opcode,numsign,@code{numsign}}). In other words, they don't cancel
+numeric mode.
+
+The difference between the two opcodes is that
+@opcoderef{numericmodechars} characters can appear anywhere in a
+number whereas @opcoderef{midendnumericmodechars} characters can
+appear only in the middle or at the end of a number. Like
+@code{midendnumericmodechars}, @code{numericmodechars} characters keep
+numeric mode active, but in addition they activate numeric mode
+immediately when at least one digit follows, and the number sign will
+precede the @code{numericmodechars} character in this case.
+
+Example:
+
+@example
+numericmodechars .,
+midendnumericmodechars -/
+@end example
+
+@end table
+
+@node Emphasis Opcodes
+@section Emphasis Opcodes
+
+In many braille systems emphasis such as bold, italics or underline is
+indicated using special dot patterns that mark the start and often
+also the end. For some languages these braille indicators differ
+depending on the context, i.e.@: here is an separate indicator for an
+emphasized word and another one for an emphasized phrase. To
+accommodate for all these usage scenarios liblouis provides a number of
+opcodes for various contexts.
+
+At the same time some braille systems use different indicators for
+different kinds of emphasis while others know only one kind of
+emphasis. For that reason liblouis doesn't hard code any emphasis but
+the table author defines which kind of emphasis exist for a specific
+language using the @opcoderef{emphclass} opcode.
+
+@menu
+* Emphasis class::
+* Contexts::
+* Fallback behavior::
+* Computer braille::
+@end menu
+
+@node Emphasis class
+@subsection Emphasis class
+
+The @code{emphclass} opcode defines the classes of emphasis that are
+relevant for a particular language. For all emphasis that need special
+indicators an emphasis class has to be declared.
+
+@table @code
+@opcode{emphclass, <emphasis class>}
+Define an emphasis class to be used later in other emphasis related
+opcodes in the table.
+
+@example
+emphclass italic
+emphclass underline
+emphclass bold
+emphclass transnote
+@end example
+
+@end table
+
+@node Contexts
+@subsection Contexts
+
+In order to understand the capabilities of Liblouis for emphasis
+handling we have to look at the different contexts that are supported.
+
+@menu
+* None::
+* Letter::
+* Word::
+* Phrase::
+* Symbol::
+@end menu
+
+@node None
+@subsubsection None
+
+For some languages there is no such concept as contexts. Emphasis is
+always handled the same regardless of context. There is simply an
+indicator for the beginning of emphasis and another one for the end of
+the emphasis.
+
+@table @code
+@opcode{begemph, <emphasis class> <dot pattern>}
+Braille dot pattern to indicate the beginning of emphasis.
+
+@example
+begemph italic 46-3
+@end example
+
+@opcode{endemph, <emphasis class> <dot pattern>}
+Braille dot pattern to indicate the end of emphasis.
+
+@example
+endemph italic 46-36
+@end example
+
+@end table
+
+@node Letter
+@subsubsection Letter
+
+Some languages have special indicators for single letter emphasis.
+
+@table @code
+@opcode{emphletter, <emphasis class> <dot pattern>}
+Braille dot pattern to indicate that the next character is emphasized.
+
+@example
+emphletter italic 46-25
+@end example
+
+@end table
+
+@node Word
+@subsubsection Word
+
+Many languages have special indicators for emphasized words. Usually
+they start at the beginning of the word and and implicitly, i.e.@:
+without a closing indicator at the end of the word. There are also use
+cases where the emphasis starts in the middle of the word and an
+explicit closing indicator is required.
+
+@table @code
+@opcode{begemphword, <emphasis class> <dot pattern>}
+Braille dot pattern to indicate the beginning of an emphasized word
+or the beginning of emphasized characters within a word.
+
+@example
+begemphword underline 456-36
+@end example
+
+@opcode{endemphword, <emphasis class> <dot pattern>}
+Generally emphasis with word context ends when the word ends. However
+when an indication is required to close a word emphasis then this
+opcode defines the Braille dot pattern that indicates the end of a word
+emphasis.
+
+@example
+endemphword transnote 6-3
+@end example
+
+If emphasis ends in the middle of a word the Braille dot pattern
+defined in this opcode is also used.
+
+@opcode{emphmodechars, characters}
+
+Normally, only space characters will cancel the
+@opcoderef{begemphword} indicator. However, by using the
+@code{emphmodechars} opcode, you can specify the list of characters
+that are legal within a emphasized word. If @code{emphmodechars} is
+specified, any character that is not in this list and is not a
+@code{letter} will cancel the @opcoderef{begemphword} indicator.
+
+Example:
+
+@example
+emphmodechars -
+@end example
+
+@end table
+
+@node Phrase
+@subsubsection Phrase
+
+Many languages have a concept of a phrase where the emphasis is valid
+for a number of words. The beginning of the phase is indicated with a
+braille dot pattern and a closing indicator is put before or after the
+last word of the phrase. To define how many words are considered a
+phrase in your language use the @opcoderef{lenemphphrase}.
+
+@table @code
+@opcode{begemphphrase, <emphasis class> <dot pattern>}
+Braille dot pattern to indicate the beginning of a phrase.
+
+@example
+begemphphrase bold 456-46-46
+@end example
+
+@c define a special opcode macro that can handle the two-word nature
+@c of the endemphphrase opcode
+@macro endemphphraseopcode{where}
+@opcodeindex endemphphrase \where\
+@anchor{endemphphrase \where\ opcode}
+@item endemphphrase <emphasis class> \where\ <dot pattern>
+@end macro
+
+@endemphphraseopcode{before}
+Braille dot pattern to indicate the end of a phrase. The closing indicator
+will be placed before the last word of the phrase.
+
+@example
+endemphphrase bold before 456-46
+@end example
+
+@endemphphraseopcode{after}
+Braille dot pattern to indicate the end of a phrase. The closing
+indicator will be placed after the last word of the phrase. If both
+@code{endemphphrase <emphasis class> before} and @code{endemphphrase
+<emphasis class> after} are defined an error will be signaled.
+
+@example
+endemphphrase underline after 6-3
+@end example
+
+@opcode{lenemphphrase, <emphasis class> <number>}
+Define how many words are required before a sequence of words is
+considered a phrase.
+
+@example
+lenemphphrase underline 3
+@end example
+
+@end table
+
+@node Symbol
+@subsubsection Symbol
+UEB has a concept of symbols that need special indication. When the
+translator detects an emphasis sequence that needs to be indicated
+with the rules for a symbol then it will use the dots defined with the
+@opcoderef{emphletter}. To indicate the end of the symbol it will use
+the dots defined in the @opcoderef{endemphword}.
+
+@node Fallback behavior
+@subsection Fallback behavior
+
+Many braille systems either handle emphasis using no contexts or
+otherwise by employing a combination of the letter, word and phrase
+contexts. So if a table defines any opcodes for the letter, word or
+phrase contexts then liblouis will signal an error for opcodes that
+define emphasis with no context. In other words contrary to previous
+versions of liblouis there is no fallback behavior.
+
+As a consequence, there will only be emphasis for a context when the
+table defines it. So for example when defining a braille dot pattern
+for phrases and not for words liblouis will not indicate emphasis on
+words that aren't part of a phrase.
+
+@node Computer braille
+@subsection Computer braille
+
+For computer braille there are only two braille indicators, for the
+beginning and end of a sequence of characters to be rendered in
+computer braille. Such a sequence may also have other emphasis. The
+computer braille indicators are applied not only when computer braille
+is indicated in the @code{typeform} parameter, but also when a
+sequence of characters is determined to be computer braille because it
+contains a subsequence defined by the @opcoderef{compbrl}.
+
+@node Special Symbol Opcodes
+@section Special Symbol Opcodes
+
+These opcodes define certain symbols, such as the decimal point, which
+require special treatment.
+
+@table @code
+@opcode{decpoint, character dots}
+
+This opcode defines the decimal point. It is useful if your Braille
+code requires the decimal separator to show as a dot pattern different
+from the normal representation of this character, i.e.@: period or
+comma. In addition, it allows the notation @samp{.001} to be
+translated correctly. This notation is common in some languages
+instead of @samp{0.001} (no leading 0). When you use the
+@code{decpoint} opcode, the decimal point will be taken to be part of
+the number and correctly preceded by number sign.
+
+The character operand must have only one character. For example, in
+@file{en-us-g1.ctb} we have:
+
+@example
+decpoint . 46
+@end example
+
+@opcode{hyphen, character dots}
+This opcode defines the hyphen, that is, the character used in
+compound words such as @samp{have-nots}. The back-translator uses it
+to determine the end of individual words.
+
+@end table
+
+@node Special Processing Opcodes
+@section Special Processing Opcodes
+
+These opcodes cause special processing to be carried out.
+
+@table @code
+@opcode{capsnocont,}
+This opcode has no operands. If it is specified, words or parts of
+words in all caps are not contracted. This is needed for languages
+such as Norwegian.
+
+Note: If you use the capsnocont opcode and do not define the
+ @opcoderef{begcapsword} indicator, every cap will be marked with the
+@opcoderef{capsletter} indicator. This is useful if you need to process caps
+separately in a later pass.
+
+@end table
+
+@node Translation Opcodes
+@section Translation Opcodes
+
+These opcodes define the braille representations for character
+sequences. Each of them defines an entry within the contraction table.
+These entries may be defined in any order except, as noted below, when
+they define alternate representations for the same character sequence.
+
+Each of these opcodes specifies a condition under which the
+translation is legal, and each also has a characters operand and a
+dots operand. The text being translated is processed strictly from
+left to right, character by character, with the most eligible entry
+for each position being used. If there is more than one eligible entry
+for a given position in the text, then the one with the longest
+character string is used. If there is more than one eligible entry for
+the same character string, then the one defined first is is tested for
+legality first. (This is the only case in which the order of the
+entries makes a difference.)
+
+The characters operand is a sequence or string of characters preceded
+and followed by whitespace. Each character can be entered in the
+normal way, or it can be defined as a four-digit hexadecimal number
+preceded by @samp{\x}.
+
+The dots operand defines the braille representation for the characters
+operand. It may also be specified as an equals sign (@samp{=}). This
+means that the the default representation for each character
+(@pxref{Character-Definition Opcodes}) within the sequence is to be
+used. It is an error if not all the characters in the rule have been
+previously defined in a character-definition rule. Note that the
+@samp{=} shortcut for dot patterns has a known bug@footnote{See
+@url{https://github.com/liblouis/liblouis/issues/500#issuecomment-365753137}.}
+that might cause problems when back-translating.
+
+In what follows the word @samp{characters} means a sequence of one or
+more consecutive letters between spaces and/or punctuation marks.
+
+@table @code
+
+@opcode{noback, opcode ...}
+This is an opcode prefix, that is to say, it modifies the operation of
+the opcode that follows it on the same line. noback specifies that
+back-translation is not to use information on this line.
+
+@example
+noback always ;\s; 0
+@end example
+
+@opcode{nofor, opcode ...}
+This is an opcode prefix which modifies the operation of the opcode
+following it on the same line. nofor specifies that forward translation
+is not to use the information on this line.
+
+@opcode{compbrl, characters}
+If the characters are found within a block of text surrounded by
+whitespace the entire block is translated according to the default
+braille representations defined by the @ref{Character-Definition
+Opcodes}, if 8-dot computer braille is enabled or according to the dot
+patterns given in the @opcoderef{comp6}, if 6-dot computer braille is
+enabled. For example:
+
+@example
+compbrl www translate URLs in computer braille
+@end example
+
+@opcode{comp6, character dots}
+This opcode specifies the translation of characters in 6-dot computer
+braille. It is necessary because the translation of a single character
+may require more than one cell. The first operand must be a character
+with a decimal representation from 0 to 255 inclusive. The second
+operand may specify as many cells as necessary. The opcode is somewhat
+of a misnomer, since any dots, not just dots 1 through 6, can be
+specified. This even includes virtual dots (@pxref{virtual dots}).
+
+@opcode{nocont, characters}
+Like @code{compbrl}, except that the string is uncontracted.
+@opcoderef{prepunc} and @opcoderef{postpunc} rules are applied,
+however. This is useful for specifying that foreign words should not
+be contracted in an entire document.
+
+@opcode{replace, characters @{characters@}}
+Replace the first set of characters, no matter where they appear, with
+the second. Note that the second operand is @emph{NOT} a dot pattern.
+It is also optional. If it is omitted the character(s) in the first
+operand will be discarded. This is useful for ignoring characters. It
+is possible that the "ignored" characters may still affect the
+translation indirectly. Therefore, it is preferable to use
+@opcoderef{correct}.
+
+@opcode{always, characters dots}
+Replace the characters with the dot pattern no matter where they
+appear. Do @emph{NOT} use an entry such as @code{always a 1}. Use the
+@code{uplow}, @code{letter}, etc. character definition opcodes
+instead. For example:
+
+@example
+always world 456-2456 unconditional translation
+@end example
+
+@opcode{repeated, characters dots}
+Replace the characters with the dot pattern no matter where they
+appear. Ignore any consecutive repetitions of the same character
+sequence. This is useful for shortening long strings of spaces or
+hyphens or periods. For example:
+
+@example
+repeated --- 36-36-36 shorten separator lines made with hyphens
+@end example
+
+@opcode{repword, characters dots}
+When characters are encountered check to see if the word before this
+string matches the word after it. If so, replace characters with dots
+and eliminate the second word and any word following another
+occurrence of characters that is the same. This opcode is used in
+Malaysian braille. In this case the rule is:
+
+@example
+repword - 123456
+@end example
+
+@opcode{largesign, characters dots}
+Replace the characters with the dot pattern no matter where they
+appear. In addition, if two words defined as large signs follow each
+other, remove the space between them. For example, in
+@file{en-us-g2.ctb} the words @samp{and} and @samp{the} are both
+defined as large signs. Thus, in the phrase @samp{the cat and the dog}
+the space would be deleted between @samp{and} and @samp{the}, with the
+result @samp{the cat andthe dog}. Of course, @samp{and} and @samp{the}
+would be properly contracted. The term @code{largesign} is a bit of
+braille jargon that pleases braille experts.
+
+@opcode{word, characters dots}
+Replace the characters with the dot pattern if they are a word, that
+is, are surrounded by whitespace and/or punctuation.
+
+@opcode{syllable, characters dots}
+As its name indicates, this opcode defines a "syllable" which must be
+represented by exactly the dot patterns given. Contractions may not
+cross the boundaries of this "syllable" either from left or right. The
+character string defined by this opcode need not be a lexical
+syllable, though it usually will be. The equal sign in the following
+example means that the the default representation for each character
+within the sequence is to be used (@pxref{Translation Opcodes}):
+
+@example
+syllable horse = sawhorse, horseradish
+@end example
+
+@opcode{nocross, characters dots}
+Replace the characters with the dot pattern if the characters are all
+in one syllable (do not cross a syllable boundary). For this opcode to
+work, a hyphenation table must be included. If this is not done,
+@code{nocross} behaves like the @opcoderef{always}. For example, if
+the English Grade 2 table is being used and the appropriate
+hyphenation table has been included @code{nocross sh 146} will cause
+the @samp{sh} in @samp{monkshood} not to be contracted.
+
+@opcode{joinword, characters dots}
+Replace the characters with the dot pattern if they are a word which
+is followed by whitespace and a letter. In addition remove the
+whitespace. For example, @file{en-us-g2.ctb} has @code{joinword to
+235}. This means that if the word @samp{to} is followed by another
+word the contraction is to be used and the space is to be omitted. If
+these conditions are not met, the word is translated according to any
+other opcodes that may apply to it.
+
+@opcode{lowword, characters dots}
+Replace the characters with the dot pattern if they are a word
+preceded and followed by whitespace. No punctuation either before or
+after the word is allowed. The term @code{lowword} derives from the
+fact that in English these contractions are written in the lower part
+of the cell. For example:
+
+@example
+lowword were 2356
+@end example
+
+@opcode{contraction, characters}
+If you look at @file{en-us-g2.ctb} you will see that some words are
+actually contracted into some of their own letters. A famous example
+among braille transcribers is @samp{also}, which is contracted as
+@samp{al}. But this is also the name of a person. To take another
+example, @samp{altogether} is contracted as @samp{alt}, but this is
+the abbreviation for the alternate key on a computer keyboard.
+Similarly @samp{could} is contracted into @samp{cd}, but this is the
+abbreviation for compact disk. To prevent confusion in such cases, the
+letter sign (see @opcoderef{letsign}) is placed before such letter
+combinations when they actually are abbreviations, not contractions.
+The @code{contraction} opcode tells the translator to do this.
+
+@opcode{sufword, characters dots}
+Replace the characters with the dot pattern if they are either a word
+or at the beginning of a word.
+
+@opcode{prfword, characters dots}
+Replace the characters with the dot pattern if they are either a word
+or at the end of a word.
+
+@opcode{begword, characters dots}
+Replace the characters with the dot pattern if they are at the
+beginning of a word.
+
+@opcode{begmidword, characters dots}
+Replace the characters with the dot pattern if they are either at the
+beginning or in the middle of a word.
+
+@opcode{midword, characters dots}
+Replace the characters with the dot pattern if they are in the middle
+of a word.
+
+@opcode{midendword, characters dots}
+Replace the characters with the dot pattern if they are either in the
+middle or at the end of a word.
+
+@opcode{endword, characters dots}
+Replace the characters with the dot pattern if they are at the end of
+a word.
+
+@opcode{partword, characters dots}
+Replace the characters with the dot pattern if the characters are
+anywhere in a word, that is, if they are proceeded or followed by a
+letter.
+
+@opcode{exactdots, @@dots}
+Note that the operand must begin with an at sign (@samp{@@}). The dot
+pattern following it is evaluated for validity. If it is valid,
+whenever an at sign followed by this dot pattern appears in the source
+document it is replaced by the characters corresponding to the dot
+pattern in the output. This opcode is intended for use in liblouisutdml
+semantic-action files to specify exact dot patterns, as in
+mathematical codes. For example:
+
+@example
+exactdots @@4-46-12356
+@end example
+will produce the characters with these dot patterns in the output.
+
+@opcode{prepunc, characters dots}
+Replace the characters with the dot pattern if they are part of
+punctuation at the beginning of a word.
+
+@opcode{postpunc, characters dots}
+Replace the characters with the dot pattern if they are part of
+punctuation at the end of a word.
+
+@opcode{begnum, characters dots}
+Replace the characters with the dot pattern if they are at the
+beginning of a number, that is, before all its digits. For example, in
+@file{en-us-g1.ctb} we have @code{begnum # 4}.
+
+@opcode{midnum, characters dots}
+Replace the characters with the dot pattern if they are in the middle
+of a number. For example, @file{en-us-g1.ctb} has @code{midnum . 46}.
+This is because the decimal point has a different dot pattern than the
+period.
+
+@opcode{endnum, characters dots}
+Replace the characters with the dot pattern if they are at the end of
+a number. For example @file{en-us-g1.ctb} has @code{endnum th 1456}.
+This handles things like @samp{4th}. A letter sign is @emph{NOT}
+inserted.
+
+@opcode{joinnum, characters dots}
+Replace the characters with the dot pattern. In addition, if
+whitespace and a number follows omit the whitespace. This opcode can
+be used to join currency symbols to numbers for example:
+
+@example
+joinnum \x20AC 15 (EURO SIGN)
+joinnum \x0024 145 (DOLLAR SIGN)
+joinnum \x00A3 1234 (POUND SIGN)
+joinnum \x00A5 13456 (YEN SIGN)
+@end example
+
+@end table
+
+@node Character-Class Opcodes
+@section Character-Class Opcodes
+
+These opcodes define and use character classes. A character class
+associates a set of characters with a name. The name then refers to
+any character within the class. A character may belong to more than
+one class.
+
+The basic character classes correspond to the character definition
+opcodes, with the exception of the @opcoderef{uplow}, which defines
+characters belonging to the two classes @code{uppercase} and
+@code{lowercase}. These classes are:
+
+@table @code
+@item space
+Whitespace characters such as blank and tab
+@item digit
+Numeric characters
+@item letter
+Both uppercase and lowercase alphabetic characters
+@item lowercase
+Lowercase alphabetic characters
+@item uppercase
+Uppercase alphabetic characters
+@item punctuation
+Punctuation marks
+@item sign
+Signs such as percent (@samp{%})
+@item math
+Mathematical symbols
+@item litdigit
+Literary digit
+@item undefined
+Not properly defined
+
+@end table
+
+The opcodes which define and use character classes are shown below.
+For examples see @file{el.ctb}.
+
+@table @code
+
+@opcode{class, name characters}
+Define a new character class. The name operand must contain only
+letters (a-z and A-Z). The letters may be upper or lower-case but the
+case matters. The characters operand must be specified as a string. A
+character class may not be used until it has been defined.
+
+@opcode{after, class opcode ...}
+The specified opcode is further constrained in that the matched
+character sequence must be immediately preceded by a character
+belonging to the specified class. If this opcode is used more than
+once on the same line then the union of the characters in all the
+classes is used.
+
+@opcode{before, class opcode ...}
+The specified opcode is further constrained in that the matched
+character sequence must be immediately followed by a character
+belonging to the specified class. If this opcode is used more than
+once on the same line then the union of the characters in all the
+classes is used.
+
+@end table
+
+@node Swap Opcodes
+@section Swap Opcodes
+
+The swap opcodes are needed to tell the @opcoderef{context}, the
+@opcoderef{correct} and multipass opcodes which dot patterns to swap
+for which characters. There are three, @code{swapcd}, @code{swapdd}
+and @code{swapcc}. The first swaps dot patterns for characters. The
+second swaps dot patterns for dot patterns and the third swaps
+characters for characters. The first is used in the @code{context}
+opcode and the second is used in the multipass opcodes.
+
+All the swap opcodes have a name so they can be refered to from the
+@code{context}, @code{correct} and multipass opcodes. The name operand
+must contain only letters (a-z and A-Z). The letters may be upper or
+lower-case but the case matters.
+
+Dot patterns are separated by commas and may contain more than one
+cell.
+
+@table @code
+
+@opcode{swapcd, name characters dots@comma{} dots@comma{} dots@comma{} ...}
+See above paragraph for explanation. For example:
+
+@example
+swapcd dropped 0123456789 356,2,23,...
+@end example
+
+@opcode{swapdd, name dots@comma{} dots@comma{} dots ... dotpattern1@comma{} dotpattern2@comma{} dotpattern3@comma{} ...}
+The @code{swapdd} opcode defines substitutions for the multipass
+opcodes. In the second operand the dot patterns must be single cells,
+but in the third operand multi-cell dot patterns are allowed. This is
+because multi-cell patterns in the second operand would lead to
+ambiguities.
+
+@opcode{swapcc, name characters characters}
+The @code{swapcc} opcode swaps characters in its second operand for
+characters in the corresponding places in its third operand. It is
+intended for use with @code{correct} opcodes and can solve problems
+such as formatting phone numbers.
+
+@end table
+
+@node The Context and Multipass Opcodes
+@section The Context and Multipass Opcodes
+
+The @code{context} and multipass opcodes (@code{pass2}, @code{pass3}
+and @code{pass4}) provide translation capabilities beyond those of the
+basic translation opcodes (@pxref{Translation Opcodes}) discussed
+previously. The multipass opcodes cause additional passes to be made
+over the string to be translated. The number after the word
+@code{pass} indicates in which pass the entry is to be applied. If no
+multipass opcodes are given, only the first translation pass is made.
+The @code{context} opcode is basically a multipass opcode for the
+first pass. It differs slightly from the multipass opcodes per se.
+When back-translating, the passes are performed in the reverse order,
+i.e.@: @code{pass4}, @code{pass3}, @code{pass2}, @code{context}. Each
+of these opcodes must be prefixed by either the @opcoderef{noback} or
+the @opcoderef{nofor}. The format of all these opcodes is @code{opcode
+test action}. The specific opcodes are invoked as follows:
+
+@table @code
+@anchor{context opcode}
+@opcodeindex context
+@opcodeindex pass2
+@opcodeindex pass3
+@opcodeindex pass4
+@item context test action
+@itemx pass2 test action
+@itemx pass3 test action
+@itemx pass4 test action
+@end table
+
+The @code{test} and @code{action} operands have suboperands. Each
+suboperand begins with a non-alphanumeric character and ends when
+another non-alphanumeric character is encountered. The suboperands and
+their initial characters are as follows.
+
+@table @kbd
+@item " (double quote)
+a string of characters. This string must be terminated by another
+double quote. It may contain any characters. If a double quote is
+needed within the string, it must be preceded by a backslash
+(@samp{\}). If a space is needed, it must be represented by the escape
+sequence \s. This suboperand is valid
+in the test and action parts of the @code{correct} opcode,
+in the test part of the @code{context} opcode when forward translating,
+and in the action part of the @code{context} opcode when back translating.
+
+@item @@ (at sign)
+a sequence of dot patterns. Cells are separated by hyphens as usual.
+This suboperand is valid in the test and action parts of
+the @code{pass2}, @code{pass3}, and @code{pass4} opcodes,
+in the action part of the @code{context} opcode when forward translating,
+and in the test part of the @code{context} opcode when back translating.
+
+@item ` (accent mark)
+If this is the beginning of the string being translated this
+suboperand is true. It is valid only in the test part and must be the
+first thing in this operand.
+
+@item ~ (tilde)
+If this is the end of the string being translated this suboperand is
+true. It is valid only in the test part and must be the last thing in
+this operand.
+
+@item $ (dollar sign)
+a string of attributes, such as @samp{d} for digit, @samp{l} for
+letter, etc. For a list of all valid attributes @pxref{valid attribute
+characters}. More than one attribute can be given. If you wish to
+check characters with any attribute, use the letter @samp{a}. Input
+characters are checked to see if they have at least one of the
+attributes. The attribute string can be followed by numbers specifying
+how many characters are to be checked. If no numbers are given, 1 is
+assumed. If two numbers separated by a hyphen are given, the input is
+checked to make sure that at least the first number of characters with
+the attributes are present, but no more than the second number. If
+only one number is present, then exactly that many characters must
+have the attributes. A period instead of the numbers indicates an
+indefinite number of characters (for technical reasons the number of
+characters that are actually matched is limited to 65535).
+
+This suboperand is valid in all test parts but not in action parts.
+For the characters which can be used in attribute strings, see the
+following table.
+
+@item ! (exclamation point)
+reverses the logical meaning of the suboperand which follows. For
+example, !$d is true only if the character is @emph{NOT} a digit. This
+suboperand is valid in test parts only.
+
+@item % (percent sign)
+the name of a class defined by the @opcoderef{class} or the name of a
+swap set defined by the swap opcodes (@pxref{Swap Opcodes}). Names
+must contain only letters (a-z and A-Z). The letters may be upper or
+lower-case but the case matters. Class names may be used in test parts
+only. Swap names are valid everywhere.
+
+@item @{ (left brace)
+Name: the name of a grouping pair. The left brace indicates that the
+first (or left) member of the pair is to be used in matching. If this
+is between replacement brackets it must be the only item. This is also
+valid in the action part.
+
+The brace actions, @code{@{name} and @code{@}name}, refer to named
+groupings. A grouping is created with the @opcoderef{grouping} and
+contains exactly two characters which represent the opening character
+and the matching closing character for a character grouping. The first
+operand is the grouping name, the second is the two (opening and
+closing) characters, and the third is the two dot patterns separated
+by a comma.
+
+Let's say that you'd like to define the opening and closing
+parentheses via multipass rules, and that you'd like to use dots
+123478 for the opening parenthesis and dots 145678 for the closing
+parenthesis. One way to do so is like this:
+
+@example
+grouping parentheses () 123478,145678
+noback correct @{parentheses @{parentheses
+noback correct @}parentheses @}parentheses
+@end example
+
+The references within the test part of the multipass rule match
+against the characters (the second operand) of the grouping rule, and
+the references within the action part replace with the dot patterns
+(the third operand) of the grouping.
+
+@item @} (right brace)
+Name: the name of a grouping pair. The right brace indicates that the
+second (or right) member is to be used in matching. See the remarks on
+the left brace immediately above.
+
+@item / (slash)
+Search the input for the expression following the slash and return
+true if found. This can be used to set a variable.
+
+@item _ (underscore)
+Move backward. If a number follows, move backward that number of
+characters. The default is to move backward one character. This
+suboperand is valid only in test parts. The test fails if moving
+backward beyond the beginning of the input string.
+
+@item [ (left bracket)
+start replacement here. This suboperand must always be paired with a
+right bracket and is valid only in test parts. Multiple pairs of
+square brackets in a single expression are not allowed.
+
+@item ] (right bracket)
+end replacement here. This suboperand must always be paired with a
+left bracket and is valid only in test parts.
+
+@item # (number sign or crosshatch)
+test or set a variable. Variables are referred to by numbers
+(0 through 49), e.g. @code{#1}, @code{#2}, @code{#25}.
+Variables may be set by one @code{context} or multipass opcode and tested
+by another. Thus, an operation that occurs at one place in a translation
+can tell an operation that occurs later within the same pass about itself.
+This feature is used in math translation, and may also help to alleviate
+the need for new opcodes. This suboperand is valid everywhere.
+
+Variables are set in the action part. To set a variable, use an
+expression like @code{#1=1}. All of the variables are initialized to 0
+at the start of each pass.
+
+Variables can also be incremented and decremented by one in the action
+part with expressions like @code{#1+} and @code{#3-} respectively.
+An attempt to decrement a variable below 0 is silently ignored.
+
+Variables are tested in the test part with conditional expressions like:
+@code{#1=2}, @code{#3<4}, @code{#5>6}, @code{#7<=8}, @code{#9>=10}.
+
+@item * (asterisk)
+Copy the input characters or dot patterns within the replacement brackets
+into the output, and discard anything else that was matched. If there are
+no replacement brackets then copy all of the matched input. This
+suboperand is only valid within the action part. It may be specified any
+number of times. This feature is used, for example, for handling numeric
+subscripts in Nemeth.
+
+@item ? (question mark)
+Valid only in the action part. The characters to be replaced are
+simply ignored. That is, they are replaced with nothing. If either
+member of a grouping pair is in the replace brackets the other member
+at the same level is also removed.
+
+@end table
+
+@anchor{valid attribute characters}
+The valid characters which can be used in attribute strings are as
+follows:
+
+@table @kbd
+@item a
+any attribute
+@item d
+digit
+@item D
+literary digit
+@item l
+letter
+@item m
+math
+@item p
+punctuation
+@item S
+sign
+@item s
+space
+@item U
+uppercase
+@item u
+lowercase
+@item w
+first user-defined class
+@item x
+second user-defined class
+@item y
+third user-defined class
+@item z
+fourth user-defined class
+@end table
+
+The following illustrates the algorithm how text is evaluated with
+multipass expressions:
+
+@noindent
+Loop over context, pass2, pass3 and pass4 and do the following for each pass:
+
+@enumerate a
+@item
+Match the text following the cursor against all expressions in the
+current pass. If an expression has square brackets to indicate the
+part to be replaced, and the opening bracket would correspond with a
+position before the cursor, it is not a match.
+@item
+If there is no match: shift the cursor one position to the right and
+continue the loop
+@item
+If there are matches: choose the longest match
+@item
+Do the replacement. If the expression has square brackets, the part of
+the input that matches the part in between the brackets is replaced
+with the right-hand side of the rule. If the expression has no square
+brackets, the whole match is replaced.
+@item
+Place the cursor after the replaced text
+@item
+continue loop
+@end enumerate
+
+Normally, when a rule is applied, the characters in the input that the
+rule applies to are "consumed", i.e. the position of the input string
+is stepped forward, and the characters are no longer available for
+subsequent rules. However, with the multipass opcodes, the
+@opcoderef{context} opcode and the @opcoderef{correct} opcode, it is
+possible to make rules which don't consume any characters from the
+input. This could happen, e.g. if you use the @opcoderef{context}
+opcode to insert a dot pattern before a special group of characters.
+In these cases, Liblouis will always advance the position by one
+character to make sure that the program doesn't apply a rule to the
+same characters again and again.
+
+@node The correct Opcode
+@section The correct Opcode
+
+@table @code
+@opcode{correct, test action}
+Because some input (such as that from an OCR program) may contain
+systematic errors, it is sometimes advantageous to use a
+pre-translation pass to remove them. The errors and their corrections
+are specified by the @code{correct} opcode. If there are no
+@code{correct} opcodes in a table, the pre-translation pass is not used.
+If any back-translation corrections have been specified then they are
+applied in a post-translation (i.e.@: the very last) pass.
+
+Note that like the @opcoderef{context} and multi-pass opcodes, the
+@code{correct} opcode must be preceded by @opcoderef{noback} or
+@opcoderef{nofor}.
+
+The format of the @code{correct} opcode is very similar to that
+of the @opcoderef{context}. The only difference is that in the action
+part strings may be used and dot patterns may not be used. Some
+examples of @code{correct} opcode entries are:
+
+@example
+noback correct "\\" ? Eliminate backslashes
+noback correct "cornf" "comf" fix a common "scano"
+noback correct "cornm" "comm"
+noback correct "cornp" "comp"
+noback correct "*" ? Get rid of stray asterisks
+noback correct "|" ? ditto for vertical bars
+noback correct "\s?" "?" drop space before question mark
+@end example
+
+@end table
+
+@node The match Opcode
+@section The match Opcode
+
+The match opcode is similar the multipass opcodes and can be seen as
+the more low-level and powerful cousin to the @opcoderef{context}.
+
+@strong{Note:} For historical reasons despite being fairly similar in
+syntax and functionality both the @opcoderef{context} and the
+@opcoderef{match} exist and are in use in modern braille tables. But
+in the future they might be merged under some common opcode. For that
+reason consider the match opcode @emph{somewhat experimental}.
+
+@table @code
+@opcode{match, pre-pattern characters post-pattern dots}
+
+This opcode allows for matching a string of characters via @emph{pre}
+and @emph{post patterns}. The patterns are specified using an
+expression syntax somewhat like regular expressions (@pxref{pattern
+expression syntax}). A single hyphen (@samp{-}) by itself means no
+pattern is specified.
+
+The following will replace @samp{xyz} with the dots
+@samp{1346-13456-1356} when it appears in the string @samp{abxyzcd}.
+
+@example
+match ab xyz cd 1346-13456-1356
+@end example
+
+The following will replace @samp{ONE} with @samp{3456-1} when it
+starts the input and is followed by @samp{:}
+
+@example
+match ^ ONE : 3456-1
+@end example
+@end table
+
+@anchor{pattern expression syntax}
+The @code{pre-pattern} and the @code{post-pattern} can contain
+any of the following expressions:
+
+@table @samp
+@item [ ]
+Expression can be any of the characters between the brackets. If only
+one character present then the brackets are not needed unless it is a
+special character, in which it should be escaped with the backslash.
+
+@item .
+Expression can be any character.
+
+@item %[ ]
+Expression is a character with the attributes listed between the
+brackets. If only one character is present then the brackets are not
+needed. The set of attributes are specified as follows:
+
+@table @samp
+@item _
+space
+@item #
+digit
+@item a
+letter
+@item u
+uppercase
+@item l
+lowercase
+@item .
+punctuation
+@item $
+sign
+@end table
+
+@item ^
+Match at the end of input processing (or beginning depending of the
+direction pre or post).
+
+@item $
+Same as @samp{^}.
+@end table
+
+For example the following will replace @samp{bb} with the dots @samp{23} when it
+is between letters.
+
+@example
+match %a bb %a 23
+@end example
+
+The following will replace @samp{con} with the dots @samp{25} when it
+is preceded by a space or beginning of input, and followed by an
+@samp{s} and then any letter.
+
+@example
+match %[^_] con s%a 25
+@end example
+
+Similar to regular expressions the pattern expressions can contain
+grouping, quantifiers and even negation:
+
+@table @samp
+@item ( )
+Expressions between parentheses are grouped together as one
+expression.
+
+@item !
+The following expression is negated.
+
+@item ?
+The previous expression must match zero or one times.
+
+@item *
+The previous expression must match zero or more times.
+
+@item +
+The previous expression must match one or more times.
+
+@item |
+Either the previous or the following expressions must match.
+@end table
+
+For example the following will replace @samp{ing} with the dots
+@samp{346} when it is @emph{not} preceded by a space or beginning of
+input. What follows after the @samp{ing} does not matter, hence the
+@samp{-}.
+
+@example
+match !%[^_] ing - 346
+@end example
+
+The following will replace @samp{con} with the dots @samp{25} when it
+is preceded by a space, or beginning of input; then followed by a
+@samp{c} that is followed by any character but @samp{h}.
+
+@example
+match %[^_] con c!h 25
+@end example
+
+@node Miscellaneous Opcodes
+@section Miscellaneous Opcodes
+
+@table @code
+@opcode{include, filename}
+Read the file indicated by @code{filename} and incorporate or include
+its entries into the table. Included files can include other files,
+which can include other files, etc. For an example, see what files are
+included by the entry include @file{en-us-g1.ctb} in the table
+@file{en-us-g2.ctb}. If the included file is not in the same directory
+as the main table, use a full path name for filename.
+
+@opcode{undefined, dots}
+If this opcode is used in a table any characters which have not been
+handled in the table but are encountered in the text will be replaced
+by the dot pattern. If this opcode is not used, any undefined
+characters are replaced by @code{'\xhhhh'}, where the h's are
+hexadecimal digits.
+
+@opcode{display, character dots}
+Associates dot patterns with the characters which will be sent to a
+braille embosser, display or screen font. The character must be in the
+range 0-255 and the dots must specify a single cell. Here are some
+examples:
+
+@example
+# When the character a is sent to the embosser or display,
+# it will produce a dot 1.
+display a 1
+@end example
+
+@example
+# When the character L is sent to the display or embosser
+# it will produce dots 1-2-3.
+display L 123
+@end example
+
+The @code{display} opcode is optional. It is used when the embosser or
+display has a different mapping of characters to dot patterns than
+that given in @ref{Character-Definition Opcodes}. If used, display
+entries must proceed character-definition entries.
+
+A possible use case would be to define display opcodes so that the
+result is Unicode braille for use on a display and a second set of
+display opcodes (in a different file) to produce plain ASCII braille
+for use with an embosser.
+
+@opcode{multind, dots opcode opcode ...}
+The @code{multind} opcode tells the back-translator that a sequence of
+braille cells represents more than one braille indicator. For example,
+in @file{en-us-g2.ctb} we have @code{multind 56-6 letsign capsletter}.
+The back-translator can generally handle single braille indicators,
+but it cannot apply them when they immediately follow each other. It
+recognizes the letter sign if it is followed by a letter and takes
+appropriate action. It also recognizes the capital sign if it is
+followed by a letter. But when there is a letter sign followed by a
+capital sign it fails to recognize the letter sign unless the sequence
+has been defined with @code{multind}. A @code{multind} entry may not
+contain a comment because liblouis would attempt to interpret it as an
+opcode.
+
+@end table
+
+@node Notes on Back-Translation
+@chapter Notes on Back-Translation
+
+@anchor{General Notes}
+@section General Notes
+
+Back-translation refers to the process of translating backwards,
+i.e.@: from Braille to text. For many years, Liblouis was mainly
+concerned with forward translation, and so were most of the authors of
+the translation tables. Today however, Liblouis is being used
+extensively in conjunction with screen reading programs like NVDA and
+JAWS for Windows as well as Braille note-takers like BrailleSense from
+HIMS and BrailleNote from HumanWare. So when writing a translation
+table for Liblouis, it is indeed relevant to consider how the table
+will work when used for back-translation, if anything special must be
+done, or if you want to write separate tables for forward translation
+and back-translation.
+
+Back-translation is generally harder to do in a computer program than
+forward translation. Ideally, any text could be translated to Braille
+and then translated back to text giving exactly the same result as the
+original. However, many Braille codes omit a lot of information and
+leaves it to the reader to fill in the missing bits. An example of this
+is letters with accents. In languages where accents are uncommon, e.g.
+English, Accented letters are usually just marked with a Braille
+indicator stating that there is an accent, but not which accent, even
+though this may be crucial to the meaning of the word or the sentence.
+Another example of this is when not all capital letters are marked in
+the Braille code, but only the "important" capital letters. A third
+example is when a Braille character serves as both a punctuation sign,
+a math sign, and perhaps even as a contraction, and the Braille code
+then leaves it up to the reader to use his/her knowledge of the context
+to decide the meaning of the Braille character.
+
+In some cases, you may need to bend the rules of the Braille code if it
+is important to create Braille that can be properly back-translated.
+This may include marking all capital letters instead of just the
+"important" ones, or perhaps marking a Braille character with an
+indicator stating that this character should in fact be interpreted as
+a math sign and not a punctuation or Braille contraction. In some
+cases, the best solution may be to create two separate sets of tables
+for forward translation: One set for Braille that must be
+back-translatable (for use with screen readers and note-takers), and
+another for good and nice literary Braille (for embossing).
+But no matter how you bend the Braille code, the back-translation
+process may not be perfect.
+
+@anchor{Back-translation with Liblouis}
+@section Back-translation with Liblouis
+
+Back-translation is carried out by the function
+@code{lou_backTranslateString}. Its calling sequence is described in
+@ref{Programming with liblouis}. @code{lou_backTranslateString} first
+performs @code{pass4}, if
+present, then @code{pass3}, then @code{pass2}, then the
+backtranslation, then corrections. Note that this is exactly the
+inverse of forward translation.
+
+Most opcodes can be preceded by @opcoderef{noback} or @opcoderef{nofor},
+and the @code{correct}, @code{context} and multi-pass opcodes must be
+preceded with either @code{noback} or @code{nofor}. So in most cases,
+it will be perfectly possible to make one table for translation in both
+directions, although a separate table for forward and backward
+translation might be more readable in some cases.
+
+Most of the opcodes associated with pass 1 have two operands, a
+character operand to the left and a dots operand to the right. During
+forward translation, these operands are used to replace the characters
+with the dot pattern according to the conditions of the opcode. The
+opcode works from left to right. When back-translating, these opcodes
+work the opposite way. The dot patterns are replaced by the text. The
+opcodes work from right to left.
+
+On the other hand, the @code{correct}, @code{context} and multi-pass
+opcodes have a test part to the left and an action part to the right.
+These opcodes work from left to right in both translation directions.
+The test is performed, and if true, the action is executed, i.e.@:
+replacing, inserting or deleting characters or dots. This is why a
+translation direction always has to be specified with these opcodes
+using @code{noback} or @code{nofor}.
+
+@node Table Metadata
+@chapter Table Metadata
+
+Translation tables may contain metadata. This makes them
+discoverable. Programs may for example use the Liblouis function
+@ref{lou_findTable,@code{lou_findTable}} to find a table based on a
+special query of which the @ref{Query Syntax,syntax} is described
+below.
+
+@section Syntax
+
+Metadata must be defined in special comments within the table
+header. The table header is the area at the top of the file, before
+the first translation rule, consisting of only comments or empty
+lines. Any metadata within included tables is ignored.
+
+A metadata field must be defined on its own line, starting with
+@code{#+}. It has the following syntax:
+
+@example
+#+<key>: <value>
+@end example
+
+where @samp{<key>} and @samp{<value>} are sequences of one or more
+characters @code{a} to @code{z}, @code{A} to @code{Z}, @code{0} to
+@code{9}, @code{.}, @code{-}, and @code{_}. The colon that separates
+the key and value may have zero or more spaces or tabs on either side.
+
+A value is optional. In case of no value the colon must be omitted as
+well:
+
+@example
+#+<key>
+@end example
+
+There is no restriction on which keys and values are allowed, as long
+as the syntax is correct. However in order to be really useful there
+must be some standard keys and values. A possible grammar is proposed
+on the wiki page
+@url{https://github.com/liblouis/liblouis/wiki/Table-discovery-based-on-table-metadata#standard-metadata-tags, Standard metadata tags}.
+
+@anchor{Query Syntax}
+@section Query Syntax
+
+A query that is passed to the @ref{lou_findTable,@code{lou_findTable}}
+function must have the following syntax:
+
+@example
+<feature1> <feature2> <feature3> ...
+@end example
+
+where @samp{<feature>} is either:
+
+@example
+<key>: <value>
+@end example
+
+or:
+
+@example
+<key>
+@end example
+
+Features are separated by one or more spaces or tabs. No spaces are
+allowed around colons.
+
+@node Testing Translation Tables interactively
+@chapter Testing Translation Tables interactively
+
+A number of test programs are provided as part of the liblouis
+package. They are intended for testing liblouis and for debugging
+tables. None of them is suitable for braille transcription. An
+application that can be used for transcription is @command{file2brl},
+which is part of the liblouisutdml package (@pxref{Top, , Introduction,
+liblouisutdml, Liblouisutdml User's and Programmer's Manual}). The source
+code of the test programs can be studied to learn how to use the
+liblouis library and they can be used to perform the following
+functions.
+
+@anchor{common options}
+All of these programs recognize the @option{--help} and
+@option{--version} options.
+
+@table @option
+
+@item --help
+@itemx -h
+Print a usage message listing all available options, then exit
+successfully.
+
+@item --version
+@itemx -v
+Print the version number, then exit successfully.
+
+@end table
+
+Most test programs let you specify one or multiple tables to use.
+These tables are usually found in standard locations in the file
+system or local to where the command is executed. @xref{How tables are
+found}, for a description on how the tables are located.
+
+@menu
+* lou_debug::
+* lou_trace::
+* lou_checktable::
+* lou_allround::
+* lou_translate (program)::
+* lou_checkhyphens::
+* lou_checkyaml::
+@end menu
+
+@node lou_debug
+@section lou_debug
+@pindex lou_debug
+
+The @command{lou_debug} tool is intended for debugging liblouis
+translation tables. The command line for @command{lou_debug} is:
+
+@example
+lou_debug [OPTIONS] TABLE[,TABLE,...]
+@end example
+
+The command line options that are accepted by @command{lou_debug} are
+described in @ref{common options}.
+
+The table (or comma-separated list of tables) is compiled. If no
+errors are found a brief command summary is printed, then the prompt
+@samp{Command:}. You can then input one of the command letters and get
+output, as described below.
+
+Most of the commands print information in the various arrays of
+@code{TranslationTableHeader}. Since these arrays are pointers to
+chains of hashed items, the commands first print the hash number, then
+the first item, then the next item chained to it, and so on. After
+each item there is a prompt indicated by @samp{=>}. You can then press
+enter (@kbd{@key{RET}}) to see the next item in the chain or the first
+item in the next chain. Or you can press @kbd{h} (for next-(h)ash) to
+skip to the next hash chain. You can also press @kbd{e} to exit the
+command and go back to the @samp{command:} prompt.
+
+@table @kbd
+@item h
+Brings up a screen of somewhat more extensive help.
+
+@item f
+Display the first forward-translation rule in the first non-empty hash
+bucket. The number of the bucket is displayed at the beginning of the
+chain. Each rule is identified by the word @samp{Rule:}. The fields
+are displayed by phrases consisting of the name of the field, an equal
+sign, and its value. The before and after fields are displayed only if
+they are nonzero. Special opcodes such as the @opcoderef{correct} and
+the multipass opcodes are shown with the code that instructs the
+virtual machine that interprets them. If you want to see only the
+rules for a particular character string you can type @kbd{p} at the
+@samp{command:} prompt. This will take you to the @samp{particular:}
+prompt, where you can press @kbd{f} and then type in the string. The
+whole hash chain containing the string will be displayed.
+
+@item b
+Display back-translation rules. This display is very similar to that
+of forward translation rules except that the dot pattern is displayed
+before the character string.
+
+@item c
+Display character definitions, again within their hash chains.
+
+@item d
+Displays single-cell dot definitions. If a character-definition opcode
+gives a multi-cell dot pattern, it is displayed among the
+back-translation rules.
+
+@item C
+Display the character-to-dots map. This is set up by the
+character-definition opcodes and can also be influenced by the
+@opcoderef{display}.
+
+@item D
+Display the dot to character map, which shows which single-cell dot
+patterns map to which characters.
+
+@item z
+Show the multi-cell dot patterns which have been assigned to the
+characters from 0 to 255 to comply with computer braille codes such as
+a 6-dot code. Note that the character-definition opcodes should use
+8-dot computer braille.
+
+@item p
+Bring up a secondary (@samp{particular:}) prompt from which you can
+examine particular character strings, dot patterns, etc. The commands
+(given in its own command summary) are very similar to those of the
+main @samp{command:} prompt, but you can type a character string or
+dot pattern. They include @kbd{h}, @kbd{f}, @kbd{b}, @kbd{c}, @kbd{d},
+@kbd{C}, @kbd{D}, @kbd{z} and @kbd{x} (to exit this prompt), but not
+@kbd{p}, @kbd{i} and @kbd{m}.
+
+@item i
+Show braille indicators. This shows the dot patterns for various
+opcodes such as the @opcoderef{capsletter} and the @opcoderef{numsign}.
+It also shows emphasis dot patterns, such as those for the
+@opcoderef{begemphword}, the @opcoderef{begemphphrase}, etc. If a
+given opcode has not been used nothing is printed for it.
+
+@item m
+Display various miscellaneous information about the table, such as the
+number of passes, whether certain opcodes have been used, and whether
+there is a hyphenation table.
+
+@item q
+Exit the program.
+@end table
+
+@node lou_trace
+@section lou_trace
+@pindex lou_trace
+
+When working on translation tables it is sometimes useful to determine
+what rules were applied when translating a string. @command{lou_trace}
+helps with exactly that. It list all the the applied rules for a given
+translation table and an input string.
+
+@example
+lou_trace [OPTIONS] TABLE[,TABLE,...]
+@end example
+
+Aside from the standard options (@pxref{common options})
+@command{lou_trace} also accepts the following options:
+
+@table @option
+
+@item --forward
+@itemx -f
+Trace a forward translation.
+
+@item --backward
+@itemx -b
+Trace a backward translation.
+
+@end table
+
+If no options are given forward translation is assumed.
+
+Once started you can type an input string followed by @kbd{@key{RET}}.
+@command{lou_trace} will print the braille translation followed by
+list of rules that were applied to produce the translation. A possible
+invocation is listed in the following example:
+
+@example
+$ lou_trace tables/en-us-g2.ctb
+the u.s. postal service
+! u4s4 po/al s@}vice
+1. largesign the 2346
+2. repeated 0
+3. lowercase u 136
+4. punctuation . 46
+5. context _$l["."]$l @@256
+6. lowercase s 234
+7. postpunc . 256
+8. repeated 0
+9. begword post 1234-135-34
+10. largesign a 1
+11. lowercase l 123
+12. repeated 0
+13. lowercase s 234
+14. always er 12456
+15. lowercase v 1236
+16. lowercase i 24
+17. lowercase c 14
+18. lowercase e 15
+19. pass2 $s1-10 @@0
+20. pass2 $s1-10 @@0
+21. pass2 $s1-10 @@0
+@end example
+
+@node lou_checktable
+@section lou_checktable
+@pindex lou_checktable
+
+To use this program type the following:
+
+@example
+lou_checktable [OPTIONS] TABLE
+@end example
+
+Aside from the standard options (@pxref{common options})
+@command{lou_checktable} also accepts the following options:
+
+@table @option
+
+@item --quiet
+@itemx -q
+Do not write to standard error if there are no errors.
+
+@end table
+
+If the table contains errors, appropriate messages will be displayed.
+If there are no errors the message @samp{no errors found.} will be
+shown.
+
+@node lou_allround
+@section lou_allround
+@pindex lou_allround
+
+This program tests every capability of the liblouis library. It is
+completely interactive. Invoke it as follows:
+
+@example
+lou_allround [OPTIONS]
+@end example
+
+The command line options that are accepted by @command{lou_allround}
+are described in @ref{common options}.
+
+You will see a few lines telling you how to use the program. Pressing
+one of the letters in parentheses and then enter will take you to a
+message asking for more information or for the answer to a yes/no
+question. Typing the letter @samp{r} and then @key{RET} will take you
+to a screen where you can enter a line to be processed by the library
+and then view the results.
+
+@node lou_translate (program)
+@section lou_translate
+@pindex lou_translate
+
+This program translates whatever is on the standard input unit and
+prints it on the standard output unit. It is intended for large-scale
+testing of the accuracy of translation and back-translation. The
+command line for @command{lou_translate} is:
+
+@example
+lou_translate [OPTION] TABLE[,TABLE,...]
+@end example
+
+Aside from the standard options (@pxref{common options}) this program
+also accepts the following options:
+
+@table @option
+
+@item --forward
+@itemx -f
+Do a forward translation.
+
+@item --backward
+@itemx -b
+Do a backward translation.
+
+@end table
+
+If no options are given forward translation is assumed.
+
+Use the following command to do a forward translation with translation
+table @file{en-us-g2.ctb}. The resulting braille is ASCII encoded (as
+defined in @file{en-us-g2.ctb}).
+
+@example
+lou_translate --forward en-us-g2.ctb < input.txt
+@end example
+
+The next example illustrates a forward translation with translation
+table @file{en-us-g2.ctb} and display table @file{unicode.dis}. The
+resulting braille is encoded as Unicode dot patterns (as defined in
+@file{unicode.dis}).
+
+@example
+lou_translate --forward unicode.dis,en-us-g2.ctb < input.txt
+@end example
+
+Use a pipe if you would rather just pass some given text to the
+translator.
+
+@example
+echo "The quick brown fox jumps over the lazy dog" | lou_translate -f unicode.dis,en-us-g2.ctb
+@end example
+
+The result will be written to standard output:
+
+@example
+⠠⠮ ⠟⠅ ⠃⠗⠪⠝ ⠋⠕⠭ ⠚⠥⠍⠏⠎ ⠕⠧⠻ ⠮ ⠇⠁⠵⠽ ⠙⠕⠛
+@end example
+
+Backward translation can be done as follows:
+
+@example
+echo ",! qk br@{n fox jumps ov@} ! lazy dog" | lou_translate --backward en-us-g2.ctb
+@end example
+
+which results in
+
+@example
+The quick brown fox jumps over the lazy dog
+@end example
+
+You can also do a backward translation using Unicode dot patterns
+
+@example
+echo "⠠⠮ ⠟⠅ ⠃⠗⠪⠝ ⠋⠕⠭" | lou_translate --backward unicode.dis,en-us-g2.ctb
+@end example
+
+resulting in
+
+@example
+The quick brown fox
+@end example
+
+@node lou_checkhyphens
+@section lou_checkhyphens
+@pindex lou_checkhyphens
+
+This program checks the accuracy of hyphenation in Braille translation
+for both translated and untranslated words. It is completely
+interactive. Invoke it as follows:
+
+@example
+lou_checkhyphens [OPTIONS]
+@end example
+
+The command line options that are accepted by
+@command{lou_checkhyphens} are described in @ref{common options}.
+
+You will see a few lines telling you how to use the program.
+
+@node lou_checkyaml
+@section lou_checkyaml
+@pindex lou_checkyaml
+
+This program tests a liblouis table against a corpus of known good
+Braille translations defined in YAML format. For a description of the
+format refer to @ref{YAML Tests}. The program returns 0 if all tests
+pass or 1 if any of the tests fail. If @code{libyaml} is not installed
+the program will simply skip all tests. Invoke it as follows:
+
+@example
+lou_checkyaml YAML_TEST_FILE
+@end example
+
+The command line options that are accepted by
+@command{lou_checkyaml} are described in @ref{common options}.
+
+@cindex Running YAML tests manually
+@cindex Running individual YAML tests
+Due to some technical limitations the YAML tests work best if the
+@env{LOUIS_TABLEPATH} is set up correctly. By running @command{make}
+this is all taken care for you. You can also run individual YAML tests
+as shown in the following example:
+
+@example
+cd tests
+make check TESTS=yaml/en-ueb-g2_backward.yaml
+@end example
+
+@node Automated Testing of Translation Tables
+@chapter Automated Testing of Translation Tables
+
+There are a number of automated tests for liblouis and they are
+proving to be of tremendous value. When changing the code the
+developers can run the tests to see if anything broke.
+
+The easiest way to test the translation tables is to write a YAML file
+where you define the table that is to be tested and any number of
+words or phrases to translate together with their respective expected
+translation.
+
+The YAML tests are data driven, i.e.@: you give the test data, a string
+to translate and the expected output. The data is in a standard format
+namely YAML. If you have @file{libyaml} installed they will
+automatically be invoked as part of the standard @command{make check}
+command.
+
+@anchor{YAML Tests}
+@section YAML Tests
+@url{http://yaml.org/,YAML} is a human readable data serialization
+format that allows for an easy and compact way to define tests.
+
+A YAML file first defines which tables are to be used for the tests.
+Then it optionally defines flags such as the @samp{testmode}. Finally
+all the tests are defined.
+
+You can repeat the cycle as many times as you like (tables, optional
+flags, tests). You can also define several rounds of tests for any
+table, with or without the optional flags. Just remember that the
+flags are reset to their default values each time you start a new
+round of tests or load a new set of tables.
+
+Let's just look at a simple example how tests could be defined:
+
+@iftex
+@emph{(For technical reasons the Unicode braille in the expected
+translation in the following YAML examples is not displayed correctly.
+Please refer to the example YAML file @file{example_test.yaml} in the
+@file{tests} directory of the source distribution or read these
+examples in another version of the documentation such as HTML)}
+@end iftex
+
+@example
+# comments start with '#' anywhere on a line
+# first define which tables will be used for your tests
+table: [unicode.dis, en-ueb-g1.ctb]
+
+# then optionally define flags such as testmode. If no flags are
+# defined forward translation is assumed
+
+# now define the tests
+tests:
+ - # each test is a list.
+ # The first item is the string to translate. Quoting of strings is
+ # optional
+ - hello
+ # The second item is the expected translation
+ - ⠓⠑⠇⠇⠕
+ - # optionally you can define additional parameters in a third
+ # item such as typeform or expected failure, etc
+ - Hello
+ - ⠨⠶⠠⠓⠑⠇⠇⠕⠨⠄
+ - @{typeform: @{italic: '++++ '@}, xfail: true@}
+ - # a simple, no-frills test
+ - Good bye
+ - ⠠⠛⠕⠕⠙ ⠃⠽⠑
+ # same as above using "flow style" notation
+ - [Good bye, ⠠⠛⠕⠕⠙ ⠃⠽⠑]
+@end example
+
+The four basic components of a test file are as follows:
+
+@table @samp
+@item table
+A list containing table files, which the tests should be run against.
+This is usually just one file, but for some situations more than one
+file can be required. For example:
+
+@example
+table: [hu-hu-g1.ctb, hyph_hu_HU.dic]
+@end example
+
+It is also possible to specify a table inline. @ref{Inline definition
+of tables} below explains how to do this.
+
+A third way to specify a table is by its metadata. A table query,
+which is essentially as list of ``features'', is matched against the
+@ref{Table Metadata,table metadata} defined inside the tables
+contained in @env{LOUIS_TABLEPATH}. Only the best match is used for
+the test.
+
+The syntax of the query is a variation of the @ref{Query
+Syntax,syntax} used for the @ref{lou_findTable,@code{lou_findTable}}
+function:
+
+@example
+table:
+ locale: fr
+ grade: 1
+@end example
+
+@item display
+A display table, which should be used to encode braille in the
+test. This item is optional. If it is present it should be the first
+item of the file. If it is not present, the braille encoding of each
+test is determined by the table that is being tested.
+
+The next example shows how to test the @file{en-ueb-g1.ctb} table
+using ASCII notation (as defined in @file{en-ueb-g1.ctb} itself):
+
+@example
+table: [en-ueb-g1.ctb]
+@end example
+
+If you wanted to test the @file{en-ueb-g1.ctb} table using Unicode dot
+patterns then you would use the following definition:
+
+@example
+display: unicode.dis
+table: [en-ueb-g1.ctb]
+@end example
+
+@item flags
+The flags that apply for all tests in this file. At the moment only
+the @samp{testmode} flag is supported. It can have four possible
+values:
+
+@table @samp
+@item forward
+This indicates that the tests are for forward translation
+@item backward
+This indicates that the tests are for backward translation
+@item bothDirections
+This indicates that the tests are for both forward and backward translation.
+@item hyphenate
+This indicates that the tests are for hyphenation
+@item hyphenateBraille
+This indicates that the tests are for hyphenation and the input is braille
+@end table
+
+If no flags are defined forward translation is assumed.
+
+@item tests
+A list of tests. Each test consists of a list of two, three or in some
+cases even four items. The first item is the unicode text to be
+tested. The second item is the expected braille output. This can be
+either unicode braille or an ASCII-braille like encoding. Quoting
+strings is optional. Comments can be inserted almost anywhere using
+the @samp{#} sign. A simple test would look at follows:
+
+@example
+ - # a simple, no-frills test
+ - Good bye
+ - ⠠⠛⠕⠕⠙ ⠃⠽⠑
+@end example
+
+Using the more compact ``flow style'' notation it would look like the
+following:
+
+@example
+ - [Good bye, ⠠⠛⠕⠕⠙ ⠃⠽⠑]
+@end example
+
+An optional third item can contain additional options for a test such
+as the typeform, or whether a test is expected to fail. The following
+shows a typical example:
+
+@example
+ -
+ - Hello
+ - ⠨⠶⠠⠓⠑⠇⠇⠕⠨⠄
+ - @{typeform: @{italic: '++++ '@}, xfail: true@}
+ # same test more compact
+ - [Hello, ⠨⠶⠠⠓⠑⠇⠇⠕⠨⠄, @{typeform: @{italic: '++++ '@}, xfail: true@}]
+@end example
+
+The valid additional options for a test are as follows:
+
+@table @samp
+@item xfail
+Whether a test is expected to fail. If you expect a test to fail, set
+this to @samp{true}. If you prefer you can also specify a reason for
+the failure:
+
+@example
+ - [Hello, ⠨, @{xfail: Test case is not complete@}]
+@end example
+
+If you expect a test case to pass then just don't mark it with
+@samp{xfail} or if you really have to, set @samp{xfail} to
+@samp{false} or @samp{off}.
+
+@item typeform
+The typeform used for a translation. It consists of one or more
+emphasis specifications. For each character in the specifications that
+is not a space the corresponding emphasis will be set. Valid options
+for emphasis are @samp{italic}, @samp{underline}, @samp{bold},
+@samp{computer_braille}, @samp{passage_break}, @samp{word_reset},
+@samp{script}, @samp{trans_note}, @samp{trans_note_1},
+@samp{trans_note_2}, @samp{trans_note_3}, @samp{trans_note_4} or
+@samp{trans_note_5}. The following shows an example where both
+@samp{italic} and @samp{underline} are specified:
+
+@example
+ -
+ - Hello
+ - ⠨⠶⠠⠓⠑⠇⠇⠕⠨⠄
+ - typeform:
+ italic: '++++ '
+ underline: ' +'
+@end example
+
+@item inputPos
+A list of 0-based input positions, one for each output position.
+Useful when simulating screen reader interaction, to debug contraction
+and cursor behavior as in the following example. Note that all
+positions in this and the following examples start at 0. Also note
+that in these examples the additional options are not passed using the
+``flow style'' notation.
+
+@example
+ -
+ - went
+ - ⠺⠢⠞
+ - inputPos: [0,1,3]
+@end example
+
+@item outputPos
+A list of 0-based output positions, one for each input position. Useful when
+simulating screen reader interaction, to debug contraction and cursor
+behavior as in the following example.
+
+@example
+ -
+ - went
+ - ⠺⠢⠞
+ - outputPos: [0,1,1,2]
+@end example
+
+@item cursorPos
+The cursor position for the given translation and optionally an
+expected cursor position where the cursor is supposed to be after the
+translation. Useful when simulating screen reader interaction, to
+debug contraction and cursor behavior:
+
+The cursor position can take two forms: You can either specify a
+single number or alternatively you can give a tuple of two numbers.
+
+@table @asis
+
+@item single number (e.g. @samp{4})
+When you simply want to specify the cursor position for the given
+translation you pass a number as in the following example:
+
+@example
+ -
+ - you went to
+ - ⠽ ⠺⠑⠝⠞ ⠞⠕
+ - mode: [compbrlAtCursor]
+ cursorPos: 4
+@end example
+
+@item a tuple (e.g. @samp{[4,2]})
+When you expect the cursor to be in a particular position after the
+translation and you want to check this then pass a tuple of cursor
+positions as in the following example:
+
+@example
+ -
+ - you went to
+ - ⠽ ⠺⠑⠝⠞ ⠞⠕
+ - mode: [compbrlAtCursor]
+ cursorPos: [4,2]
+@end example
+@end table
+
+@item mode
+A list of translation modes that should be used for this test. If not
+defined defaults to 0. Valid mode values are @samp{noContractions},
+@samp{compbrlAtCursor}, @samp{dotsIO}, @samp{compbrlLeftCursor},
+@samp{ucBrl}, @samp{noUndefined} or @samp{partialTrans}.
+
+For a description of the various translation mode flags, please see
+the function @ref{lou_translateString}.
+
+@item maxOutputLength
+Define a maximum length of the output. This can be used to test the
+behavior of liblouis in the face of a limited output buffer, for
+example the length of the refreshable braille display.
+
+@end table
+
+@end table
+
+@subsection Optional test description
+When a test contains three or four items the first item is assumed to
+be a test description, the second item is the unicode text to be
+tested and the third item is the expected braille output. Again an
+optional fourth item can contain additional options for the test. The
+following shows an example:
+
+@example
+ -
+ - Number-text-transitions with italic
+ - 123abc
+ - ⠼⠁⠃⠉⠨⠶⠰⠁⠃⠉⠨⠄
+ - @{typeform: '000111'@}
+@end example
+
+In case the test fails the description will be printed together with
+the expected and the actual braille output.
+
+For more examples and inspiration please see the YAML tests
+(@file{*.yaml}) in the @file{tests} directory of the source
+distribution.
+
+@subsection Testing multiple tables within the same YAML test file
+Sometimes you are more focused on testing a particular feature across
+several tables rather than just testing one table. For that reason the
+following is also allowed:
+
+@example
+table: ...
+tests:
+ - [..., ...]
+ - [..., ...]
+table: ...
+tests:
+ - [..., ...]
+ - [..., ...]
+@end example
+
+If you specify flags for the tests, remember that the flags are reset
+to their default values when you specify a new table.
+
+@subsection Multiple test sections for each table
+You can specify several sections of tests for each table, with or
+without the optional flags. This is useful e.g. if you want to have
+various tests for both forward and backward translation for the same
+set of tables, especially if you are defining the table as part of
+the yaml file (see next section). This feature is also useful if you
+simply want to devide your tests into multiple sections for better
+overview. All flags are reset to their default values when you start
+a new test section.
+
+Thus, a yaml file might look as follows:
+
+@example
+table: ...
+tests:
+ - [..., ...]
+ - [..., ...]
+
+# Some more tests
+ tests:
+ - [..., ...]
+ - [..., ...]
+
+# Some tests for back-translation - same table
+flags: @{testmode: backward@}
+ - [..., ...]
+ - [..., ...]
+@end example
+
+@anchor{Inline definition of tables}
+@subsection Inline definition of tables
+When testing very specific opcode combinations it is sometimes tedious
+to create specific test tables just for that. Hence the YAML tests
+allow for specification of table definitions inline. Instead of
+referring to a table by name you just define the table inline by using
+what the YAML spec calls a
+@url{http://www.yaml.org/spec/1.2/spec.html#id2795688,Literal Style
+Block}. Start the definition with a @samp{|}, then list the opcodes
+with an indentation. The inline table ends when the indentation ends.
+
+@example
+table: |
+ sign a 1
+ ...
+tests:
+ - ...
+ - ...
+@end example
+
+@subsection Running the same test data on multiple tables
+Sometimes you maintain multiple tables which are very similar and
+basically contain the same test data. Instead of copying the YAML test
+and changing the table name you can also define multiple tables. This
+will cause the YAML tests to be checked against both tables.
+
+@example
+table: nl-NL
+table: nl-BE
+tests:
+ - [..., ...]
+ - [..., ...]
+@end example
+
+@node Programming with liblouis
+@chapter Programming with liblouis
+
+@menu
+* Overview (library)::
+* Data structure of liblouis tables::
+* How tables are found::
+* Deprecation of the logging system::
+* lou_version::
+* lou_translateString::
+* lou_translate::
+* lou_backTranslateString::
+* lou_backTranslate::
+* lou_hyphenate::
+* lou_compileString::
+* lou_getTypeformForEmphClass::
+* lou_dotsToChar::
+* lou_charToDots::
+* lou_registerLogCallback::
+* lou_setLogLevel::
+* lou_logFile::
+* lou_logPrint::
+* lou_logEnd::
+* lou_setDataPath::
+* lou_getDataPath::
+* lou_getTable::
+* lou_findTable::
+* lou_indexTables::
+* lou_checkTable::
+* lou_readCharFromFile::
+* lou_free::
+* lou_charSize::
+* Python bindings::
+@end menu
+
+@node Overview (library)
+@section Overview
+
+You use the liblouis library by calling the following functions,
+@code{lou_translateString}, @code{lou_backTranslateString},
+@code{lou_translate}, @code{lou_backTranslate},
+@code{lou_registerLogCallback}, @code{lou_setLogLevel},
+@code{lou_logFile}, @code{lou_logPrint}, @code{lou_logEnd},
+@code{lou_getTable}, @code{lou_findTable}, @code{lou_indexTables},
+@code{lou_checkTable}, @code{lou_hyphenate}, @code{lou_charToDots},
+@code{lou_dotsToChar}, @code{lou_compileString},
+@code{lou_getTypeformForEmphClass}, @code{lou_readCharFromFile},
+@code{lou_version}, @code{lou_free} and @code{lou_charSize}. These are
+described below. The header file, @file{liblouis.h}, also contains
+brief descriptions. Liblouis is written in straight C. It has four
+code modules, @file{compileTranslationTable.c}, @file{logging.c},
+@file{lou_translateString.c} and @file{lou_backTranslateString.c}. In
+addition, there are two header files, @file{liblouis.h}, which defines
+the API, and @file{louis.h}, used only internally and by
+liblouisutdml. The latter includes @file{liblouis.h}.
+
+Persons who wish to use liblouis from Python may want to skip ahead to
+@ref{Python bindings}.
+
+@file{compileTranslationTable.c} keeps track of all translation tables
+which an application has used. It is called by the translation,
+hyphenation and checking functions when they start. If a table has not
+yet been compiled @file{compileTranslationTable.c} checks it for
+correctness and compiles it into an efficient internal representation.
+The main entry point is @code{lou_getTable}. Since it is the module
+that keeps track of memory usage, it also contains the @code{lou_free}
+function. In addition, it contains the @code{lou_checkTable} function,
+plus some utility functions which are used by the other modules.
+
+By default, liblouis handles all characters internally as 16-bit
+unsigned integers. It can be compiled for 32-bit characters as
+explained below. The meanings of these integers are not hard-coded.
+Rather they are defined by the character-definition opcodes. However,
+the standard printable characters, from decimal 32 to 126 are
+recognized for the purpose of processing the opcodes. Hence, the
+following definition is included in @file{liblouis.h}. It is correct
+for computers with at least 32-bit processors.
+
+@example
+typedef unsigned short int widechar
+@end example
+
+To make liblouis handle 32-bit Unicode simply remove the word
+@code{short} in the above @code{typedef}. This will cause the translate and
+back-translate functions to expect input in 32-bit form and to deliver
+their output in this form. The input to the compiler (tables) is
+unaffected except that two new escape sequences for 20-bit and 32-bit
+characters are recognized.
+
+At runtime, the width of a character specified during compilation may
+be obtained using @code{lou_charSize}.
+
+Here are the definitions of the eleven liblouis functions and their
+parameters. They are given in terms of 16-bit Unicode. If liblouis has
+been compiled for 32-bit Unicode simply read 32 instead of 16.
+
+@node Data structure of liblouis tables
+@section Data structure of liblouis tables
+
+The data structure @code{TranslationTableHeader} is defined by a
+@code{typedef} statement in @file{louis.h}. To find the beginning,
+search for the word @samp{header}. As its name implies, this is
+actually the table header. Data are placed in the @code{ruleArea}
+array, which is the last item defined in this structure. This array is
+declared with a length of 1 and is expanded as needed. The table
+header consists mostly of arrays of pointers of size @code{HASHNUM}.
+These pointers are actually offsets into @code{ruleArea} and point to
+chains of items which have been placed in the same hash bucket by a
+simple hashing algorithm. @code{HASHNUM} should be a prime and is
+currently 1123. The structure of the table was chosen to optimize
+speed rather than memory usage.
+
+The first part of the table contains miscellaneous information, such
+as the number of passes and whether various opcodes have been used. It
+also contains the amount of memory allocated to the table and the
+amount actually used.
+
+The next section contains pointers to various braille indicators and
+begins with @code{capitalSign}. The rules pointed to contain the
+dot pattern for the indicator and an opcode which is used by the
+back-translator but does not appear in the list of opcodes. The
+braille indicators also include various kinds of emphasis, such as
+italic and bold and information about the length of emphasized
+phrases. The latter is contained directly in the table item instead of
+in a rule.
+
+After the braille indicators comes information about when a letter
+sign should be used.
+
+Next is an array of size @code{HASHNUM} which points to character
+definitions. These are created by the character-definition opcodes.
+
+Following this is a similar array pointing to definitions of
+single-cell dot patterns. This is also created from the
+character-definition opcodes. If a character definition contains a
+multi-cell dot pattern this is compiled into ordinary forward and
+backward rules. If such a multi-cell dot pattern contains a single
+cell which has not previously been defined that cell is placed in this
+array, but is given the attribute @code{space}.
+
+Next come arrays that map characters to single-cell dot patterns and
+dots to characters. These are created from both character-definition
+opcodes and display opcodes.
+
+Next is an array of size 256 which maps characters in this range to
+dot patterns which may consist of multiple cells. It is used, for
+example, to map @samp{@{} to dots 456-246. These mappings are created
+@c FIXME: the compdots opcode should be documented
+@c by the @opcoderef{compdots}
+by the @code{compdots}
+or the @opcoderef{comp6}.
+
+Next are two small arrays that held pointers to chains of rules
+produced by the @opcoderef{swapcd} and the @opcoderef{swapdd} and by
+some multipass, @code{context} and @code{correct} opcodes.
+
+Now we get to an array of size @code{HASHNUM} which points to chains
+of rules for forward translation.
+
+Following this is a similar array for back-translation.
+
+Finally is the @code{ruleArea}, an array of variable size to which
+various structures are mapped and to which almost everything else
+points.
+
+@node How tables are found
+@section How tables are found
+@cindex Table search path
+@cindex LOUIS_TABLEPATH
+liblouis knows where to find all the tables that have been distributed
+with it. So you can just give a table name such as @code{en-us-g2.ctb}
+and liblouis will load it. You can also give a table name which
+includes a path. If this is the first table in a list, all the tables
+in the list must be on the same path. You can specify a path on which
+liblouis will look for table names by setting the environment variable
+@env{LOUIS_TABLEPATH}. This environment variable can contain one or
+more paths separated by commas. On receiving a table name liblouis
+first checks to see if it can be found on any of these paths. If not,
+it then checks to see if it can be found in the current directory, or,
+if the first (or only) name in a table list, if it contains a
+path name, can be found on that path. If not, it checks to see if it
+can be found on the path where the distributed tables have been
+installed. If a table has already been loaded and compiled this
+path-checking is skipped.
+
+@node Deprecation of the logging system
+@section Deprecation of the logging system
+
+As of version 2.6.0 @code{lou_logFile}, @code{lou_logPrint} and
+@code{lou_logEnd} are deprecated. They are replaced by a more powerful,
+abstract API consisting of @code{lou_registerLogCallback} and
+@code{lou_setLogLevel}.
+
+Usage of @code{lou_logFile}, @code{lou_logPrint} and @code{lou_logEnd} is
+discouraged as they may not be part of future releases. Applications using
+Liblouis should implement their own logging system.
+
+During the transitional phase, @code{lou_logPrint} is registered as default
+callback in @code{lou_registerLogCallback}. @code{lou_logPrint} is overwritten
+by the first call to @code{lou_registerLogCallback} and reattached when
+@code{NULL} is set as callback. Note that calling @code{lou_logPrint} directly
+will not cause an invocation of the registered callback.
+
+@node lou_version
+@section lou_version
+@findex lou_version
+
+@example
+char *lou_version ()
+@end example
+
+This function returns a pointer to a character string containing the
+version of liblouis, plus other information, such as the release date
+and perhaps notable changes.
+
+@node lou_translateString
+@section lou_translateString
+@findex lou_translateString
+
+@example
+int lou_translateString(
+ const char *tableList,
+ const widechar *inbuf,
+ int *inlen,
+ widechar *outbuf,
+ int *outlen,
+ formtype *typeform,
+ char *spacing,
+ int mode);
+@end example
+
+This function takes a string of 16-bit Unicode characters in
+@code{inbuf} and translates it into a string of 16-bit characters in
+@code{outbuf}. Each 16-bit character produces a particular dot pattern
+in one braille cell when sent to an embosser or braille display or to
+a screen type font. Which 16-bit character represents which dot pattern
+is indicated by the character-definition and display opcodes in the
+translation table.
+
+@anchor{translation-tables}
+The @code{tableList} parameter points to a list of translation tables
+separated by commas. @xref{How tables are found}, for a description on
+how the tables are located in the file system. If only one table is
+given, no comma should be used after it. It is these tables which
+control just how the translation is made, whether in Grade 2, Grade 1,
+or something else.
+
+The tables in a list are all compiled into the same internal table.
+The list is then regarded as the name of this table. As explained in
+@ref{How to Write Translation Tables}, each table is a file which may
+be plain text, big-endian Unicode or little-endian Unicode. A table
+(or list of tables) is compiled into an internal representation the
+first time it is used. Liblouis keeps track of which tables have been
+compiled. For this reason, it is essential to call the @code{lou_free}
+function at the end of your application to avoid memory leaks. Do
+@emph{NOT} call @code{lou_free} after each translation. This will
+force liblouis to compile the translation tables each time they are
+used, leading to great inefficiency.
+
+Note that both the @code{*inlen} and @code{*outlen} parameters are
+pointers to integers. When the function is called, these integers
+contain the maximum input and output lengths, respectively. When it
+returns, they are set to the actual lengths used.
+
+The @code{typeform} parameter is used to indicate italic type,
+boldface type, computer braille, etc. It is an array of @code{formtype}
+with the same length as the input buffer pointed to by @code{*inbuf}.
+However, it is used to pass back character-by-character results, so
+enough space must be provided to match the @code{*outlen} parameter.
+Each element indicates the typeform of the corresponding character
+in the input buffer. The values and their meaning can be consulted in the
+@code{typeforms} enum in @file{liblouis.h}. These values can be
+added for multiple emphasis. If this parameter is @code{NULL}, no
+checking for type forms is done. In addition, if this parameter is not
+@code{NULL}, it is set on return to have an 8 at every position
+corresponding to a character in @code{outbuf} which was defined to
+have a dot representation containing dot 7, dot 8 or both, and to 0
+otherwise.
+
+The @code{spacing} parameter is used to indicate differences in
+spacing between the input string and the translated output string. It
+is also of the same length as the string pointed to by @code{*inbuf}.
+If this parameter is @code{NULL}, no spacing information is computed.
+
+The @code{mode} parameter specifies how the translation should be
+done. The valid values of mode are defined in @file{liblouis.h}. They
+are all powers of 2, so that a combined mode can be specified by
+adding up different values.
+
+Note that the @code{mode} parameter is an integer, not a pointer to
+an integer.
+
+A combination of the following mode flags can be used with the
+@code{lou_translateString} function:
+
+@table @code
+@item compbrlAtCursor
+If this bit is set in the @code{mode} parameter the space-bounded
+characters containing the cursor will be translated in computer
+braille.
+
+@item compbrlLeftCursor
+If this bit is set, only the characters to the left of the cursor will
+be in computer braille. This bit overrides @code{compbrlAtCursor}.
+
+@item dotsIO
+When this bit is set, during forward translation, Liblouis will produce
+output as dot patterns. During back-translation Liblouis accepts input
+as dot patterns. Note that the produced dot patterns are affected if
+you have any @opcoderef{display} defined in any of your tables.
+
+@item ucBrl
+The @code{ucBrl} (Unicode Braille) bit is used by the functions
+@code{lou_charToDots} and @code{lou_translate}. It causes the dot
+patterns to be Unicode Braille rather than the liblouis representation.
+Note that you will not notice any change when setting @code{ucBrl}
+unless @code{dotsIO} is also set. @code{lou_dotsToChar} and
+@code{lou_backTranslate} recognize Unicode braille automatically.
+
+@item partialTrans
+This flag specifies that back-translation input should be treated as an
+incomplete word. Rules that apply only for complete words or at the end
+of a word will not take effect. This is intended to be used when
+translating input typed on a braille keyboard to provide a rough idea
+to the user of the characters they are typing before the word is
+complete.
+
+@item noUndefined
+Setting this bit disables the output of hexadecimal values when
+forward-translating undefined characters (characters that are not
+matched by any rule), and dot numbers when back-translating undefined
+braille patterns (braille patterns that are not matched by any
+rule). The default is for liblouis to output the hexadecimal value (as
+'\xhhhh') of an undefined character when forward-translating and the
+dot numbers (as \ddd/) of an undefined braille pattern when
+back-translating.
+
+When back translating input from a braille keyboard cell by cell, it
+is desirable to output characters as soon as they are
+produced. Similarly, when back translating contracted braille, it is
+desirable to provide a "guess" to the user of the characters they
+typed. To achieve this, liblouis needs to have the ability to produce
+no text when indicators (which don't produce a character by
+themselves) are not followed by another cell. This works automatically
+for indicators liblouis knows about such as capital sign, number sign,
+etc., but it does not work for indicators which are not (and cannot
+be) specifically defined as indicators. For example, in UEB, dots 4 5
+6 alone produces the text "\456/". Setting the noUndefined mode
+suppresses this dot number output.
+
+@end table
+
+The function returns 1 if no errors were encountered@footnote{When the
+output buffer is not big enough, @code{lou_translateString} returns a
+partial translation that is more or less accurate up until the
+returned @code{inlen}/@code{outlen}, and treats it as a successful
+translation, i.e.@: also returns 1.} and 0 otherwise.
+
+@node lou_translate
+@section lou_translate
+@findex lou_translate
+
+@example
+int lou_translate(
+ const char *tableList,
+ const widechar *inbuf,
+ int *inlen,
+ widechar *outbuf,
+ int *outlen,
+ formtype *typeform,
+ char *spacing,
+ int *outputPos,
+ int *inputPos,
+ int *cursorPos,
+ int mode);
+@end example
+
+This function adds the parameters @code{outputPos}, @code{inputPos}
+and @code{cursorPos}, to facilitate use in screen reader programs. The
+@code{outputPos} parameter must point to an array of integers with at
+least @code{inlen} elements. On return, this array will contain the
+position in @code{outbuf} corresponding to each input position.
+Similarly, @code{inputPos} must point to an array of integers of at
+least @code{outlen} elements. On return, this array will contain the
+position in @code{inbuf} corresponding to each position in
+@code{outbuf}. @code{cursorPos} must point to an integer containing
+the position of the cursor in the input. On return, it will contain
+the cursor position in the output. Any parameter after @code{outlen}
+may be @code{NULL}. In this case, the actions corresponding to it will
+not be carried out.
+
+For a description of all other parameters, please see
+@ref{lou_translateString}.
+
+@node lou_backTranslateString
+@section lou_backTranslateString
+@findex lou_backTranslateString
+
+@example
+int lou_backTranslateString(
+ const char *tableList,
+ const widechar *inbuf,
+ int *inlen,
+ widechar *outbuf,
+ int *outlen,
+ formtype *typeform,
+ char *spacing,
+ int mode);
+@end example
+
+This is exactly the opposite of @code{lou_translateString}.
+@code{inbuf} is a string of 16-bit Unicode characters representing
+braille. @code{outbuf} will contain a string of 16--bit Unicode
+characters. @code{typeform} will indicate any emphasis found in the
+input string, while @code{spacing} will indicate any differences in
+spacing between the input and output strings. The @code{typeform} and
+@code{spacing} parameters may be @code{NULL} if this information is
+not needed. @code{mode} specifies how the back-translation
+should be done.
+
+By default, if a dot pattern in the input is undefined
+then its dot numbers will be included in the output (as \ddd/).
+This does not occur if the @code{noUndefined} mode is set;
+an undefined dot pattern simply produces no output.
+
+The @code{partialTrans} mode specifies that the input should be
+treated as an incomplete word. That is, rules that apply only for
+complete words or at the end of a word will not take effect. This is
+intended to be used when translating input typed on a braille keyboard
+to provide a rough idea to the user of the characters they are typing
+before the word is complete.
+
+@node lou_backTranslate
+@section lou_backTranslate
+@findex lou_backTranslate
+
+@example
+int lou_backTranslate(
+ const char *tableList,
+ const widechar *inbuf,
+ int *inlen,
+ widechar *outbuf,
+ int *outlen,
+ formtype *typeform,
+ char *spacing,
+ int *outputPos,
+ int *inputPos,
+ int *cursorPos,
+ int mode);
+@end example
+
+This function is exactly the inverse of @code{lou_translate}.
+
+@node lou_hyphenate
+@section lou_hyphenate
+@findex lou_hyphenate
+
+@example
+int lou_hyphenate (
+ const char *tableList,
+ const widechar *inbuf,
+ int inlen,
+ char *hyphens,
+ int mode);
+@end example
+
+This function looks at the characters in @code{inbuf} and if it finds
+a sequence of letters attempts to hyphenate it as a word. Note that
+lou_hyphenate operates on single words only, and spaces or punctuation
+marks between letters are not allowed. Leading and trailing
+punctuation marks are ignored. The table named by the @code{tableList}
+parameter must contain a hyphenation table. If it does not, the
+function does nothing. @code{inlen} is the length of the character
+string in @code{inbuf}. @code{hyphens} is an array of characters and
+must be of size @code{inlen} + 1 (to account for the NULL terminator).
+If hyphenation is successful it will have a 1 at the beginning of each
+syllable and a 0 elsewhere. If the @code{mode} parameter is 0
+@code{inbuf} is assumed to contain untranslated characters. Any
+nonzero value means that @code{inbuf} contains a translation. In this
+case, it is back-translated, hyphenation is performed, and it is
+re-translated so that the hyphens can be placed correctly. The
+@code{lou_translate} and @code{lou_backTranslate} functions are used
+in this process. @code{lou_hyphenate} returns 1 if hyphenation was
+successful and 0 otherwise. In the latter case, the contents of the
+@code{hyphens} parameter are undefined. This function was provided for
+use in liblouisutdml.
+
+@node lou_compileString
+@section lou_compileString
+@findex lou_compileString
+
+@example
+int lou_compileString (const char *tableList, const char *inString)
+@end example
+
+This function enables you to compile a table entry on the fly at
+run-time. The new entry is added to @code{tableList} and remains in force
+until @code{lou_free} is called. If @code{tableList} has not previously
+been loaded it is loaded and compiled. @code{inString} contains the
+table entry to be added. It may be anything valid. Error messages
+will be produced if it is invalid. The function returns 1 on success and
+0 on failure.
+
+@node lou_getTypeformForEmphClass
+@section lou_getTypeformForEmphClass
+@findex lou_getTypeformForEmphClass
+
+@example
+int lou_getTypeformForEmphClass (const char *tableList, const char *emphClass);
+@end example
+
+This function returns the typeform bit associated with the given
+emphasis class. If the emphasis class is undefined this function
+returns @code{0}. If errors are found error messages are logged to the
+log callback (see @code{lou_registerLogCallback}) and the return value
+is @code{0}. @code{tableList} is a list of names of table files
+separated by commas, as explained previously
+(@pxref{translation-tables,,@code{tableList} parameter in
+@code{lou_translateString}}). @code{emphClass} is the name of an
+emphasis class.
+
+@node lou_dotsToChar
+@section lou_dotsToChar
+@findex lou_dotsToChar
+
+@example
+int lou_dotsToChar (
+ const char *tableList,
+ const widechar *inbuf,
+ widechar *outbuf,
+ int length,
+ int mode)
+@end example
+
+This function takes a widechar string in @code{inbuf} consisting of dot
+patterns and converts it to a widechar string in @code{outbuf}
+consisting of characters according to the specifications in
+@code{tableList}. @code{length} is the length of both @code{inbuf} and
+@code{outbuf}. The dot patterns in @code{inbuf} can be in either
+liblouis format or Unicode braille. The function returns 1 on success
+and 0 on failure.
+
+Note that the @code{mode} parameter has no effect and is deprecated.
+
+@node lou_charToDots
+@section lou_charToDots
+@findex lou_charToDots
+
+@example
+int lou_charToDots (
+ const char *tableList,
+ const widechar *inbuf,
+ widechar *outbuf,
+ int length,
+ int mode)
+@end example
+
+This function is the inverse of @code{lou_dotsToChar}. It takes a
+widechar string in @code{inbuf} consisting of characters and converts it
+to a widechar string in @code{outbuf} consisting of dot patterns
+according to the specifications in @code{tableList}. @code{length} is the
+length of both @code{inbuf} and @code{outbuf}. The dot patterns in
+@code{outbufbuf} are in liblouis format if the mode bit @code{ucBrl} is
+not set and in Unicode format if it is set. The function returns 1 on
+success and 0 on failure.
+
+@node lou_registerLogCallback
+@section lou_registerLogCallback
+@findex lou_registerLogCallback
+
+@example
+typedef void (*logcallback) (
+ int level,
+ const char *message);
+
+void lou_registerLogCallback (
+ logcallback callback);
+@end example
+
+This function can be used to register a custom logging callback. The
+callback must take two arguments, the log level and the message string. By default
+log messages are printed to stderr, or if a filename was specified
+with @code{lou_logFile} then messages are logged to that
+file. @code{lou_registerLogCallback} overrides the default
+callback. Passing @code{NULL} resets to the default callback.
+
+@node lou_setLogLevel
+@section lou_setLogLevel
+@findex lou_setLogLevel
+
+@example
+typedef enum
+@{
+ LOU_LOG_ALL = 0,
+ LOU_LOG_DEBUG = 10000,
+ LOU_LOG_INFO = 20000,
+ LOU_LOG_WARN = 30000,
+ LOU_LOG_ERROR = 40000,
+ LOU_LOG_FATAL = 50000,
+ LOU_LOG_OFF = 60000
+@} logLevels;
+void lou_setLogLevel (
+ logLevels level);
+@end example
+
+This function can be used to influence the amount of logging, from
+fatal error messages only to detailed debugging messages. Supported
+values are @code{LOU_LOG_DEBUG}, @code{LOU_LOG_INFO},
+@code{LOU_LOG_WARN}, @code{LOU_LOG_ERROR}, @code{LOU_LOG_FATAL} and
+@code{LOU_LOG_OFF}. Enabling logging at a given level also enables
+logging at all higher levels. Setting the level to @code{LOU_LOG_OFF}
+disables logging. The default level is @code{LOU_LOG_INFO}.
+
+@node lou_logFile
+@section lou_logFile (deprecated)
+@findex lou_logFile
+
+@example
+void lou_logFile (
+ char *fileName);
+@end example
+
+This function is used when it is not convenient either to let messages
+be printed on stderr or to use redirection, as when liblouis is used
+in a GUI application or in liblouisutdml. Any error messages generated
+will be printed to the file given in this call. The entire path name of
+the file must be given.
+
+This function is deprecated. See @ref{Deprecation of the logging system}.
+
+@node lou_logPrint
+@section lou_logPrint (deprecated)
+@findex lou_logPrint
+
+@example
+void lou_logPrint (
+ char *format,
+ ...);
+@end example
+
+This function is called like @code{fprint}. It can be used by other
+libraries to print messages to the file specified by the call to
+@code{lou_logFile}. In particular, it is used by the companion
+library liblouisutdml.
+
+This function is deprecated. See @ref{Deprecation of the logging system}.
+
+@node lou_logEnd
+@section lou_logEnd (deprecated)
+@findex lou_logEnd
+
+@example
+lou_logEnd ();
+@end example
+
+This function is used at the end of processing a document to close the
+log file, so that it can be read by the rest of the program.
+
+This function is deprecated. See @ref{Deprecation of the logging system}.
+
+@node lou_setDataPath
+@section lou_setDataPath
+@findex lou_setDataPath
+
+@example
+char *lou_setDataPath (
+ char *path);
+@end example
+
+This function is used to tell liblouis and liblouisutdml where tables
+and files are located. It thus makes them completely relocatable, even
+on Linux. The @code{path} is the directory where the subdirectories
+@code{liblouis/tables} and @code{liblouisutdml/lbu_files} are rooted
+or located. The function returns a pointer to the @code{path}.
+
+@node lou_getDataPath
+@section lou_getDataPath
+@findex lou_getDataPath
+
+@example
+char *lou_getDataPath ();
+@end example
+
+This function returns a pointer to the path set by
+@code{lou_setDataPath}. If no path has been set it returns
+@code{NULL}.
+
+@node lou_getTable
+@section lou_getTable
+@findex lou_getTable
+
+@example
+void *lou_getTable (
+ char *tableList);
+@end example
+
+@code{tableList} is a list of names of table files separated by
+commas, as explained previously
+(@pxref{translation-tables,,@code{tableList} parameter in
+@code{lou_translateString}}). If no errors are found this function
+returns a pointer to the compiled table. If errors are found error
+messages are logged to the log callback (see
+@code{lou_registerLogCallback}). Errors result in a @code{NULL}
+pointer being returned.
+
+@node lou_findTable
+@section lou_findTable
+@findex lou_findTable
+
+@example
+char *lou_findTable (const char *query);
+@end example
+
+This function can be used to find a table based on
+metadata. @code{query} is a string in the special @ref{Query
+Syntax,query syntax}. It is matched against @ref{Table Metadata,table
+metadata} inside the tables that were previously indexed with
+@ref{lou_indexTables,@code{lou_indexTables}}. Returns the file name of
+the best match. Returns @code{NULL} if the query is invalid or if no
+match can be found.
+
+The match algorithm works as follows:
+
+@itemize @bullet
+@item
+For every table a match quotient with the query is computed. The table
+with the highest (positive) match quotient wins. If no table has a
+positive quotient, there is no match.
+@item
+A query is a list of features. Features defined first have a higher
+importance (have a higher impact on the final quotient) than features
+defined later.
+@item
+A feature that matches a metadata field in the table (keys equal and
+values equal, or both values absent) adds to the quotient.
+@item
+A feature that is undefined in the table (no field with that key)
+creates a medium penalty.
+@item
+A feature that is defined in the table but does not match (keys equal
+but values not equal) creates the highest penalty.
+@item
+Every field in the table that has no corresponding feature in the
+query creates a very small penalty.
+@end itemize
+
+@node lou_indexTables
+@section lou_indexTables
+@findex lou_indexTables
+
+@example
+void lou_indexTables (const char **tables);
+@end example
+
+This function must be called prior to
+@ref{lou_findTable,@code{lou_findTable}}. It parses, analyzes and
+indexes all specified tables. @code{tables} must be an array of file
+names. Tables that contain invalid metadata are ignored.
+
+@node lou_checkTable
+@section lou_checkTable
+@findex lou_checkTable
+
+@example
+int lou_checkTable (const char *tableList);
+@end example
+
+This function does the same as @code{lou_getTable} but does not return
+a pointer to the resulting table. It is to be preferred if only the
+validity of a table needs to be checked. @code{tableList} is a list of
+names of table files separated by commas, as explained previously
+(@pxref{translation-tables,,@code{tableList} parameter in
+@code{lou_translateString}}). If no errors are found this function
+returns a non-zero. If errors are found error messages are logged to
+the log callback (see @code{lou_registerLogCallback}) and the return
+value is @code{0}.
+
+@node lou_readCharFromFile
+@section lou_readCharFromFile
+@findex lou_readCharFromFile
+
+@example
+int lou_readCharFromFile (
+ const char *fileName,
+ int *mode);
+@end example
+
+This function is provided for situations where it is necessary to read
+a file which may contain little-endian or big-endian 16-bit Unicode
+characters or ASCII8 characters. The return value is a little-endian
+character, encoded as an integer. The @code{fileName} parameter is the
+name of the file to be read. The @code{mode} parameter is a pointer to
+an integer which must be set to 1 on the first call. After that, the
+function takes care of it. On end-of-file the function returns
+@code{EOF}.
+
+@node lou_free
+@section lou_free
+@findex lou_free
+
+@example
+void lou_free ();
+@end example
+
+This function should be called at the end of the application to free
+all memory allocated by liblouis. Failure to do so will result in
+memory leaks. Do @emph{NOT} call @code{lou_free} after each
+translation. This will force liblouis to compile the translation
+tables every time they are used, resulting in great inefficiency.
+
+@node lou_charSize
+@section lou_charSize
+@findex lou_charSize
+
+@example
+int lou_charSize ();
+@end example
+
+This function returns the size of @code{widechar} in bytes and can
+therefore be used to differentiate between 16-bit and 32bit-Unicode
+builds of liblouis.
+
+@node Python bindings
+@section Python bindings
+
+There are Python bindings for @code{lou_translateString},
+@code{lou_translate}, @code{lou_backTranslateString},
+@code{lou_backTranslate}, @code{lou_hyphenate}, @code{checkTable},
+@code{lou_compileString} and @code{lou_version}. For installation
+instructions see the the @file{README} file in the @file{python}
+directory. Usage information is included in the Python module itself.
+
+
+@node Concept Index
+@unnumbered Concept Index
+@printindex cp
+
+@node Opcode Index
+@unnumbered Opcode Index
+@printindex opcode
+
+@node Function Index
+@unnumbered Function Index
+@printindex fn
+
+@node Program Index
+@unnumbered Program Index
+@printindex pg
+
+@bye
+
+@c The following list is a list of exceptions for the ispell spell
+@c checker
+
+@c LocalWords: liblouis opcode args BRLTTY ViewPlus Abilitiessoft LGPL lou
+@c LocalWords: checktable allround checkhyphens Opcodes Multipass dotsToChar
+@c LocalWords: translateString backTranslateString backTranslate charToDots
+@c LocalWords: compileString logFile logPrint checkyaml findTable
+@c LocalWords: getTable checkTable readCharFromFile itemx charSize
+@c LocalWords: README liblouisxml pindex samp kbd opcodes opcoderef numsign
+@c LocalWords: FIXME ctb nemeth filename multipass suboperand uplow litdigit
+@c LocalWords: begcaps endcaps letsign noletsign largesign typeform
+@c LocalWords: noletsignbefore noletsignafter compbrl firstwordital
+@c LocalWords: lenitalphrase doubleOpcode lastworditalbefore firstletterital
+@c LocalWords: lastworditalafter lastletterital firstwordbold UTF
+@c LocalWords: singleletterital lastwordboldbefore lastwordboldafter
+@c LocalWords: firstletterbold lastletterbold lenboldphrase filll
+@c LocalWords: singleletterbold firstwordunder lastwordunderbefore
+@c LocalWords: lastwordunderafter firstletterunder lastletterunder
+@c LocalWords: singleletterunder lenunderphrase begcomp endcomp decpoint texi
+@c LocalWords: capsnocont noback nofor texinfo setfilename settitle direntry
+@c LocalWords: dircategory finalout defindex opcodeindex noindent uref vskip
+@c LocalWords: titlepage insertcopying ifnottex dir detailmenu italword RET
+@c LocalWords: TranslationTableHeader txt cti nocross exactdots nocont emph
+@c LocalWords: prepunc postpunc repword joinword lowword sufword prfword API
+@c LocalWords: begword begmidword midword midendword endword partword begnum
+@c LocalWords: midnum endnum joinnum swapcd swapdd swapcc multind endLog
+@c LocalWords: backtranslation compileTranslationTable typedef louis ruleArea
+@c LocalWords: HASHNUM capitalSign compdots findex const inbuf outbuf outlen
+@c LocalWords: tableList TABLEPATH widechar inputPos cursorPos outputPos
+@c LocalWords: inlen compbrlAtCursor compbrlLeftCursor trantab stderr endian
+@c LocalWords: tablelist fileName printindex deprecatedopcode setDataPath
+@c LocalWords: getDataPath MathML suboperands logEnd liblouisutdml whitespace
+@c LocalWords: xhhhh yhhhhh zhhhhhhhh OpenOffice documentencoding
+@c LocalWords: YAML JSON logLevels nocontractsign OSX DLL env NVDA
+@c LocalWords: MERCHANTABILITY registerLogCallback setLogLevel brf
+@c LocalWords: cindex chardefs xhtml pxref dec multi hyph dic Aa al
+@c LocalWords: mrow mfrac emphclass transnote subsubsection begemph
+@c LocalWords: endemph emphletter begemphword endemphword www cd th
+@c LocalWords: lenemphphrase begemphphrase endemphphrase andthe se
+@c LocalWords: abrege decrement pre cornf comf scano cornm cornp po
+@c LocalWords: h's brl testtrans UCS asis libyaml url yaml formtype
+@c LocalWords: testmode iftex unicode ueb xfail eo noContractions
+@c LocalWords: dotsIO ucBrl noUndefined partialTrans capsletter
+@c LocalWords: abc doctest inString enum cp outbufbuf logcallback fprint
+@c LocalWords: lbu EOF heckTable fn ispell getTypeformForEmphClass
+@c LocalWords: indexTables begcapsword endcapsword typeforms
+@c LocalWords: endemphphraseopcode emphClass BrailleSense HumanWare
+@c LocalWords: BrailleNote refreshable
diff --git a/extra/generate-display-names/Makefile b/extra/generate-display-names/Makefile
new file mode 100644
index 0000000..a5430a1
--- /dev/null
+++ b/extra/generate-display-names/Makefile
@@ -0,0 +1,23 @@
+CC := gcc
+DISPLAY_NAMES_FILE := display-names
+
+export LOUIS_TABLEPATH = $(CURDIR)/../../tables
+export GOPATH = $(CURDIR)/.go-packages
+
+.PHONY : check
+check : generate
+ ./$< $(DISPLAY_NAMES_FILE) >$<.log 2>$<.log
+
+generate : generate.o displayLanguage.a ../../liblouis/liblouis.la
+ ../../libtool --tag=CC --mode=link $(CC) -o $@ $^ -lpthread
+
+generate.o : generate.c displayLanguage.h
+ $(CC) -I. -I../../liblouis -g -O2 -c -o $@ $<
+
+displayLanguage.a displayLanguage.h : displayLanguage.go
+ go get golang.org/x/text/language/display
+ go build -buildmode=c-archive $<
+
+.PHONY : clean
+clean :
+ rm -rf displayLanguage.a displayLanguage.h $(GOPATH)
diff --git a/extra/generate-display-names/display-names b/extra/generate-display-names/display-names
new file mode 100644
index 0000000..74065a2
--- /dev/null
+++ b/extra/generate-display-names/display-names
@@ -0,0 +1,142 @@
+* ../../tables/afr-za-g1.ctb Afrikaans uncontracted braille
+* ../../tables/afr-za-g2.ctb Afrikaans contracted braille
+* ../../tables/ar.tbl Arabic uncontracted braille
+* ../../tables/ar-ar-g2.ctb Arabic contracted braille
+* ../../tables/ar-ar-comp8.utb Arabic computer braille
+* ../../tables/as.tbl Assamese braille
+* ../../tables/awa.tbl Awadhi braille
+* ../../tables/bg.tbl Bulgarian computer braille
+* ../../tables/bh.tbl Bihari braille
+* ../../tables/bn.tbl Bengali braille
+* ../../tables/bo.tbl Tibetan computer braille
+* ../../tables/bra.tbl Braj braille
+* ../../tables/ca.tbl Catalan braille
+* ../../tables/chr-us-g1.ctb Cherokee braille
+* ../../tables/ckb.tbl Kurdish braille
+* ../../tables/cs.tbl Czech braille
+* ../../tables/cs-comp8.utb Czech computer braille
+* ../../tables/cy-cy-g1.utb Welsh uncontracted braille
+* ../../tables/cy.tbl Welsh contracted braille
+* ../../tables/da-dk-g08.ctb Danish computer braille
+* ../../tables/da-dk-g16-lit.ctb Danish 6-dot uncontracted braille
+* ../../tables/da-dk-g16.ctb Danish 6-dot uncontracted braille
+* ../../tables/da-dk-g18.ctb Danish 8-dot uncontracted braille
+* ../../tables/da-dk-g26-lit.ctb Danish 6-dot contracted braille
+* ../../tables/da-dk-g26.ctb Danish 6-dot contracted braille
+* ../../tables/da-dk-g26l-lit.ctb Danish 6-dot partially contracted braille
+* ../../tables/da-dk-g26l.ctb Danish 6-dot partially contracted braille
+* ../../tables/da-dk-g28.ctb Danish 8-dot contracted braille
+* ../../tables/da-dk-g28l.ctb Danish 8-dot partially contracted braille
+* ../../tables/de-g0.utb German uncontracted braille
+* ../../tables/de-g1.ctb German partially contracted braille
+* ../../tables/de-g2.ctb German contracted braille
+* ../../tables/dra.tbl Dravidian computer braille
+* ../../tables/el.tbl Greek braille
+ ../../tables/grc-international-en.utb Greek internationalized braille as used by English speakers
+* ../../tables/fa-ir-comp8.ctb Persian computer braille
+* ../../tables/fa-ir-g1.utb Persian braille
+ ../../tables/en-ueb-g1.ctb Unified English uncontracted braille
+ ../../tables/en-ueb-g2.ctb Unified English contracted braille
+ ../../tables/en_CA.tbl English computer braille as used in Canada
+ ../../tables/en-gb-g1.utb English uncontracted braille as used in the U.K.
+ ../../tables/en_GB.tbl English contracted braille as used in the U.K.
+ ../../tables/en-gb-comp8.ctb English computer braille as used in the U.K.
+ ../../tables/en-nabcc.utb North American Braille Computer Code
+ ../../tables/en-us-g1.ctb English uncontracted braille as used in the U.S.
+ ../../tables/en-us-comp6.ctb English 6-dot computer braille as used in the U.S.
+ ../../tables/en_US-comp8-ext.tbl English 8-dot computer braille as used in the U.S.
+ ../../tables/en_US.tbl English contracted braille as used in the U.S.
+* ../../tables/eo.tbl Esperanto braille
+* ../../tables/eo-g1-x-system.ctb Esperanto x-system braille
+* ../../tables/es.tbl Spanish uncontracted braille
+* ../../tables/es-g2.ctb Spanish contracted braille
+* ../../tables/Es-Es-G0.utb Spanish computer braille
+* ../../tables/et.tbl Estonian computer braille
+* ../../tables/fi.utb Finnish braille
+* ../../tables/fi-fi-8dot.ctb Finnish computer braille
+* ../../tables/fr-bfu-comp6.utb French uncontracted braille
+* ../../tables/fr-bfu-comp8.utb French computer braille
+* ../../tables/fr-bfu-g2.ctb French contracted braille
+* ../../tables/ga-g1.utb Irish uncontracted braille
+* ../../tables/ga-g2.ctb Irish contracted braille
+* ../../tables/gd.tbl Scottish Gaelic computer braille
+* ../../tables/gez.tbl Ethiopic braille
+* ../../tables/gon.tbl Gondi braille
+* ../../tables/gu.tbl Gujarati braille
+* ../../tables/haw-us-g1.ctb Hawaiian braille
+* ../../tables/he.tbl Hebrew computer braille
+* ../../tables/hi.tbl Hindi braille
+* ../../tables/hr-g1.tbl Croatian braille
+* ../../tables/hr-comp8.tbl Croatian computer braille
+* ../../tables/hu-hu-comp8.ctb Hungarian computer braille
+* ../../tables/hu.tbl Hungarian partially contracted braille
+* ../../tables/hu-hu-g2.ctb Hungarian contracted braille
+* ../../tables/hy.tbl Armenian computer braille
+* ../../tables/is.tbl Icelandic braille
+* ../../tables/it.tbl Italian braille
+* ../../tables/it-it-comp8.utb Italian computer braille
+* ../../tables/iu-ca-g1.ctb Inuktitut braille
+* ../../tables/kha.tbl Khasi braille
+* ../../tables/kn.tbl Kannada braille
+* ../../tables/ko-2006-g2.ctb Korean contracted braille (2006 standard)
+* ../../tables/ko-2006-g1.ctb Korean uncontracted braille (2006 standard)
+* ../../tables/ko-g2.ctb Korean contracted braille
+* ../../tables/ko-g1.ctb Korean uncontracted braille
+* ../../tables/kok.tbl Konkani braille
+* ../../tables/kru.tbl Kurukh braille
+* ../../tables/lt.tbl Lithuanian 8-dot braille
+* ../../tables/lt-6dot.tbl Lithuanian 6-dot braille
+* ../../tables/lv.tbl Latvian braille
+* ../../tables/mao-nz-g1.ctb Maori braille
+* ../../tables/ml.tbl Malayalam braille
+* ../../tables/mn-MN-g1.utb Mongolian uncontracted braille
+* ../../tables/mn-MN-g2.ctb Mongolian contracted braille
+* ../../tables/mni.tbl Manipuri braille
+* ../../tables/mr.tbl Marathi braille
+* ../../tables/mt.tbl Maltese computer braille
+* ../../tables/mun.tbl Munda braille
+* ../../tables/mwr.tbl Marwari braille
+* ../../tables/no-no-comp8.ctb Norwegian computer braille
+* ../../tables/no-no-g0.utb Norwegian 6-dot uncontracted braille
+* ../../tables/no-no-8dot.utb Norwegian 8-dot uncontracted braille
+ ../../tables/no-no-8dot-fallback-6dot-g0.utb Norwegian 8-dot uncontracted braille with 6-dot fallback
+* ../../tables/no-no-g1.ctb Norwegian grade 1 contracted braille
+* ../../tables/no-no-g2.ctb Norwegian grade 2 contracted braille
+* ../../tables/no.tbl Norwegian grade 3 contracted braille
+* ../../tables/ne.tbl Nepali braille
+ ../../tables/nl.tbl Dutch braille as used in the Netherlands
+ ../../tables/nl_BE.tbl Dutch braille as used in Belgium
+* ../../tables/or.tbl Oriya braille
+* ../../tables/pa.tbl Punjabi braille
+* ../../tables/pi.tbl Pali braille
+* ../../tables/pl-pl-comp8.ctb Polish computer braille
+* ../../tables/pl.tbl Polish braille
+* ../../tables/pt.tbl Portuguese contracted braille
+* ../../tables/pt-pt-g1.utb Portuguese uncontracted braille
+* ../../tables/pt-pt-comp8.ctb Portuguese computer braille
+* ../../tables/ro.tbl Romanian computer braille
+* ../../tables/ru.tbl Russian braille
+* ../../tables/ru-compbrl.ctb Russian computer braille
+* ../../tables/sa.tbl Sanskrit braille
+* ../../tables/sd.tbl Sindhi braille
+* ../../tables/sv.tbl Swedish braille
+* ../../tables/sv-1996.ctb Swedish computer braille (1996 standard)
+* ../../tables/sv-1989.ctb Swedish computer braille (1989 standard)
+* ../../tables/sk.tbl Slovak braille
+* ../../tables/sl.tbl Slovenian braille
+* ../../tables/sl-si-comp8.ctb Slovenian computer braille
+* ../../tables/sr.tbl Serbian braille
+* ../../tables/ta-ta-g1.ctb Tamil braille
+* ../../tables/ta.tbl Tamil computer braille
+* ../../tables/te.tbl Telugu braille
+* ../../tables/tr.tbl Turkish computer braille
+* ../../tables/ur-pk-g1.utb Urdu uncontracted braille
+* ../../tables/ur-pk-g2.ctb Urdu contracted braille
+* ../../tables/vi.ctb Vietnamese computer braille
+* ../../tables/vi.tbl Vietnamese braille
+ ../../tables/zh_CHN.tbl Chinese braille without tones, for simplified Chinese characters
+* ../../tables/zh_HK.tbl Cantonese braille
+ ../../tables/zh_TW.tbl Taiwanese braille
+ ../../tables/zhcn-g1.ctb Chinese braille with tones
+ ../../tables/zhcn-g2.ctb Two-cell Chinese braille
+
diff --git a/extra/generate-display-names/displayLanguage.go b/extra/generate-display-names/displayLanguage.go
new file mode 100644
index 0000000..fa80b3f
--- /dev/null
+++ b/extra/generate-display-names/displayLanguage.go
@@ -0,0 +1,68 @@
+package main
+
+import (
+ "C"
+ "golang.org/x/text/language"
+ "golang.org/x/text/language/display"
+)
+
+//export DisplayLanguage
+func DisplayLanguage(lang_c *C.char) *C.char {
+ var lang string
+ var ret string
+ lang = C.GoString(lang_c)
+ switch (lang) {
+ case "bh":
+ ret = "Bihari";
+ break;
+ case "bn":
+ ret = "Bengali";
+ break;
+ case "ckb":
+ ret = "Kurdish";
+ break;
+ case "dra":
+ ret = "Dravidian";
+ break;
+ case "en-GB":
+ ret = "U.K. English";
+ break;
+ case "en-US":
+ ret = "U.S. English";
+ break;
+ case "eo-xsistemo":
+ ret = "Esperanto x-system";;
+ break;
+ case "gez":
+ ret = "Ethiopic";
+ break;
+ case "mun":
+ ret = "Munda";
+ break;
+ case "no":
+ ret = "Norwegian";
+ break;
+ case "or":
+ ret = "Oriya";
+ break;
+ default:
+ var namer display.Namer
+ namer = display.English.Languages()
+ ret = namer.Name(language.MustParse(lang))
+ }
+ return C.CString(ret)
+}
+
+//export NativeLanguage
+func NativeLanguage(lang_c *C.char) *C.char {
+ var lang string
+ var ret string
+ var namer display.Namer
+ lang = C.GoString(lang_c)
+ namer = display.Self
+ ret = namer.Name(language.MustParse(lang))
+ return C.CString(ret)
+}
+
+// main function required for interfacing with C
+func main() {}
diff --git a/extra/generate-display-names/generate.c b/extra/generate-display-names/generate.c
new file mode 100644
index 0000000..cbbfa23
--- /dev/null
+++ b/extra/generate-display-names/generate.c
@@ -0,0 +1,272 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "internal.h"
+#include "displayLanguage.h"
+
+static const char *
+displayLanguage(const char *lang) {
+ return DisplayLanguage((char *)lang);
+}
+
+static const char *
+getDisplayName(const char *table) {
+ return lou_getTableInfo(table, "display-name");
+}
+
+static char *
+generateDisplayName(const char *table) {
+ char *name;
+ char *language;
+ char *locale;
+ char *type;
+ char *dots;
+ char *contraction;
+ char *grade;
+ char *version;
+ char *query;
+ char **matches;
+ char *n;
+ char *q;
+ char **m;
+ name = (char *)malloc(100 * sizeof(*name));
+ n = name;
+ query = (char *)malloc(100 * sizeof(*query));
+ q = query;
+ locale = lou_getTableInfo(table, "locale");
+ if (!locale)
+ return NULL;
+ language = displayLanguage(locale);
+ n += sprintf(n, "%s", language);
+ q += sprintf(q, "locale:%s", locale);
+ free(locale);
+ type = lou_getTableInfo(table, "type");
+ if (type) {
+ q += sprintf(q, " type:%s", type);
+ if (!strcmp(type, "computer")) {
+ dots = lou_getTableInfo(table, "dots");
+ if (dots) {
+ if (!strcmp(dots, "6")) {
+ n += sprintf(n, " %s-dot", dots);
+ } else {
+ char *q_save = q;
+ q += sprintf(q, " dots:6");
+ matches = lou_findTables(query);
+ if (matches) {
+ n += sprintf(n, " %s-dot", dots);
+ for (m = matches; *m; m++) free(*m);
+ free(matches);
+ }
+ q = q_save;
+ }
+ q += sprintf(q, " dots:%s", dots);
+ free(dots);
+ }
+ n += sprintf(n, " %s", type);
+ } else if (!strcmp(type, "literary")) {
+ int uncontracted = 0;
+ int fullyContracted = 0;
+ int partiallyContracted = 0;
+ int otherUncontracted = 0;
+ int otherFullyContracted = 0;
+ int otherPartiallyContracted = 0;
+ int twoOrMorePartiallyContracted = 0;
+ contraction = lou_getTableInfo(table, "contraction");
+ if (contraction) {
+ char *q_save = q;
+ uncontracted = !strcmp(contraction, "no");
+ fullyContracted = !strcmp(contraction, "full");
+ partiallyContracted = !strcmp(contraction, "partial");
+ otherUncontracted = 0;
+ q += sprintf(q, " contraction:no");
+ matches = lou_findTables(query);
+ if (matches) {
+ if (!uncontracted || matches[0] && matches[1])
+ otherUncontracted = 1;
+ for (m = matches; *m; m++) free(*m);
+ free(matches);
+ }
+ q = q_save;
+ otherPartiallyContracted = 0;
+ twoOrMorePartiallyContracted = 0;
+ grade = NULL;
+ q += sprintf(q, " contraction:partial");
+ matches = lou_findTables(query);
+ if (matches) {
+ for (m = matches; *m; m++) {
+ if (!twoOrMorePartiallyContracted) {
+ char *g = lou_getTableInfo(*m, "grade");
+ if (g) {
+ if (!grade)
+ grade = g;
+ else if (strcmp(grade, g))
+ twoOrMorePartiallyContracted = 1;
+ }
+ }
+ free(*m);
+ }
+ free(matches);
+ if (!partiallyContracted || twoOrMorePartiallyContracted)
+ otherPartiallyContracted = 1;
+ if (twoOrMorePartiallyContracted)
+ grade = lou_getTableInfo(table, "grade");
+ else
+ grade = NULL;
+ }
+ q = q_save;
+ otherFullyContracted = 0;
+ q += sprintf(q, " contraction:full");
+ matches = lou_findTables(query);
+ if (matches) {
+ if (!fullyContracted || matches[0] && matches[1])
+ otherFullyContracted = 1;
+ for (m = matches; *m; m++) free(*m);
+ free(matches);
+ }
+ q = q_save;
+ q += sprintf(q, " contraction:%s", contraction);
+ free(contraction);
+ }
+ dots = lou_getTableInfo(table, "dots");
+ if (dots) {
+ int otherDots = 0;
+ matches = lou_findTables(query);
+ if (matches) {
+ for (m = matches; *m; m++) {
+ if (!otherDots) {
+ char *d = lou_getTableInfo(*m, "dots");
+ if (d && strcmp(dots, d))
+ otherDots = 1;
+ }
+ free(*m);
+ }
+ }
+ if (otherDots)
+ n += sprintf(n, " %s-dot", dots);
+ free(dots);
+ }
+ if (uncontracted) {
+ if (otherFullyContracted || otherPartiallyContracted)
+ n += sprintf(n, " uncontracted");
+ } else if (fullyContracted) {
+ if (otherPartiallyContracted) {
+ if (twoOrMorePartiallyContracted && grade)
+ n += sprintf(n, " grade %s contracted", grade);
+ else
+ n += sprintf(n, " contracted");
+ } else if (otherUncontracted) {
+ n += sprintf(n, " contracted");
+ }
+ } else if (partiallyContracted) {
+ if (twoOrMorePartiallyContracted && grade)
+ n += sprintf(n, " grade %s contracted", grade);
+ else
+ n += sprintf(n, " partially contracted");
+ }
+ free(grade);
+ }
+ free(type);
+ }
+ n += sprintf(n, " braille");
+ version = lou_getTableInfo(table, "version");
+ if (version) {
+ n += sprintf(n, " (%s standard)", version);
+ free(version);
+ }
+ return name;
+}
+
+int main(int argc, char **argv) {
+ int result = 0;
+ FILE *fp;
+ char *line = NULL;
+ size_t len = 0;
+ if (argc != 2) {
+ fprintf(stderr, "One argument expected\n");
+ exit(EXIT_FAILURE);
+ }
+ fp = fopen(argv[1], "rb");
+ if (!fp) {
+ fprintf(stderr, "Could not open file: %s\n", argv[1]);
+ exit(EXIT_FAILURE);
+ }
+ lou_setLogLevel(LOU_LOG_WARN);
+ while (getline(&line, &len, fp) != -1) {
+ char *cp = line;
+ int generate = 0;
+ if (*cp == '*') {
+ generate = 1;
+ cp++;
+ }
+ while (*cp && *cp == ' ')
+ cp++;
+ if (*cp == '\n' || *cp == '#') {
+ if (!generate)
+ continue;
+ else
+ goto parse_error;
+ } else if (*cp) {
+ char *table = cp;
+ cp++;
+ while (*cp && *cp != ' ' && *cp != '\n' && *cp != '#')
+ cp++;
+ if (*cp == ' ') {
+ cp++;
+ while (*cp && *cp == ' ')
+ cp++;
+ if (*cp && *cp != '\n' && *cp != '#') {
+ char *expectedName = cp;
+ cp++;
+ while (*cp && *cp != '\n' && *cp != '#')
+ cp++;
+ if (*cp) {
+ cp--;
+ while (*cp == ' ')
+ cp--;
+ cp++;
+ *cp = '\0';
+ cp = table;
+ while (*cp != ' ')
+ cp++;
+ *cp = '\0';
+ const char *actualName = getDisplayName(table);
+ if (!actualName) {
+ fprintf(stderr, "No display-name field in table %s\n", table);
+ result = 1;
+ } else {
+ if (strcmp(actualName, expectedName) != 0) {
+ fprintf(stderr, "%s: %s != %s\n", table, actualName, expectedName);
+ fprintf(stderr, " cat %s | sed 's/^\\(#-display-name: *\\).*$/\\1%s/g' > %s.tmp\n", table, expectedName, table);
+ fprintf(stderr, " mv %s.tmp %s\n", table, table);
+ result = 1;
+ }
+ const char *generatedName = generateDisplayName(table);
+ if (!generatedName || !*generatedName) {
+ if (generate) {
+ fprintf(stderr, "No display-name could be generated for table %s\n", table);
+ result = 1;
+ }
+ } else if (strcmp(actualName, generatedName) != 0) {
+ if (generate) {
+ fprintf(stderr, "%s: %s != %s\n", table, actualName, generatedName);
+ result = 1;
+ }
+ } else {
+ if (!generate) {
+ fprintf(stderr, "%s: %s == %s\n", table, actualName, generatedName);
+ result = 1;
+ }
+ }
+ }
+ continue;
+ }
+ }
+ }
+ }
+ parse_error:
+ fprintf(stderr, "Could not parse line: %s\n", line);
+ exit(EXIT_FAILURE);
+ }
+ free(line);
+ return result;
+}
diff --git a/gnulib/Makefile.am b/gnulib/Makefile.am
new file mode 100644
index 0000000..35f58f9
--- /dev/null
+++ b/gnulib/Makefile.am
@@ -0,0 +1,814 @@
+## DO NOT EDIT! GENERATED AUTOMATICALLY!
+## Process this file with automake to produce Makefile.in.
+# Copyright (C) 2002-2019 Free Software Foundation, Inc.
+#
+# 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
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This file is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this file. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License,
+# this file may be distributed as part of a program that
+# contains a configuration script generated by Autoconf, under
+# the same distribution terms as the rest of that program.
+#
+# Generated by gnulib-tool.
+# Reproduce by:
+# gnulib-tool --import \
+# --lib=libgnu \
+# --source-base=gnulib \
+# --m4-base=gnulib/m4 \
+# --doc-base=doc \
+# --tests-base=tests \
+# --aux-dir=build-aux \
+# --no-conditional-dependencies \
+# --libtool \
+# --macro-prefix=gl \
+# --no-vc-files \
+# dirent \
+# lib-msvc-compat \
+# malloc-gnu \
+# manywarnings \
+# realloc-gnu \
+# setenv \
+# strndup
+
+AUTOMAKE_OPTIONS = 1.11 gnits
+
+SUBDIRS =
+noinst_HEADERS =
+noinst_LIBRARIES =
+noinst_LTLIBRARIES =
+EXTRA_DIST =
+BUILT_SOURCES =
+SUFFIXES =
+MOSTLYCLEANFILES = core *.stackdump
+MOSTLYCLEANDIRS =
+CLEANFILES =
+DISTCLEANFILES =
+MAINTAINERCLEANFILES =
+# No GNU Make output.
+EXTRA_DIST += m4/gnulib-cache.m4
+
+AM_CPPFLAGS =
+AM_CFLAGS =
+
+noinst_LTLIBRARIES += libgnu.la
+
+libgnu_la_SOURCES =
+libgnu_la_LIBADD = $(gl_LTLIBOBJS)
+libgnu_la_DEPENDENCIES = $(gl_LTLIBOBJS)
+EXTRA_libgnu_la_SOURCES =
+libgnu_la_LDFLAGS = $(AM_LDFLAGS)
+libgnu_la_LDFLAGS += -no-undefined
+
+## begin gnulib module absolute-header
+
+# Use this preprocessor expression to decide whether #include_next works.
+# Do not rely on a 'configure'-time test for this, since the expression
+# might appear in an installed header, which is used by some other compiler.
+HAVE_INCLUDE_NEXT = (__GNUC__ || 60000000 <= __DECC_VER)
+
+## end gnulib module absolute-header
+
+## begin gnulib module alloca-opt
+
+BUILT_SOURCES += $(ALLOCA_H)
+
+# We need the following in order to create <alloca.h> when the system
+# doesn't have one that works with the given compiler.
+if GL_GENERATE_ALLOCA_H
+alloca.h: alloca.in.h $(top_builddir)/config.status
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's|@''HAVE_ALLOCA_H''@|$(HAVE_ALLOCA_H)|g' < $(srcdir)/alloca.in.h; \
+ } > $@-t && \
+ mv -f $@-t $@
+else
+alloca.h: $(top_builddir)/config.status
+ rm -f $@
+endif
+MOSTLYCLEANFILES += alloca.h alloca.h-t
+
+EXTRA_DIST += alloca.in.h
+
+## end gnulib module alloca-opt
+
+## begin gnulib module dirent
+
+BUILT_SOURCES += dirent.h
+
+# We need the following in order to create <dirent.h> when the system
+# doesn't have one that works with the given compiler.
+dirent.h: dirent.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+ -e 's|@''HAVE_DIRENT_H''@|$(HAVE_DIRENT_H)|g' \
+ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_DIRENT_H''@|$(NEXT_DIRENT_H)|g' \
+ -e 's/@''GNULIB_OPENDIR''@/$(GNULIB_OPENDIR)/g' \
+ -e 's/@''GNULIB_READDIR''@/$(GNULIB_READDIR)/g' \
+ -e 's/@''GNULIB_REWINDDIR''@/$(GNULIB_REWINDDIR)/g' \
+ -e 's/@''GNULIB_CLOSEDIR''@/$(GNULIB_CLOSEDIR)/g' \
+ -e 's/@''GNULIB_DIRFD''@/$(GNULIB_DIRFD)/g' \
+ -e 's/@''GNULIB_FDOPENDIR''@/$(GNULIB_FDOPENDIR)/g' \
+ -e 's/@''GNULIB_SCANDIR''@/$(GNULIB_SCANDIR)/g' \
+ -e 's/@''GNULIB_ALPHASORT''@/$(GNULIB_ALPHASORT)/g' \
+ -e 's/@''HAVE_OPENDIR''@/$(HAVE_OPENDIR)/g' \
+ -e 's/@''HAVE_READDIR''@/$(HAVE_READDIR)/g' \
+ -e 's/@''HAVE_REWINDDIR''@/$(HAVE_REWINDDIR)/g' \
+ -e 's/@''HAVE_CLOSEDIR''@/$(HAVE_CLOSEDIR)/g' \
+ -e 's|@''HAVE_DECL_DIRFD''@|$(HAVE_DECL_DIRFD)|g' \
+ -e 's|@''HAVE_DECL_FDOPENDIR''@|$(HAVE_DECL_FDOPENDIR)|g' \
+ -e 's|@''HAVE_FDOPENDIR''@|$(HAVE_FDOPENDIR)|g' \
+ -e 's|@''HAVE_SCANDIR''@|$(HAVE_SCANDIR)|g' \
+ -e 's|@''HAVE_ALPHASORT''@|$(HAVE_ALPHASORT)|g' \
+ -e 's|@''REPLACE_OPENDIR''@|$(REPLACE_OPENDIR)|g' \
+ -e 's|@''REPLACE_CLOSEDIR''@|$(REPLACE_CLOSEDIR)|g' \
+ -e 's|@''REPLACE_DIRFD''@|$(REPLACE_DIRFD)|g' \
+ -e 's|@''REPLACE_FDOPENDIR''@|$(REPLACE_FDOPENDIR)|g' \
+ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+ < $(srcdir)/dirent.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += dirent.h dirent.h-t
+
+EXTRA_DIST += dirent.in.h
+
+## end gnulib module dirent
+
+## begin gnulib module limits-h
+
+BUILT_SOURCES += $(LIMITS_H)
+
+# We need the following in order to create <limits.h> when the system
+# doesn't have one that is compatible with GNU.
+if GL_GENERATE_LIMITS_H
+limits.h: limits.in.h $(top_builddir)/config.status
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_LIMITS_H''@|$(NEXT_LIMITS_H)|g' \
+ < $(srcdir)/limits.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+else
+limits.h: $(top_builddir)/config.status
+ rm -f $@
+endif
+MOSTLYCLEANFILES += limits.h limits.h-t
+
+EXTRA_DIST += limits.in.h
+
+## end gnulib module limits-h
+
+## begin gnulib module malloc-gnu
+
+
+EXTRA_DIST += malloc.c
+
+EXTRA_libgnu_la_SOURCES += malloc.c
+
+## end gnulib module malloc-gnu
+
+## begin gnulib module malloc-posix
+
+
+EXTRA_DIST += malloc.c
+
+EXTRA_libgnu_la_SOURCES += malloc.c
+
+## end gnulib module malloc-posix
+
+## begin gnulib module malloca
+
+libgnu_la_SOURCES += malloca.c
+
+EXTRA_DIST += malloca.h
+
+## end gnulib module malloca
+
+## begin gnulib module realloc-gnu
+
+
+EXTRA_DIST += realloc.c
+
+EXTRA_libgnu_la_SOURCES += realloc.c
+
+## end gnulib module realloc-gnu
+
+## begin gnulib module realloc-posix
+
+
+EXTRA_DIST += realloc.c
+
+EXTRA_libgnu_la_SOURCES += realloc.c
+
+## end gnulib module realloc-posix
+
+## begin gnulib module setenv
+
+
+EXTRA_DIST += setenv.c
+
+EXTRA_libgnu_la_SOURCES += setenv.c
+
+## end gnulib module setenv
+
+## begin gnulib module snippet/_Noreturn
+
+# Because this Makefile snippet defines a variable used by other
+# gnulib Makefile snippets, it must be present in all makefiles that
+# need it. This is ensured by the applicability 'all' defined above.
+
+_NORETURN_H=$(srcdir)/_Noreturn.h
+
+EXTRA_DIST += _Noreturn.h
+
+## end gnulib module snippet/_Noreturn
+
+## begin gnulib module snippet/arg-nonnull
+
+# Because this Makefile snippet defines a variable used by other
+# gnulib Makefile snippets, it must be present in all makefiles that
+# need it. This is ensured by the applicability 'all' defined above.
+
+ARG_NONNULL_H=$(srcdir)/arg-nonnull.h
+
+EXTRA_DIST += arg-nonnull.h
+
+## end gnulib module snippet/arg-nonnull
+
+## begin gnulib module snippet/c++defs
+
+# Because this Makefile snippet defines a variable used by other
+# gnulib Makefile snippets, it must be present in all makefiles that
+# need it. This is ensured by the applicability 'all' defined above.
+
+CXXDEFS_H=$(srcdir)/c++defs.h
+
+EXTRA_DIST += c++defs.h
+
+## end gnulib module snippet/c++defs
+
+## begin gnulib module snippet/warn-on-use
+
+# Because this Makefile snippet defines a variable used by other
+# gnulib Makefile snippets, it must be present in all makefiles that
+# need it. This is ensured by the applicability 'all' defined above.
+
+WARN_ON_USE_H=$(srcdir)/warn-on-use.h
+
+EXTRA_DIST += warn-on-use.h
+
+## end gnulib module snippet/warn-on-use
+
+## begin gnulib module stddef
+
+BUILT_SOURCES += $(STDDEF_H)
+
+# We need the following in order to create <stddef.h> when the system
+# doesn't have one that works with the given compiler.
+if GL_GENERATE_STDDEF_H
+stddef.h: stddef.in.h $(top_builddir)/config.status
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \
+ -e 's|@''HAVE_MAX_ALIGN_T''@|$(HAVE_MAX_ALIGN_T)|g' \
+ -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \
+ -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \
+ < $(srcdir)/stddef.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+else
+stddef.h: $(top_builddir)/config.status
+ rm -f $@
+endif
+MOSTLYCLEANFILES += stddef.h stddef.h-t
+
+EXTRA_DIST += stddef.in.h
+
+## end gnulib module stddef
+
+## begin gnulib module stdint
+
+BUILT_SOURCES += $(STDINT_H)
+
+# We need the following in order to create <stdint.h> when the system
+# doesn't have one that works with the given compiler.
+if GL_GENERATE_STDINT_H
+stdint.h: stdint.in.h $(top_builddir)/config.status
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+ -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \
+ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \
+ -e 's/@''HAVE_C99_STDINT_H''@/$(HAVE_C99_STDINT_H)/g' \
+ -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \
+ -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \
+ -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \
+ -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \
+ -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \
+ -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \
+ -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \
+ -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \
+ -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \
+ -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \
+ -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \
+ -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \
+ -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \
+ -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \
+ -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \
+ -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \
+ -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \
+ -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \
+ -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \
+ -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \
+ -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \
+ -e 's/@''GNULIB_OVERRIDES_WINT_T''@/$(GNULIB_OVERRIDES_WINT_T)/g' \
+ < $(srcdir)/stdint.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+else
+stdint.h: $(top_builddir)/config.status
+ rm -f $@
+endif
+MOSTLYCLEANFILES += stdint.h stdint.h-t
+
+EXTRA_DIST += stdint.in.h
+
+## end gnulib module stdint
+
+## begin gnulib module stdlib
+
+BUILT_SOURCES += stdlib.h
+
+# We need the following in order to create <stdlib.h> when the system
+# doesn't have one that works with the given compiler.
+stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \
+ $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \
+ -e 's/@''GNULIB__EXIT''@/$(GNULIB__EXIT)/g' \
+ -e 's/@''GNULIB_ATOLL''@/$(GNULIB_ATOLL)/g' \
+ -e 's/@''GNULIB_CALLOC_POSIX''@/$(GNULIB_CALLOC_POSIX)/g' \
+ -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GNULIB_CANONICALIZE_FILE_NAME)/g' \
+ -e 's/@''GNULIB_GETLOADAVG''@/$(GNULIB_GETLOADAVG)/g' \
+ -e 's/@''GNULIB_GETSUBOPT''@/$(GNULIB_GETSUBOPT)/g' \
+ -e 's/@''GNULIB_GRANTPT''@/$(GNULIB_GRANTPT)/g' \
+ -e 's/@''GNULIB_MALLOC_POSIX''@/$(GNULIB_MALLOC_POSIX)/g' \
+ -e 's/@''GNULIB_MBTOWC''@/$(GNULIB_MBTOWC)/g' \
+ -e 's/@''GNULIB_MKDTEMP''@/$(GNULIB_MKDTEMP)/g' \
+ -e 's/@''GNULIB_MKOSTEMP''@/$(GNULIB_MKOSTEMP)/g' \
+ -e 's/@''GNULIB_MKOSTEMPS''@/$(GNULIB_MKOSTEMPS)/g' \
+ -e 's/@''GNULIB_MKSTEMP''@/$(GNULIB_MKSTEMP)/g' \
+ -e 's/@''GNULIB_MKSTEMPS''@/$(GNULIB_MKSTEMPS)/g' \
+ -e 's/@''GNULIB_POSIX_OPENPT''@/$(GNULIB_POSIX_OPENPT)/g' \
+ -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \
+ -e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \
+ -e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \
+ -e 's/@''GNULIB_QSORT_R''@/$(GNULIB_QSORT_R)/g' \
+ -e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \
+ -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \
+ -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \
+ -e 's/@''GNULIB_REALLOCARRAY''@/$(GNULIB_REALLOCARRAY)/g' \
+ -e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \
+ -e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \
+ -e 's/@''GNULIB_SECURE_GETENV''@/$(GNULIB_SECURE_GETENV)/g' \
+ -e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \
+ -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \
+ -e 's/@''GNULIB_STRTOLD''@/$(GNULIB_STRTOLD)/g' \
+ -e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \
+ -e 's/@''GNULIB_STRTOULL''@/$(GNULIB_STRTOULL)/g' \
+ -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GNULIB_SYSTEM_POSIX)/g' \
+ -e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \
+ -e 's/@''GNULIB_UNSETENV''@/$(GNULIB_UNSETENV)/g' \
+ -e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \
+ < $(srcdir)/stdlib.in.h | \
+ sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \
+ -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \
+ -e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|g' \
+ -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \
+ -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \
+ -e 's|@''HAVE_GRANTPT''@|$(HAVE_GRANTPT)|g' \
+ -e 's|@''HAVE_INITSTATE''@|$(HAVE_INITSTATE)|g' \
+ -e 's|@''HAVE_DECL_INITSTATE''@|$(HAVE_DECL_INITSTATE)|g' \
+ -e 's|@''HAVE_MBTOWC''@|$(HAVE_MBTOWC)|g' \
+ -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \
+ -e 's|@''HAVE_MKOSTEMP''@|$(HAVE_MKOSTEMP)|g' \
+ -e 's|@''HAVE_MKOSTEMPS''@|$(HAVE_MKOSTEMPS)|g' \
+ -e 's|@''HAVE_MKSTEMP''@|$(HAVE_MKSTEMP)|g' \
+ -e 's|@''HAVE_MKSTEMPS''@|$(HAVE_MKSTEMPS)|g' \
+ -e 's|@''HAVE_POSIX_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \
+ -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \
+ -e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_R)|g' \
+ -e 's|@''HAVE_QSORT_R''@|$(HAVE_QSORT_R)|g' \
+ -e 's|@''HAVE_RANDOM''@|$(HAVE_RANDOM)|g' \
+ -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \
+ -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \
+ -e 's|@''HAVE_REALLOCARRAY''@|$(HAVE_REALLOCARRAY)|g' \
+ -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \
+ -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \
+ -e 's|@''HAVE_SECURE_GETENV''@|$(HAVE_SECURE_GETENV)|g' \
+ -e 's|@''HAVE_DECL_SETENV''@|$(HAVE_DECL_SETENV)|g' \
+ -e 's|@''HAVE_SETSTATE''@|$(HAVE_SETSTATE)|g' \
+ -e 's|@''HAVE_DECL_SETSTATE''@|$(HAVE_DECL_SETSTATE)|g' \
+ -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \
+ -e 's|@''HAVE_STRTOLD''@|$(HAVE_STRTOLD)|g' \
+ -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \
+ -e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \
+ -e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \
+ -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \
+ -e 's|@''HAVE_UNLOCKPT''@|$(HAVE_UNLOCKPT)|g' \
+ -e 's|@''HAVE_DECL_UNSETENV''@|$(HAVE_DECL_UNSETENV)|g' \
+ -e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \
+ -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \
+ -e 's|@''REPLACE_INITSTATE''@|$(REPLACE_INITSTATE)|g' \
+ -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \
+ -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \
+ -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
+ -e 's|@''REPLACE_PTSNAME''@|$(REPLACE_PTSNAME)|g' \
+ -e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \
+ -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
+ -e 's|@''REPLACE_QSORT_R''@|$(REPLACE_QSORT_R)|g' \
+ -e 's|@''REPLACE_RANDOM''@|$(REPLACE_RANDOM)|g' \
+ -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \
+ -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \
+ -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \
+ -e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \
+ -e 's|@''REPLACE_SETSTATE''@|$(REPLACE_SETSTATE)|g' \
+ -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \
+ -e 's|@''REPLACE_STRTOLD''@|$(REPLACE_STRTOLD)|g' \
+ -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \
+ -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \
+ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+ -e '/definition of _Noreturn/r $(_NORETURN_H)' \
+ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += stdlib.h stdlib.h-t
+
+EXTRA_DIST += stdlib.in.h
+
+## end gnulib module stdlib
+
+## begin gnulib module string
+
+BUILT_SOURCES += string.h
+
+# We need the following in order to create <string.h> when the system
+# doesn't have one that works with the given compiler.
+string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|g' \
+ -e 's/@''GNULIB_EXPLICIT_BZERO''@/$(GNULIB_EXPLICIT_BZERO)/g' \
+ -e 's/@''GNULIB_FFSL''@/$(GNULIB_FFSL)/g' \
+ -e 's/@''GNULIB_FFSLL''@/$(GNULIB_FFSLL)/g' \
+ -e 's/@''GNULIB_MBSLEN''@/$(GNULIB_MBSLEN)/g' \
+ -e 's/@''GNULIB_MBSNLEN''@/$(GNULIB_MBSNLEN)/g' \
+ -e 's/@''GNULIB_MBSCHR''@/$(GNULIB_MBSCHR)/g' \
+ -e 's/@''GNULIB_MBSRCHR''@/$(GNULIB_MBSRCHR)/g' \
+ -e 's/@''GNULIB_MBSSTR''@/$(GNULIB_MBSSTR)/g' \
+ -e 's/@''GNULIB_MBSCASECMP''@/$(GNULIB_MBSCASECMP)/g' \
+ -e 's/@''GNULIB_MBSNCASECMP''@/$(GNULIB_MBSNCASECMP)/g' \
+ -e 's/@''GNULIB_MBSPCASECMP''@/$(GNULIB_MBSPCASECMP)/g' \
+ -e 's/@''GNULIB_MBSCASESTR''@/$(GNULIB_MBSCASESTR)/g' \
+ -e 's/@''GNULIB_MBSCSPN''@/$(GNULIB_MBSCSPN)/g' \
+ -e 's/@''GNULIB_MBSPBRK''@/$(GNULIB_MBSPBRK)/g' \
+ -e 's/@''GNULIB_MBSSPN''@/$(GNULIB_MBSSPN)/g' \
+ -e 's/@''GNULIB_MBSSEP''@/$(GNULIB_MBSSEP)/g' \
+ -e 's/@''GNULIB_MBSTOK_R''@/$(GNULIB_MBSTOK_R)/g' \
+ -e 's/@''GNULIB_MEMCHR''@/$(GNULIB_MEMCHR)/g' \
+ -e 's/@''GNULIB_MEMMEM''@/$(GNULIB_MEMMEM)/g' \
+ -e 's/@''GNULIB_MEMPCPY''@/$(GNULIB_MEMPCPY)/g' \
+ -e 's/@''GNULIB_MEMRCHR''@/$(GNULIB_MEMRCHR)/g' \
+ -e 's/@''GNULIB_RAWMEMCHR''@/$(GNULIB_RAWMEMCHR)/g' \
+ -e 's/@''GNULIB_STPCPY''@/$(GNULIB_STPCPY)/g' \
+ -e 's/@''GNULIB_STPNCPY''@/$(GNULIB_STPNCPY)/g' \
+ -e 's/@''GNULIB_STRCHRNUL''@/$(GNULIB_STRCHRNUL)/g' \
+ -e 's/@''GNULIB_STRDUP''@/$(GNULIB_STRDUP)/g' \
+ -e 's/@''GNULIB_STRNCAT''@/$(GNULIB_STRNCAT)/g' \
+ -e 's/@''GNULIB_STRNDUP''@/$(GNULIB_STRNDUP)/g' \
+ -e 's/@''GNULIB_STRNLEN''@/$(GNULIB_STRNLEN)/g' \
+ -e 's/@''GNULIB_STRPBRK''@/$(GNULIB_STRPBRK)/g' \
+ -e 's/@''GNULIB_STRSEP''@/$(GNULIB_STRSEP)/g' \
+ -e 's/@''GNULIB_STRSTR''@/$(GNULIB_STRSTR)/g' \
+ -e 's/@''GNULIB_STRCASESTR''@/$(GNULIB_STRCASESTR)/g' \
+ -e 's/@''GNULIB_STRTOK_R''@/$(GNULIB_STRTOK_R)/g' \
+ -e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \
+ -e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \
+ -e 's/@''GNULIB_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \
+ -e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \
+ < $(srcdir)/string.in.h | \
+ sed -e 's|@''HAVE_EXPLICIT_BZERO''@|$(HAVE_EXPLICIT_BZERO)|g' \
+ -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \
+ -e 's|@''HAVE_FFSLL''@|$(HAVE_FFSLL)|g' \
+ -e 's|@''HAVE_MBSLEN''@|$(HAVE_MBSLEN)|g' \
+ -e 's|@''HAVE_MEMCHR''@|$(HAVE_MEMCHR)|g' \
+ -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \
+ -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \
+ -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \
+ -e 's|@''HAVE_RAWMEMCHR''@|$(HAVE_RAWMEMCHR)|g' \
+ -e 's|@''HAVE_STPCPY''@|$(HAVE_STPCPY)|g' \
+ -e 's|@''HAVE_STPNCPY''@|$(HAVE_STPNCPY)|g' \
+ -e 's|@''HAVE_STRCHRNUL''@|$(HAVE_STRCHRNUL)|g' \
+ -e 's|@''HAVE_DECL_STRDUP''@|$(HAVE_DECL_STRDUP)|g' \
+ -e 's|@''HAVE_DECL_STRNDUP''@|$(HAVE_DECL_STRNDUP)|g' \
+ -e 's|@''HAVE_DECL_STRNLEN''@|$(HAVE_DECL_STRNLEN)|g' \
+ -e 's|@''HAVE_STRPBRK''@|$(HAVE_STRPBRK)|g' \
+ -e 's|@''HAVE_STRSEP''@|$(HAVE_STRSEP)|g' \
+ -e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \
+ -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \
+ -e 's|@''HAVE_DECL_STRERROR_R''@|$(HAVE_DECL_STRERROR_R)|g' \
+ -e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \
+ -e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \
+ -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \
+ -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \
+ -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \
+ -e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \
+ -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \
+ -e 's|@''REPLACE_STRNCAT''@|$(REPLACE_STRNCAT)|g' \
+ -e 's|@''REPLACE_STRNDUP''@|$(REPLACE_STRNDUP)|g' \
+ -e 's|@''REPLACE_STRNLEN''@|$(REPLACE_STRNLEN)|g' \
+ -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \
+ -e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \
+ -e 's|@''REPLACE_STRTOK_R''@|$(REPLACE_STRTOK_R)|g' \
+ -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \
+ -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \
+ -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \
+ -e 's|@''UNDEFINE_STRTOK_R''@|$(UNDEFINE_STRTOK_R)|g' \
+ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \
+ < $(srcdir)/string.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += string.h string.h-t
+
+EXTRA_DIST += string.in.h
+
+## end gnulib module string
+
+## begin gnulib module strndup
+
+
+EXTRA_DIST += strndup.c
+
+EXTRA_libgnu_la_SOURCES += strndup.c
+
+## end gnulib module strndup
+
+## begin gnulib module strnlen
+
+
+EXTRA_DIST += strnlen.c
+
+EXTRA_libgnu_la_SOURCES += strnlen.c
+
+## end gnulib module strnlen
+
+## begin gnulib module sys_types
+
+BUILT_SOURCES += sys/types.h
+
+# We need the following in order to create <sys/types.h> when the system
+# doesn't have one that works with the given compiler.
+sys/types.h: sys_types.in.h $(top_builddir)/config.status
+ $(AM_V_at)$(MKDIR_P) sys
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_SYS_TYPES_H''@|$(NEXT_SYS_TYPES_H)|g' \
+ -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \
+ -e 's|@''WINDOWS_STAT_INODES''@|$(WINDOWS_STAT_INODES)|g' \
+ < $(srcdir)/sys_types.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += sys/types.h sys/types.h-t
+
+EXTRA_DIST += sys_types.in.h
+
+## end gnulib module sys_types
+
+## begin gnulib module unistd
+
+BUILT_SOURCES += unistd.h
+libgnu_la_SOURCES += unistd.c
+
+# We need the following in order to create an empty placeholder for
+# <unistd.h> when the system doesn't have one.
+unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+ -e 's|@''HAVE_UNISTD_H''@|$(HAVE_UNISTD_H)|g' \
+ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \
+ -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \
+ -e 's/@''GNULIB_CHDIR''@/$(GNULIB_CHDIR)/g' \
+ -e 's/@''GNULIB_CHOWN''@/$(GNULIB_CHOWN)/g' \
+ -e 's/@''GNULIB_CLOSE''@/$(GNULIB_CLOSE)/g' \
+ -e 's/@''GNULIB_COPY_FILE_RANGE''@/$(GNULIB_COPY_FILE_RANGE)/g' \
+ -e 's/@''GNULIB_DUP''@/$(GNULIB_DUP)/g' \
+ -e 's/@''GNULIB_DUP2''@/$(GNULIB_DUP2)/g' \
+ -e 's/@''GNULIB_DUP3''@/$(GNULIB_DUP3)/g' \
+ -e 's/@''GNULIB_ENVIRON''@/$(GNULIB_ENVIRON)/g' \
+ -e 's/@''GNULIB_EUIDACCESS''@/$(GNULIB_EUIDACCESS)/g' \
+ -e 's/@''GNULIB_FACCESSAT''@/$(GNULIB_FACCESSAT)/g' \
+ -e 's/@''GNULIB_FCHDIR''@/$(GNULIB_FCHDIR)/g' \
+ -e 's/@''GNULIB_FCHOWNAT''@/$(GNULIB_FCHOWNAT)/g' \
+ -e 's/@''GNULIB_FDATASYNC''@/$(GNULIB_FDATASYNC)/g' \
+ -e 's/@''GNULIB_FSYNC''@/$(GNULIB_FSYNC)/g' \
+ -e 's/@''GNULIB_FTRUNCATE''@/$(GNULIB_FTRUNCATE)/g' \
+ -e 's/@''GNULIB_GETCWD''@/$(GNULIB_GETCWD)/g' \
+ -e 's/@''GNULIB_GETDOMAINNAME''@/$(GNULIB_GETDOMAINNAME)/g' \
+ -e 's/@''GNULIB_GETDTABLESIZE''@/$(GNULIB_GETDTABLESIZE)/g' \
+ -e 's/@''GNULIB_GETGROUPS''@/$(GNULIB_GETGROUPS)/g' \
+ -e 's/@''GNULIB_GETHOSTNAME''@/$(GNULIB_GETHOSTNAME)/g' \
+ -e 's/@''GNULIB_GETLOGIN''@/$(GNULIB_GETLOGIN)/g' \
+ -e 's/@''GNULIB_GETLOGIN_R''@/$(GNULIB_GETLOGIN_R)/g' \
+ -e 's/@''GNULIB_GETPAGESIZE''@/$(GNULIB_GETPAGESIZE)/g' \
+ -e 's/@''GNULIB_GETPASS''@/$(GNULIB_GETPASS)/g' \
+ -e 's/@''GNULIB_GETUSERSHELL''@/$(GNULIB_GETUSERSHELL)/g' \
+ -e 's/@''GNULIB_GROUP_MEMBER''@/$(GNULIB_GROUP_MEMBER)/g' \
+ -e 's/@''GNULIB_ISATTY''@/$(GNULIB_ISATTY)/g' \
+ -e 's/@''GNULIB_LCHOWN''@/$(GNULIB_LCHOWN)/g' \
+ -e 's/@''GNULIB_LINK''@/$(GNULIB_LINK)/g' \
+ -e 's/@''GNULIB_LINKAT''@/$(GNULIB_LINKAT)/g' \
+ -e 's/@''GNULIB_LSEEK''@/$(GNULIB_LSEEK)/g' \
+ -e 's/@''GNULIB_PIPE''@/$(GNULIB_PIPE)/g' \
+ -e 's/@''GNULIB_PIPE2''@/$(GNULIB_PIPE2)/g' \
+ -e 's/@''GNULIB_PREAD''@/$(GNULIB_PREAD)/g' \
+ -e 's/@''GNULIB_PWRITE''@/$(GNULIB_PWRITE)/g' \
+ -e 's/@''GNULIB_READ''@/$(GNULIB_READ)/g' \
+ -e 's/@''GNULIB_READLINK''@/$(GNULIB_READLINK)/g' \
+ -e 's/@''GNULIB_READLINKAT''@/$(GNULIB_READLINKAT)/g' \
+ -e 's/@''GNULIB_RMDIR''@/$(GNULIB_RMDIR)/g' \
+ -e 's/@''GNULIB_SETHOSTNAME''@/$(GNULIB_SETHOSTNAME)/g' \
+ -e 's/@''GNULIB_SLEEP''@/$(GNULIB_SLEEP)/g' \
+ -e 's/@''GNULIB_SYMLINK''@/$(GNULIB_SYMLINK)/g' \
+ -e 's/@''GNULIB_SYMLINKAT''@/$(GNULIB_SYMLINKAT)/g' \
+ -e 's/@''GNULIB_TRUNCATE''@/$(GNULIB_TRUNCATE)/g' \
+ -e 's/@''GNULIB_TTYNAME_R''@/$(GNULIB_TTYNAME_R)/g' \
+ -e 's/@''GNULIB_UNISTD_H_GETOPT''@/0$(GNULIB_GL_UNISTD_H_GETOPT)/g' \
+ -e 's/@''GNULIB_UNISTD_H_NONBLOCKING''@/$(GNULIB_UNISTD_H_NONBLOCKING)/g' \
+ -e 's/@''GNULIB_UNISTD_H_SIGPIPE''@/$(GNULIB_UNISTD_H_SIGPIPE)/g' \
+ -e 's/@''GNULIB_UNLINK''@/$(GNULIB_UNLINK)/g' \
+ -e 's/@''GNULIB_UNLINKAT''@/$(GNULIB_UNLINKAT)/g' \
+ -e 's/@''GNULIB_USLEEP''@/$(GNULIB_USLEEP)/g' \
+ -e 's/@''GNULIB_WRITE''@/$(GNULIB_WRITE)/g' \
+ < $(srcdir)/unistd.in.h | \
+ sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \
+ -e 's|@''HAVE_COPY_FILE_RANGE''@|$(HAVE_COPY_FILE_RANGE)|g' \
+ -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \
+ -e 's|@''HAVE_DUP3''@|$(HAVE_DUP3)|g' \
+ -e 's|@''HAVE_EUIDACCESS''@|$(HAVE_EUIDACCESS)|g' \
+ -e 's|@''HAVE_FACCESSAT''@|$(HAVE_FACCESSAT)|g' \
+ -e 's|@''HAVE_FCHDIR''@|$(HAVE_FCHDIR)|g' \
+ -e 's|@''HAVE_FCHOWNAT''@|$(HAVE_FCHOWNAT)|g' \
+ -e 's|@''HAVE_FDATASYNC''@|$(HAVE_FDATASYNC)|g' \
+ -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \
+ -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \
+ -e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \
+ -e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \
+ -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \
+ -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \
+ -e 's|@''HAVE_GETPASS''@|$(HAVE_GETPASS)|g' \
+ -e 's|@''HAVE_GROUP_MEMBER''@|$(HAVE_GROUP_MEMBER)|g' \
+ -e 's|@''HAVE_LCHOWN''@|$(HAVE_LCHOWN)|g' \
+ -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \
+ -e 's|@''HAVE_LINKAT''@|$(HAVE_LINKAT)|g' \
+ -e 's|@''HAVE_PIPE''@|$(HAVE_PIPE)|g' \
+ -e 's|@''HAVE_PIPE2''@|$(HAVE_PIPE2)|g' \
+ -e 's|@''HAVE_PREAD''@|$(HAVE_PREAD)|g' \
+ -e 's|@''HAVE_PWRITE''@|$(HAVE_PWRITE)|g' \
+ -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \
+ -e 's|@''HAVE_READLINKAT''@|$(HAVE_READLINKAT)|g' \
+ -e 's|@''HAVE_SETHOSTNAME''@|$(HAVE_SETHOSTNAME)|g' \
+ -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \
+ -e 's|@''HAVE_SYMLINK''@|$(HAVE_SYMLINK)|g' \
+ -e 's|@''HAVE_SYMLINKAT''@|$(HAVE_SYMLINKAT)|g' \
+ -e 's|@''HAVE_UNLINKAT''@|$(HAVE_UNLINKAT)|g' \
+ -e 's|@''HAVE_USLEEP''@|$(HAVE_USLEEP)|g' \
+ -e 's|@''HAVE_DECL_ENVIRON''@|$(HAVE_DECL_ENVIRON)|g' \
+ -e 's|@''HAVE_DECL_FCHDIR''@|$(HAVE_DECL_FCHDIR)|g' \
+ -e 's|@''HAVE_DECL_FDATASYNC''@|$(HAVE_DECL_FDATASYNC)|g' \
+ -e 's|@''HAVE_DECL_GETDOMAINNAME''@|$(HAVE_DECL_GETDOMAINNAME)|g' \
+ -e 's|@''HAVE_DECL_GETLOGIN''@|$(HAVE_DECL_GETLOGIN)|g' \
+ -e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \
+ -e 's|@''HAVE_DECL_GETPAGESIZE''@|$(HAVE_DECL_GETPAGESIZE)|g' \
+ -e 's|@''HAVE_DECL_GETUSERSHELL''@|$(HAVE_DECL_GETUSERSHELL)|g' \
+ -e 's|@''HAVE_DECL_SETHOSTNAME''@|$(HAVE_DECL_SETHOSTNAME)|g' \
+ -e 's|@''HAVE_DECL_TRUNCATE''@|$(HAVE_DECL_TRUNCATE)|g' \
+ -e 's|@''HAVE_DECL_TTYNAME_R''@|$(HAVE_DECL_TTYNAME_R)|g' \
+ -e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \
+ -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \
+ | \
+ sed -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \
+ -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \
+ -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \
+ -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \
+ -e 's|@''REPLACE_FACCESSAT''@|$(REPLACE_FACCESSAT)|g' \
+ -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \
+ -e 's|@''REPLACE_FTRUNCATE''@|$(REPLACE_FTRUNCATE)|g' \
+ -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \
+ -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \
+ -e 's|@''REPLACE_GETDTABLESIZE''@|$(REPLACE_GETDTABLESIZE)|g' \
+ -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \
+ -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \
+ -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \
+ -e 's|@''REPLACE_GETPASS''@|$(REPLACE_GETPASS)|g' \
+ -e 's|@''REPLACE_ISATTY''@|$(REPLACE_ISATTY)|g' \
+ -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \
+ -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \
+ -e 's|@''REPLACE_LINKAT''@|$(REPLACE_LINKAT)|g' \
+ -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \
+ -e 's|@''REPLACE_PREAD''@|$(REPLACE_PREAD)|g' \
+ -e 's|@''REPLACE_PWRITE''@|$(REPLACE_PWRITE)|g' \
+ -e 's|@''REPLACE_READ''@|$(REPLACE_READ)|g' \
+ -e 's|@''REPLACE_READLINK''@|$(REPLACE_READLINK)|g' \
+ -e 's|@''REPLACE_READLINKAT''@|$(REPLACE_READLINKAT)|g' \
+ -e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \
+ -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \
+ -e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|g' \
+ -e 's|@''REPLACE_SYMLINKAT''@|$(REPLACE_SYMLINKAT)|g' \
+ -e 's|@''REPLACE_TRUNCATE''@|$(REPLACE_TRUNCATE)|g' \
+ -e 's|@''REPLACE_TTYNAME_R''@|$(REPLACE_TTYNAME_R)|g' \
+ -e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \
+ -e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \
+ -e 's|@''REPLACE_USLEEP''@|$(REPLACE_USLEEP)|g' \
+ -e 's|@''REPLACE_WRITE''@|$(REPLACE_WRITE)|g' \
+ -e 's|@''UNISTD_H_HAVE_WINSOCK2_H''@|$(UNISTD_H_HAVE_WINSOCK2_H)|g' \
+ -e 's|@''UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \
+ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += unistd.h unistd.h-t
+
+EXTRA_DIST += unistd.in.h
+
+## end gnulib module unistd
+
+## begin gnulib module verify
+
+
+EXTRA_DIST += verify.h
+
+## end gnulib module verify
+
+## begin gnulib module xalloc-oversized
+
+
+EXTRA_DIST += xalloc-oversized.h
+
+## end gnulib module xalloc-oversized
+
+
+mostlyclean-local: mostlyclean-generic
+ @for dir in '' $(MOSTLYCLEANDIRS); do \
+ if test -n "$$dir" && test -d $$dir; then \
+ echo "rmdir $$dir"; rmdir $$dir; \
+ fi; \
+ done; \
+ :
diff --git a/gnulib/_Noreturn.h b/gnulib/_Noreturn.h
new file mode 100644
index 0000000..db9b455
--- /dev/null
+++ b/gnulib/_Noreturn.h
@@ -0,0 +1,33 @@
+/* A C macro for declaring that a function does not return.
+ Copyright (C) 2011-2019 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _Noreturn
+# if (defined __cplusplus \
+ && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \
+ || (defined _MSC_VER && 1900 <= _MSC_VER)))
+# define _Noreturn [[noreturn]]
+# elif ((!defined __cplusplus || defined __clang__) \
+ && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
+ || 4 < __GNUC__ + (7 <= __GNUC_MINOR__)))
+ /* _Noreturn works as-is. */
+# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C
+# define _Noreturn __attribute__ ((__noreturn__))
+# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn
+# endif
+#endif
diff --git a/gnulib/alloca.in.h b/gnulib/alloca.in.h
new file mode 100644
index 0000000..a581d58
--- /dev/null
+++ b/gnulib/alloca.in.h
@@ -0,0 +1,71 @@
+/* Memory allocation on the stack.
+
+ Copyright (C) 1995, 1999, 2001-2004, 2006-2019 Free Software Foundation,
+ Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with this program; if not, see
+ <https://www.gnu.org/licenses/>.
+ */
+
+/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
+ means there is a real alloca function. */
+#ifndef _GL_ALLOCA_H
+#define _GL_ALLOCA_H
+
+/* alloca (N) returns a pointer to N bytes of memory
+ allocated on the stack, which will last until the function returns.
+ Use of alloca should be avoided:
+ - inside arguments of function calls - undefined behaviour,
+ - in inline functions - the allocation may actually last until the
+ calling function returns,
+ - for huge N (say, N >= 65536) - you never know how large (or small)
+ the stack is, and when the stack cannot fulfill the memory allocation
+ request, the program just crashes.
+ */
+
+#ifndef alloca
+# ifdef __GNUC__
+ /* Some version of mingw have an <alloca.h> that causes trouble when
+ included after 'alloca' gets defined as a macro. As a workaround, include
+ this <alloca.h> first and define 'alloca' as a macro afterwards. */
+# if (defined _WIN32 && ! defined __CYGWIN__) && @HAVE_ALLOCA_H@
+# include_next <alloca.h>
+# endif
+# define alloca __builtin_alloca
+# elif defined _AIX
+# define alloca __alloca
+# elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# elif defined __DECC && defined __VMS
+# define alloca __ALLOCA
+# elif defined __TANDEM && defined _TNS_E_TARGET
+# ifdef __cplusplus
+extern "C"
+# endif
+void *_alloca (unsigned short);
+# pragma intrinsic (_alloca)
+# define alloca _alloca
+# elif defined __MVS__
+# include <stdlib.h>
+# else
+# include <stddef.h>
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+# endif
+#endif
+
+#endif /* _GL_ALLOCA_H */
diff --git a/gnulib/arg-nonnull.h b/gnulib/arg-nonnull.h
new file mode 100644
index 0000000..ad8c26c
--- /dev/null
+++ b/gnulib/arg-nonnull.h
@@ -0,0 +1,26 @@
+/* A C macro for declaring that specific arguments must not be NULL.
+ Copyright (C) 2009-2019 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools
+ that the values passed as arguments n, ..., m must be non-NULL pointers.
+ n = 1 stands for the first argument, n = 2 for the second argument etc. */
+#ifndef _GL_ARG_NONNULL
+# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3
+# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))
+# else
+# define _GL_ARG_NONNULL(params)
+# endif
+#endif
diff --git a/gnulib/c++defs.h b/gnulib/c++defs.h
new file mode 100644
index 0000000..87d0716
--- /dev/null
+++ b/gnulib/c++defs.h
@@ -0,0 +1,316 @@
+/* C++ compatible function declaration macros.
+ Copyright (C) 2010-2019 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _GL_CXXDEFS_H
+#define _GL_CXXDEFS_H
+
+/* Begin/end the GNULIB_NAMESPACE namespace. */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {
+# define _GL_END_NAMESPACE }
+#else
+# define _GL_BEGIN_NAMESPACE
+# define _GL_END_NAMESPACE
+#endif
+
+/* The three most frequent use cases of these macros are:
+
+ * For providing a substitute for a function that is missing on some
+ platforms, but is declared and works fine on the platforms on which
+ it exists:
+
+ #if @GNULIB_FOO@
+ # if !@HAVE_FOO@
+ _GL_FUNCDECL_SYS (foo, ...);
+ # endif
+ _GL_CXXALIAS_SYS (foo, ...);
+ _GL_CXXALIASWARN (foo);
+ #elif defined GNULIB_POSIXCHECK
+ ...
+ #endif
+
+ * For providing a replacement for a function that exists on all platforms,
+ but is broken/insufficient and needs to be replaced on some platforms:
+
+ #if @GNULIB_FOO@
+ # if @REPLACE_FOO@
+ # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+ # undef foo
+ # define foo rpl_foo
+ # endif
+ _GL_FUNCDECL_RPL (foo, ...);
+ _GL_CXXALIAS_RPL (foo, ...);
+ # else
+ _GL_CXXALIAS_SYS (foo, ...);
+ # endif
+ _GL_CXXALIASWARN (foo);
+ #elif defined GNULIB_POSIXCHECK
+ ...
+ #endif
+
+ * For providing a replacement for a function that exists on some platforms
+ but is broken/insufficient and needs to be replaced on some of them and
+ is additionally either missing or undeclared on some other platforms:
+
+ #if @GNULIB_FOO@
+ # if @REPLACE_FOO@
+ # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+ # undef foo
+ # define foo rpl_foo
+ # endif
+ _GL_FUNCDECL_RPL (foo, ...);
+ _GL_CXXALIAS_RPL (foo, ...);
+ # else
+ # if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@
+ _GL_FUNCDECL_SYS (foo, ...);
+ # endif
+ _GL_CXXALIAS_SYS (foo, ...);
+ # endif
+ _GL_CXXALIASWARN (foo);
+ #elif defined GNULIB_POSIXCHECK
+ ...
+ #endif
+*/
+
+/* _GL_EXTERN_C declaration;
+ performs the declaration with C linkage. */
+#if defined __cplusplus
+# define _GL_EXTERN_C extern "C"
+#else
+# define _GL_EXTERN_C extern
+#endif
+
+/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);
+ declares a replacement function, named rpl_func, with the given prototype,
+ consisting of return type, parameters, and attributes.
+ Example:
+ _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
+ _GL_ARG_NONNULL ((1)));
+ */
+#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
+ _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
+#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
+ _GL_EXTERN_C rettype rpl_func parameters_and_attributes
+
+/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
+ declares the system function, named func, with the given prototype,
+ consisting of return type, parameters, and attributes.
+ Example:
+ _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
+ _GL_ARG_NONNULL ((1)));
+ */
+#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
+ _GL_EXTERN_C rettype func parameters_and_attributes
+
+/* _GL_CXXALIAS_RPL (func, rettype, parameters);
+ declares a C++ alias called GNULIB_NAMESPACE::func
+ that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
+ Example:
+ _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
+
+ Wrapping rpl_func in an object with an inline conversion operator
+ avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is
+ actually used in the program. */
+#define _GL_CXXALIAS_RPL(func,rettype,parameters) \
+ _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
+ namespace GNULIB_NAMESPACE \
+ { \
+ static const struct _gl_ ## func ## _wrapper \
+ { \
+ typedef rettype (*type) parameters; \
+ \
+ inline operator type () const \
+ { \
+ return ::rpl_func; \
+ } \
+ } func = {}; \
+ } \
+ _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
+ _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
+ is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
+ except that the C function rpl_func may have a slightly different
+ declaration. A cast is used to silence the "invalid conversion" error
+ that would otherwise occur. */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
+ namespace GNULIB_NAMESPACE \
+ { \
+ static const struct _gl_ ## func ## _wrapper \
+ { \
+ typedef rettype (*type) parameters; \
+ \
+ inline operator type () const \
+ { \
+ return reinterpret_cast<type>(::rpl_func); \
+ } \
+ } func = {}; \
+ } \
+ _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
+ _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_SYS (func, rettype, parameters);
+ declares a C++ alias called GNULIB_NAMESPACE::func
+ that redirects to the system provided function func, if GNULIB_NAMESPACE
+ is defined.
+ Example:
+ _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
+
+ Wrapping func in an object with an inline conversion operator
+ avoids a reference to func unless GNULIB_NAMESPACE::func is
+ actually used in the program. */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
+ namespace GNULIB_NAMESPACE \
+ { \
+ static const struct _gl_ ## func ## _wrapper \
+ { \
+ typedef rettype (*type) parameters; \
+ \
+ inline operator type () const \
+ { \
+ return ::func; \
+ } \
+ } func = {}; \
+ } \
+ _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
+ _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
+ is like _GL_CXXALIAS_SYS (func, rettype, parameters);
+ except that the C function func may have a slightly different declaration.
+ A cast is used to silence the "invalid conversion" error that would
+ otherwise occur. */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
+ namespace GNULIB_NAMESPACE \
+ { \
+ static const struct _gl_ ## func ## _wrapper \
+ { \
+ typedef rettype (*type) parameters; \
+ \
+ inline operator type () const \
+ { \
+ return reinterpret_cast<type>(::func); \
+ } \
+ } func = {}; \
+ } \
+ _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
+ _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
+ is like _GL_CXXALIAS_SYS (func, rettype, parameters);
+ except that the C function is picked among a set of overloaded functions,
+ namely the one with rettype2 and parameters2. Two consecutive casts
+ are used to silence the "cannot find a match" and "invalid conversion"
+ errors that would otherwise occur. */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+ /* The outer cast must be a reinterpret_cast.
+ The inner cast: When the function is defined as a set of overloaded
+ functions, it works as a static_cast<>, choosing the designated variant.
+ When the function is defined as a single variant, it works as a
+ reinterpret_cast<>. The parenthesized cast syntax works both ways. */
+# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
+ namespace GNULIB_NAMESPACE \
+ { \
+ static const struct _gl_ ## func ## _wrapper \
+ { \
+ typedef rettype (*type) parameters; \
+ \
+ inline operator type () const \
+ { \
+ return reinterpret_cast<type>((rettype2 (*) parameters2)(::func)); \
+ } \
+ } func = {}; \
+ } \
+ _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
+ _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIASWARN (func);
+ causes a warning to be emitted when ::func is used but not when
+ GNULIB_NAMESPACE::func is used. func must be defined without overloaded
+ variants. */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIASWARN(func) \
+ _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
+# define _GL_CXXALIASWARN_1(func,namespace) \
+ _GL_CXXALIASWARN_2 (func, namespace)
+/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
+ we enable the warning only when not optimizing. */
+# if !__OPTIMIZE__
+# define _GL_CXXALIASWARN_2(func,namespace) \
+ _GL_WARN_ON_USE (func, \
+ "The symbol ::" #func " refers to the system function. " \
+ "Use " #namespace "::" #func " instead.")
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+# define _GL_CXXALIASWARN_2(func,namespace) \
+ extern __typeof__ (func) func
+# else
+# define _GL_CXXALIASWARN_2(func,namespace) \
+ _GL_EXTERN_C int _gl_cxxalias_dummy
+# endif
+#else
+# define _GL_CXXALIASWARN(func) \
+ _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
+ causes a warning to be emitted when the given overloaded variant of ::func
+ is used but not when GNULIB_NAMESPACE::func is used. */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
+ _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
+ GNULIB_NAMESPACE)
+# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
+ _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
+/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
+ we enable the warning only when not optimizing. */
+# if !__OPTIMIZE__
+# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
+ _GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \
+ "The symbol ::" #func " refers to the system function. " \
+ "Use " #namespace "::" #func " instead.")
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
+ extern __typeof__ (func) func
+# else
+# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
+ _GL_EXTERN_C int _gl_cxxalias_dummy
+# endif
+#else
+# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
+ _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+#endif /* _GL_CXXDEFS_H */
diff --git a/gnulib/dirent.in.h b/gnulib/dirent.in.h
new file mode 100644
index 0000000..a3c8eb3
--- /dev/null
+++ b/gnulib/dirent.in.h
@@ -0,0 +1,267 @@
+/* A GNU-like <dirent.h>.
+ Copyright (C) 2006-2019 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _@GUARD_PREFIX@_DIRENT_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+/* The include_next requires a split double-inclusion guard. */
+#if @HAVE_DIRENT_H@
+# @INCLUDE_NEXT@ @NEXT_DIRENT_H@
+#endif
+
+#ifndef _@GUARD_PREFIX@_DIRENT_H
+#define _@GUARD_PREFIX@_DIRENT_H
+
+/* Get ino_t. Needed on some systems, including glibc 2.8. */
+#include <sys/types.h>
+
+#if !@HAVE_DIRENT_H@
+/* Define types DIR and 'struct dirent'. */
+# if !GNULIB_defined_struct_dirent
+struct dirent
+{
+ char d_type;
+ char d_name[1];
+};
+/* Possible values for 'd_type'. */
+# define DT_UNKNOWN 0
+# define DT_FIFO 1 /* FIFO */
+# define DT_CHR 2 /* character device */
+# define DT_DIR 4 /* directory */
+# define DT_BLK 6 /* block device */
+# define DT_REG 8 /* regular file */
+# define DT_LNK 10 /* symbolic link */
+# define DT_SOCK 12 /* socket */
+# define DT_WHT 14 /* whiteout */
+typedef struct gl_directory DIR;
+# define GNULIB_defined_struct_dirent 1
+# endif
+#endif
+
+/* The __attribute__ feature is available in gcc versions 2.5 and later.
+ The attribute __pure__ was added in gcc 2.96. */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
+# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
+#else
+# define _GL_ATTRIBUTE_PURE /* empty */
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
+
+/* The definition of _GL_ARG_NONNULL is copied here. */
+
+/* The definition of _GL_WARN_ON_USE is copied here. */
+
+
+/* Declare overridden functions. */
+
+#if @GNULIB_OPENDIR@
+# if @REPLACE_OPENDIR@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef opendir
+# define opendir rpl_opendir
+# define GNULIB_defined_opendir 1
+# endif
+_GL_FUNCDECL_RPL (opendir, DIR *, (const char *dir_name) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (opendir, DIR *, (const char *dir_name));
+# else
+# if !@HAVE_OPENDIR@
+_GL_FUNCDECL_SYS (opendir, DIR *, (const char *dir_name) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (opendir, DIR *, (const char *dir_name));
+# endif
+_GL_CXXALIASWARN (opendir);
+#elif defined GNULIB_POSIXCHECK
+# undef opendir
+# if HAVE_RAW_DECL_OPENDIR
+_GL_WARN_ON_USE (opendir, "opendir is not portable - "
+ "use gnulib module opendir for portability");
+# endif
+#endif
+
+#if @GNULIB_READDIR@
+# if !@HAVE_READDIR@
+_GL_FUNCDECL_SYS (readdir, struct dirent *, (DIR *dirp) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (readdir, struct dirent *, (DIR *dirp));
+_GL_CXXALIASWARN (readdir);
+#elif defined GNULIB_POSIXCHECK
+# undef readdir
+# if HAVE_RAW_DECL_READDIR
+_GL_WARN_ON_USE (readdir, "readdir is not portable - "
+ "use gnulib module readdir for portability");
+# endif
+#endif
+
+#if @GNULIB_REWINDDIR@
+# if !@HAVE_REWINDDIR@
+_GL_FUNCDECL_SYS (rewinddir, void, (DIR *dirp) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (rewinddir, void, (DIR *dirp));
+_GL_CXXALIASWARN (rewinddir);
+#elif defined GNULIB_POSIXCHECK
+# undef rewinddir
+# if HAVE_RAW_DECL_REWINDDIR
+_GL_WARN_ON_USE (rewinddir, "rewinddir is not portable - "
+ "use gnulib module rewinddir for portability");
+# endif
+#endif
+
+#if @GNULIB_CLOSEDIR@
+# if @REPLACE_CLOSEDIR@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef closedir
+# define closedir rpl_closedir
+# define GNULIB_defined_closedir 1
+# endif
+_GL_FUNCDECL_RPL (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (closedir, int, (DIR *dirp));
+# else
+# if !@HAVE_CLOSEDIR@
+_GL_FUNCDECL_SYS (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (closedir, int, (DIR *dirp));
+# endif
+_GL_CXXALIASWARN (closedir);
+#elif defined GNULIB_POSIXCHECK
+# undef closedir
+# if HAVE_RAW_DECL_CLOSEDIR
+_GL_WARN_ON_USE (closedir, "closedir is not portable - "
+ "use gnulib module closedir for portability");
+# endif
+#endif
+
+#if @GNULIB_DIRFD@
+/* Return the file descriptor associated with the given directory stream,
+ or -1 if none exists. */
+# if @REPLACE_DIRFD@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef dirfd
+# define dirfd rpl_dirfd
+# endif
+_GL_FUNCDECL_RPL (dirfd, int, (DIR *) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (dirfd, int, (DIR *));
+
+# ifdef __KLIBC__
+/* Gnulib internal hooks needed to maintain the dirfd metadata. */
+_GL_EXTERN_C int _gl_register_dirp_fd (int fd, DIR *dirp)
+ _GL_ARG_NONNULL ((2));
+_GL_EXTERN_C void _gl_unregister_dirp_fd (int fd);
+# endif
+# else
+# if defined __cplusplus && defined GNULIB_NAMESPACE && defined dirfd
+ /* dirfd is defined as a macro and not as a function.
+ Turn it into a function and get rid of the macro. */
+static inline int (dirfd) (DIR *dp) { return dirfd (dp); }
+# undef dirfd
+# endif
+# if !(@HAVE_DECL_DIRFD@ || defined dirfd)
+_GL_FUNCDECL_SYS (dirfd, int, (DIR *) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (dirfd, int, (DIR *));
+# endif
+_GL_CXXALIASWARN (dirfd);
+#elif defined GNULIB_POSIXCHECK
+# undef dirfd
+# if HAVE_RAW_DECL_DIRFD
+_GL_WARN_ON_USE (dirfd, "dirfd is unportable - "
+ "use gnulib module dirfd for portability");
+# endif
+#endif
+
+#if @GNULIB_FDOPENDIR@
+/* Open a directory stream visiting the given directory file
+ descriptor. Return NULL and set errno if fd is not visiting a
+ directory. On success, this function consumes fd (it will be
+ implicitly closed either by this function or by a subsequent
+ closedir). */
+# if @REPLACE_FDOPENDIR@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef fdopendir
+# define fdopendir rpl_fdopendir
+# endif
+_GL_FUNCDECL_RPL (fdopendir, DIR *, (int fd));
+_GL_CXXALIAS_RPL (fdopendir, DIR *, (int fd));
+# else
+# if !@HAVE_FDOPENDIR@ || !@HAVE_DECL_FDOPENDIR@
+_GL_FUNCDECL_SYS (fdopendir, DIR *, (int fd));
+# endif
+_GL_CXXALIAS_SYS (fdopendir, DIR *, (int fd));
+# endif
+_GL_CXXALIASWARN (fdopendir);
+#elif defined GNULIB_POSIXCHECK
+# undef fdopendir
+# if HAVE_RAW_DECL_FDOPENDIR
+_GL_WARN_ON_USE (fdopendir, "fdopendir is unportable - "
+ "use gnulib module fdopendir for portability");
+# endif
+#endif
+
+#if @GNULIB_SCANDIR@
+/* Scan the directory DIR, calling FILTER on each directory entry.
+ Entries for which FILTER returns nonzero are individually malloc'd,
+ sorted using qsort with CMP, and collected in a malloc'd array in
+ *NAMELIST. Returns the number of entries selected, or -1 on error. */
+# if !@HAVE_SCANDIR@
+_GL_FUNCDECL_SYS (scandir, int,
+ (const char *dir, struct dirent ***namelist,
+ int (*filter) (const struct dirent *),
+ int (*cmp) (const struct dirent **, const struct dirent **))
+ _GL_ARG_NONNULL ((1, 2, 4)));
+# endif
+/* Need to cast, because on glibc systems, the fourth parameter is
+ int (*cmp) (const void *, const void *). */
+_GL_CXXALIAS_SYS_CAST (scandir, int,
+ (const char *dir, struct dirent ***namelist,
+ int (*filter) (const struct dirent *),
+ int (*cmp) (const struct dirent **, const struct dirent **)));
+_GL_CXXALIASWARN (scandir);
+#elif defined GNULIB_POSIXCHECK
+# undef scandir
+# if HAVE_RAW_DECL_SCANDIR
+_GL_WARN_ON_USE (scandir, "scandir is unportable - "
+ "use gnulib module scandir for portability");
+# endif
+#endif
+
+#if @GNULIB_ALPHASORT@
+/* Compare two 'struct dirent' entries alphabetically. */
+# if !@HAVE_ALPHASORT@
+_GL_FUNCDECL_SYS (alphasort, int,
+ (const struct dirent **, const struct dirent **)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2)));
+# endif
+/* Need to cast, because on glibc systems, the parameters are
+ (const void *, const void *). */
+_GL_CXXALIAS_SYS_CAST (alphasort, int,
+ (const struct dirent **, const struct dirent **));
+_GL_CXXALIASWARN (alphasort);
+#elif defined GNULIB_POSIXCHECK
+# undef alphasort
+# if HAVE_RAW_DECL_ALPHASORT
+_GL_WARN_ON_USE (alphasort, "alphasort is unportable - "
+ "use gnulib module alphasort for portability");
+# endif
+#endif
+
+
+#endif /* _@GUARD_PREFIX@_DIRENT_H */
+#endif /* _@GUARD_PREFIX@_DIRENT_H */
diff --git a/gnulib/limits.in.h b/gnulib/limits.in.h
new file mode 100644
index 0000000..39750b3
--- /dev/null
+++ b/gnulib/limits.in.h
@@ -0,0 +1,104 @@
+/* A GNU-like <limits.h>.
+
+ Copyright 2016-2019 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 3, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _@GUARD_PREFIX@_LIMITS_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+/* The include_next requires a split double-inclusion guard. */
+#@INCLUDE_NEXT@ @NEXT_LIMITS_H@
+
+#ifndef _@GUARD_PREFIX@_LIMITS_H
+#define _@GUARD_PREFIX@_LIMITS_H
+
+#ifndef LLONG_MIN
+# if defined LONG_LONG_MIN /* HP-UX 11.31 */
+# define LLONG_MIN LONG_LONG_MIN
+# elif defined LONGLONG_MIN /* IRIX 6.5 */
+# define LLONG_MIN LONGLONG_MIN
+# elif defined __GNUC__
+# define LLONG_MIN (- __LONG_LONG_MAX__ - 1LL)
+# endif
+#endif
+#ifndef LLONG_MAX
+# if defined LONG_LONG_MAX /* HP-UX 11.31 */
+# define LLONG_MAX LONG_LONG_MAX
+# elif defined LONGLONG_MAX /* IRIX 6.5 */
+# define LLONG_MAX LONGLONG_MAX
+# elif defined __GNUC__
+# define LLONG_MAX __LONG_LONG_MAX__
+# endif
+#endif
+#ifndef ULLONG_MAX
+# if defined ULONG_LONG_MAX /* HP-UX 11.31 */
+# define ULLONG_MAX ULONG_LONG_MAX
+# elif defined ULONGLONG_MAX /* IRIX 6.5 */
+# define ULLONG_MAX ULONGLONG_MAX
+# elif defined __GNUC__
+# define ULLONG_MAX (__LONG_LONG_MAX__ * 2ULL + 1ULL)
+# endif
+#endif
+
+/* The number of usable bits in an unsigned or signed integer type
+ with minimum value MIN and maximum value MAX, as an int expression
+ suitable in #if. Cover all known practical hosts. This
+ implementation exploits the fact that MAX is 1 less than a power of
+ 2, and merely counts the number of 1 bits in MAX; "COBn" means
+ "count the number of 1 bits in the low-order n bits"). */
+#define _GL_INTEGER_WIDTH(min, max) (((min) < 0) + _GL_COB128 (max))
+#define _GL_COB128(n) (_GL_COB64 ((n) >> 31 >> 31 >> 2) + _GL_COB64 (n))
+#define _GL_COB64(n) (_GL_COB32 ((n) >> 31 >> 1) + _GL_COB32 (n))
+#define _GL_COB32(n) (_GL_COB16 ((n) >> 16) + _GL_COB16 (n))
+#define _GL_COB16(n) (_GL_COB8 ((n) >> 8) + _GL_COB8 (n))
+#define _GL_COB8(n) (_GL_COB4 ((n) >> 4) + _GL_COB4 (n))
+#define _GL_COB4(n) (!!((n) & 8) + !!((n) & 4) + !!((n) & 2) + !!((n) & 1))
+
+#ifndef WORD_BIT
+/* Assume 'int' is 32 bits wide. */
+# define WORD_BIT 32
+#endif
+#ifndef LONG_BIT
+/* Assume 'long' is 32 or 64 bits wide. */
+# if LONG_MAX == INT_MAX
+# define LONG_BIT 32
+# else
+# define LONG_BIT 64
+# endif
+#endif
+
+/* Macros specified by ISO/IEC TS 18661-1:2014. */
+
+#if (! defined ULLONG_WIDTH \
+ && (defined _GNU_SOURCE || defined __STDC_WANT_IEC_60559_BFP_EXT__))
+# define CHAR_WIDTH _GL_INTEGER_WIDTH (CHAR_MIN, CHAR_MAX)
+# define SCHAR_WIDTH _GL_INTEGER_WIDTH (SCHAR_MIN, SCHAR_MAX)
+# define UCHAR_WIDTH _GL_INTEGER_WIDTH (0, UCHAR_MAX)
+# define SHRT_WIDTH _GL_INTEGER_WIDTH (SHRT_MIN, SHRT_MAX)
+# define USHRT_WIDTH _GL_INTEGER_WIDTH (0, USHRT_MAX)
+# define INT_WIDTH _GL_INTEGER_WIDTH (INT_MIN, INT_MAX)
+# define UINT_WIDTH _GL_INTEGER_WIDTH (0, UINT_MAX)
+# define LONG_WIDTH _GL_INTEGER_WIDTH (LONG_MIN, LONG_MAX)
+# define ULONG_WIDTH _GL_INTEGER_WIDTH (0, ULONG_MAX)
+# define LLONG_WIDTH _GL_INTEGER_WIDTH (LLONG_MIN, LLONG_MAX)
+# define ULLONG_WIDTH _GL_INTEGER_WIDTH (0, ULLONG_MAX)
+#endif /* !ULLONG_WIDTH && (_GNU_SOURCE || __STDC_WANT_IEC_60559_BFP_EXT__) */
+
+#endif /* _@GUARD_PREFIX@_LIMITS_H */
+#endif /* _@GUARD_PREFIX@_LIMITS_H */
diff --git a/gnulib/m4/00gnulib.m4 b/gnulib/m4/00gnulib.m4
new file mode 100644
index 0000000..e3e0fb6
--- /dev/null
+++ b/gnulib/m4/00gnulib.m4
@@ -0,0 +1,46 @@
+# 00gnulib.m4 serial 3
+dnl Copyright (C) 2009-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This file must be named something that sorts before all other
+dnl gnulib-provided .m4 files. It is needed until such time as we can
+dnl assume Autoconf 2.64, with its improved AC_DEFUN_ONCE and
+dnl m4_divert semantics.
+
+# Until autoconf 2.63, handling of the diversion stack required m4_init
+# to be called first; but this does not happen with aclocal. Wrapping
+# the entire execution in another layer of the diversion stack fixes this.
+# Worse, prior to autoconf 2.62, m4_wrap depended on the underlying m4
+# for whether it was FIFO or LIFO; in order to properly balance with
+# m4_init, we need to undo our push just before anything wrapped within
+# the m4_init body. The way to ensure this is to wrap both sides of
+# m4_init with a one-shot macro that does the pop at the right time.
+m4_ifndef([_m4_divert_diversion],
+[m4_divert_push([KILL])
+m4_define([gl_divert_fixup], [m4_divert_pop()m4_define([$0])])
+m4_define([m4_init],
+ [gl_divert_fixup()]m4_defn([m4_init])[gl_divert_fixup()])])
+
+
+# AC_DEFUN_ONCE([NAME], VALUE)
+# ----------------------------
+# Define NAME to expand to VALUE on the first use (whether by direct
+# expansion, or by AC_REQUIRE), and to nothing on all subsequent uses.
+# Avoid bugs in AC_REQUIRE in Autoconf 2.63 and earlier. This
+# definition is slower than the version in Autoconf 2.64, because it
+# can only use interfaces that existed since 2.59; but it achieves the
+# same effect. Quoting is necessary to avoid confusing Automake.
+m4_version_prereq([2.63.263], [],
+[m4_define([AC][_DEFUN_ONCE],
+ [AC][_DEFUN([$1],
+ [AC_REQUIRE([_gl_DEFUN_ONCE([$1])],
+ [m4_indir([_gl_DEFUN_ONCE([$1])])])])]dnl
+[AC][_DEFUN([_gl_DEFUN_ONCE([$1])], [$2])])])
+
+# gl_00GNULIB
+# -----------
+# Witness macro that this file has been included. Needed to force
+# Automake to include this file prior to all other gnulib .m4 files.
+AC_DEFUN([gl_00GNULIB])
diff --git a/gnulib/m4/absolute-header.m4 b/gnulib/m4/absolute-header.m4
new file mode 100644
index 0000000..a8f2cba
--- /dev/null
+++ b/gnulib/m4/absolute-header.m4
@@ -0,0 +1,102 @@
+# absolute-header.m4 serial 16
+dnl Copyright (C) 2006-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Derek Price.
+
+# gl_ABSOLUTE_HEADER(HEADER1 HEADER2 ...)
+# ---------------------------------------
+# Find the absolute name of a header file, testing first if the header exists.
+# If the header were sys/inttypes.h, this macro would define
+# ABSOLUTE_SYS_INTTYPES_H to the '""' quoted absolute name of sys/inttypes.h
+# in config.h
+# (e.g. '#define ABSOLUTE_SYS_INTTYPES_H "///usr/include/sys/inttypes.h"').
+# The three "///" are to pacify Sun C 5.8, which otherwise would say
+# "warning: #include of /usr/include/... may be non-portable".
+# Use '""', not '<>', so that the /// cannot be confused with a C99 comment.
+# Note: This macro assumes that the header file is not empty after
+# preprocessing, i.e. it does not only define preprocessor macros but also
+# provides some type/enum definitions or function/variable declarations.
+AC_DEFUN([gl_ABSOLUTE_HEADER],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_PREPROC_REQUIRE()dnl
+dnl FIXME: gl_absolute_header and ac_header_exists must be used unquoted
+dnl until we can assume autoconf 2.64 or newer.
+m4_foreach_w([gl_HEADER_NAME], [$1],
+ [AS_VAR_PUSHDEF([gl_absolute_header],
+ [gl_cv_absolute_]m4_defn([gl_HEADER_NAME]))dnl
+ AC_CACHE_CHECK([absolute name of <]m4_defn([gl_HEADER_NAME])[>],
+ m4_defn([gl_absolute_header]),
+ [AS_VAR_PUSHDEF([ac_header_exists],
+ [ac_cv_header_]m4_defn([gl_HEADER_NAME]))dnl
+ AC_CHECK_HEADERS_ONCE(m4_defn([gl_HEADER_NAME]))dnl
+ if test AS_VAR_GET(ac_header_exists) = yes; then
+ gl_ABSOLUTE_HEADER_ONE(m4_defn([gl_HEADER_NAME]))
+ fi
+ AS_VAR_POPDEF([ac_header_exists])dnl
+ ])dnl
+ AC_DEFINE_UNQUOTED(AS_TR_CPP([ABSOLUTE_]m4_defn([gl_HEADER_NAME])),
+ ["AS_VAR_GET(gl_absolute_header)"],
+ [Define this to an absolute name of <]m4_defn([gl_HEADER_NAME])[>.])
+ AS_VAR_POPDEF([gl_absolute_header])dnl
+])dnl
+])# gl_ABSOLUTE_HEADER
+
+# gl_ABSOLUTE_HEADER_ONE(HEADER)
+# ------------------------------
+# Like gl_ABSOLUTE_HEADER, except that:
+# - it assumes that the header exists,
+# - it uses the current CPPFLAGS,
+# - it does not cache the result,
+# - it is silent.
+AC_DEFUN([gl_ABSOLUTE_HEADER_ONE],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_LANG_CONFTEST([AC_LANG_SOURCE([[#include <]]m4_dquote([$1])[[>]])])
+ dnl AIX "xlc -E" and "cc -E" omit #line directives for header files
+ dnl that contain only a #include of other header files and no
+ dnl non-comment tokens of their own. This leads to a failure to
+ dnl detect the absolute name of <dirent.h>, <signal.h>, <poll.h>
+ dnl and others. The workaround is to force preservation of comments
+ dnl through option -C. This ensures all necessary #line directives
+ dnl are present. GCC supports option -C as well.
+ case "$host_os" in
+ aix*) gl_absname_cpp="$ac_cpp -C" ;;
+ *) gl_absname_cpp="$ac_cpp" ;;
+ esac
+changequote(,)
+ case "$host_os" in
+ mingw*)
+ dnl For the sake of native Windows compilers (excluding gcc),
+ dnl treat backslash as a directory separator, like /.
+ dnl Actually, these compilers use a double-backslash as
+ dnl directory separator, inside the
+ dnl # line "filename"
+ dnl directives.
+ gl_dirsep_regex='[/\\]'
+ ;;
+ *)
+ gl_dirsep_regex='\/'
+ ;;
+ esac
+ dnl A sed expression that turns a string into a basic regular
+ dnl expression, for use within "/.../".
+ gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g'
+ gl_header_literal_regex=`echo '$1' \
+ | sed -e "$gl_make_literal_regex_sed"`
+ gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{
+ s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/
+ s|^/[^/]|//&|
+ p
+ q
+ }'
+changequote([,])
+ dnl eval is necessary to expand gl_absname_cpp.
+ dnl Ultrix and Pyramid sh refuse to redirect output of eval,
+ dnl so use subshell.
+ AS_VAR_SET([gl_cv_absolute_]AS_TR_SH([[$1]]),
+[`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD |
+ sed -n "$gl_absolute_header_sed"`])
+])
diff --git a/gnulib/m4/alloca.m4 b/gnulib/m4/alloca.m4
new file mode 100644
index 0000000..29bd289
--- /dev/null
+++ b/gnulib/m4/alloca.m4
@@ -0,0 +1,128 @@
+# alloca.m4 serial 15
+dnl Copyright (C) 2002-2004, 2006-2007, 2009-2019 Free Software Foundation,
+dnl Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_ALLOCA],
+[
+ AC_REQUIRE([AC_FUNC_ALLOCA])
+ if test $ac_cv_func_alloca_works = no; then
+ gl_PREREQ_ALLOCA
+ fi
+
+ # Define an additional variable used in the Makefile substitution.
+ if test $ac_cv_working_alloca_h = yes; then
+ AC_CACHE_CHECK([for alloca as a compiler built-in], [gl_cv_rpl_alloca], [
+ AC_EGREP_CPP([Need own alloca], [
+#if defined __GNUC__ || defined _AIX || defined _MSC_VER
+ Need own alloca
+#endif
+ ], [gl_cv_rpl_alloca=yes], [gl_cv_rpl_alloca=no])
+ ])
+ if test $gl_cv_rpl_alloca = yes; then
+ dnl OK, alloca can be implemented through a compiler built-in.
+ AC_DEFINE([HAVE_ALLOCA], [1],
+ [Define to 1 if you have 'alloca' after including <alloca.h>,
+ a header that may be supplied by this distribution.])
+ ALLOCA_H=alloca.h
+ else
+ dnl alloca exists as a library function, i.e. it is slow and probably
+ dnl a memory leak. Don't define HAVE_ALLOCA in this case.
+ ALLOCA_H=
+ fi
+ else
+ ALLOCA_H=alloca.h
+ fi
+ AC_SUBST([ALLOCA_H])
+ AM_CONDITIONAL([GL_GENERATE_ALLOCA_H], [test -n "$ALLOCA_H"])
+
+ if test $ac_cv_working_alloca_h = yes; then
+ HAVE_ALLOCA_H=1
+ else
+ HAVE_ALLOCA_H=0
+ fi
+ AC_SUBST([HAVE_ALLOCA_H])
+])
+
+# Prerequisites of lib/alloca.c.
+# STACK_DIRECTION is already handled by AC_FUNC_ALLOCA.
+AC_DEFUN([gl_PREREQ_ALLOCA], [:])
+
+# This works around a bug in autoconf <= 2.68.
+# See <https://lists.gnu.org/r/bug-gnulib/2011-06/msg00277.html>.
+
+m4_version_prereq([2.69], [] ,[
+
+# This is taken from the following Autoconf patch:
+# https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=6cd9f12520b0d6f76d3230d7565feba1ecf29497
+
+# _AC_LIBOBJ_ALLOCA
+# -----------------
+# Set up the LIBOBJ replacement of 'alloca'. Well, not exactly
+# AC_LIBOBJ since we actually set the output variable 'ALLOCA'.
+# Nevertheless, for Automake, AC_LIBSOURCES it.
+m4_define([_AC_LIBOBJ_ALLOCA],
+[# The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble. Some versions do not even contain alloca or
+# contain a buggy version. If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+AC_LIBSOURCES(alloca.c)
+AC_SUBST([ALLOCA], [\${LIBOBJDIR}alloca.$ac_objext])dnl
+AC_DEFINE(C_ALLOCA, 1, [Define to 1 if using 'alloca.c'.])
+
+AC_CACHE_CHECK(whether 'alloca.c' needs Cray hooks, ac_cv_os_cray,
+[AC_EGREP_CPP(webecray,
+[#if defined CRAY && ! defined CRAY2
+webecray
+#else
+wenotbecray
+#endif
+], ac_cv_os_cray=yes, ac_cv_os_cray=no)])
+if test $ac_cv_os_cray = yes; then
+ for ac_func in _getb67 GETB67 getb67; do
+ AC_CHECK_FUNC($ac_func,
+ [AC_DEFINE_UNQUOTED(CRAY_STACKSEG_END, $ac_func,
+ [Define to one of '_getb67', 'GETB67',
+ 'getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for
+ 'alloca.c' support on those systems.])
+ break])
+ done
+fi
+
+AC_CACHE_CHECK([stack direction for C alloca],
+ [ac_cv_c_stack_direction],
+[AC_RUN_IFELSE([AC_LANG_SOURCE(
+[AC_INCLUDES_DEFAULT
+int
+find_stack_direction (int *addr, int depth)
+{
+ int dir, dummy = 0;
+ if (! addr)
+ addr = &dummy;
+ *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
+ dir = depth ? find_stack_direction (addr, depth - 1) : 0;
+ return dir + dummy;
+}
+
+int
+main (int argc, char **argv)
+{
+ return find_stack_direction (0, argc + !argv + 20) < 0;
+}])],
+ [ac_cv_c_stack_direction=1],
+ [ac_cv_c_stack_direction=-1],
+ [ac_cv_c_stack_direction=0])])
+AH_VERBATIM([STACK_DIRECTION],
+[/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at runtime.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+@%:@undef STACK_DIRECTION])dnl
+AC_DEFINE_UNQUOTED(STACK_DIRECTION, $ac_cv_c_stack_direction)
+])# _AC_LIBOBJ_ALLOCA
+])
diff --git a/gnulib/m4/dirent_h.m4 b/gnulib/m4/dirent_h.m4
new file mode 100644
index 0000000..732aa55
--- /dev/null
+++ b/gnulib/m4/dirent_h.m4
@@ -0,0 +1,64 @@
+# dirent_h.m4 serial 16
+dnl Copyright (C) 2008-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Written by Bruno Haible.
+
+AC_DEFUN([gl_DIRENT_H],
+[
+ dnl Use AC_REQUIRE here, so that the default behavior below is expanded
+ dnl once only, before all statements that occur in other macros.
+ AC_REQUIRE([gl_DIRENT_H_DEFAULTS])
+
+ dnl <dirent.h> is always overridden, because of GNULIB_POSIXCHECK.
+ gl_CHECK_NEXT_HEADERS([dirent.h])
+ if test $ac_cv_header_dirent_h = yes; then
+ HAVE_DIRENT_H=1
+ else
+ HAVE_DIRENT_H=0
+ fi
+ AC_SUBST([HAVE_DIRENT_H])
+
+ dnl Check for declarations of anything we want to poison if the
+ dnl corresponding gnulib module is not in use.
+ gl_WARN_ON_USE_PREPARE([[#include <dirent.h>
+ ]], [alphasort closedir dirfd fdopendir opendir readdir rewinddir scandir])
+])
+
+AC_DEFUN([gl_DIRENT_MODULE_INDICATOR],
+[
+ dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+ AC_REQUIRE([gl_DIRENT_H_DEFAULTS])
+ gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+ dnl Define it also as a C macro, for the benefit of the unit tests.
+ gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+AC_DEFUN([gl_DIRENT_H_DEFAULTS],
+[
+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) dnl for REPLACE_FCHDIR
+ GNULIB_OPENDIR=0; AC_SUBST([GNULIB_OPENDIR])
+ GNULIB_READDIR=0; AC_SUBST([GNULIB_READDIR])
+ GNULIB_REWINDDIR=0; AC_SUBST([GNULIB_REWINDDIR])
+ GNULIB_CLOSEDIR=0; AC_SUBST([GNULIB_CLOSEDIR])
+ GNULIB_DIRFD=0; AC_SUBST([GNULIB_DIRFD])
+ GNULIB_FDOPENDIR=0; AC_SUBST([GNULIB_FDOPENDIR])
+ GNULIB_SCANDIR=0; AC_SUBST([GNULIB_SCANDIR])
+ GNULIB_ALPHASORT=0; AC_SUBST([GNULIB_ALPHASORT])
+ dnl Assume proper GNU behavior unless another module says otherwise.
+ HAVE_OPENDIR=1; AC_SUBST([HAVE_OPENDIR])
+ HAVE_READDIR=1; AC_SUBST([HAVE_READDIR])
+ HAVE_REWINDDIR=1; AC_SUBST([HAVE_REWINDDIR])
+ HAVE_CLOSEDIR=1; AC_SUBST([HAVE_CLOSEDIR])
+ HAVE_DECL_DIRFD=1; AC_SUBST([HAVE_DECL_DIRFD])
+ HAVE_DECL_FDOPENDIR=1;AC_SUBST([HAVE_DECL_FDOPENDIR])
+ HAVE_FDOPENDIR=1; AC_SUBST([HAVE_FDOPENDIR])
+ HAVE_SCANDIR=1; AC_SUBST([HAVE_SCANDIR])
+ HAVE_ALPHASORT=1; AC_SUBST([HAVE_ALPHASORT])
+ REPLACE_OPENDIR=0; AC_SUBST([REPLACE_OPENDIR])
+ REPLACE_CLOSEDIR=0; AC_SUBST([REPLACE_CLOSEDIR])
+ REPLACE_DIRFD=0; AC_SUBST([REPLACE_DIRFD])
+ REPLACE_FDOPENDIR=0; AC_SUBST([REPLACE_FDOPENDIR])
+])
diff --git a/gnulib/m4/eealloc.m4 b/gnulib/m4/eealloc.m4
new file mode 100644
index 0000000..2a4b120
--- /dev/null
+++ b/gnulib/m4/eealloc.m4
@@ -0,0 +1,31 @@
+# eealloc.m4 serial 3
+dnl Copyright (C) 2003, 2009-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_EEALLOC],
+[
+ AC_REQUIRE([gl_EEMALLOC])
+ AC_REQUIRE([gl_EEREALLOC])
+])
+
+AC_DEFUN([gl_EEMALLOC],
+[
+ _AC_FUNC_MALLOC_IF(
+ [gl_cv_func_malloc_0_nonnull=1],
+ [gl_cv_func_malloc_0_nonnull=0])
+ AC_DEFINE_UNQUOTED([MALLOC_0_IS_NONNULL], [$gl_cv_func_malloc_0_nonnull],
+ [If malloc(0) is != NULL, define this to 1. Otherwise define this
+ to 0.])
+])
+
+AC_DEFUN([gl_EEREALLOC],
+[
+ _AC_FUNC_REALLOC_IF(
+ [gl_cv_func_realloc_0_nonnull=1],
+ [gl_cv_func_realloc_0_nonnull=0])
+ AC_DEFINE_UNQUOTED([REALLOC_0_IS_NONNULL], [$gl_cv_func_realloc_0_nonnull],
+ [If realloc(NULL,0) is != NULL, define this to 1. Otherwise define this
+ to 0.])
+])
diff --git a/gnulib/m4/environ.m4 b/gnulib/m4/environ.m4
new file mode 100644
index 0000000..c1a6fa3
--- /dev/null
+++ b/gnulib/m4/environ.m4
@@ -0,0 +1,45 @@
+# environ.m4 serial 7
+dnl Copyright (C) 2001-2004, 2006-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN_ONCE([gl_ENVIRON],
+[
+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+ dnl Persuade glibc <unistd.h> to declare environ.
+ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+
+ AC_CHECK_HEADERS_ONCE([unistd.h])
+ gt_CHECK_VAR_DECL(
+ [#if HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+ /* mingw, BeOS, Haiku declare environ in <stdlib.h>, not in <unistd.h>. */
+ #include <stdlib.h>
+ ],
+ [environ])
+ if test $gt_cv_var_environ_declaration != yes; then
+ HAVE_DECL_ENVIRON=0
+ fi
+])
+
+# Check if a variable is properly declared.
+# gt_CHECK_VAR_DECL(includes,variable)
+AC_DEFUN([gt_CHECK_VAR_DECL],
+[
+ define([gt_cv_var], [gt_cv_var_]$2[_declaration])
+ AC_CACHE_CHECK([if $2 is properly declared], [gt_cv_var],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[$1
+ extern struct { int foo; } $2;]],
+ [[$2.foo = 1;]])],
+ [gt_cv_var=no],
+ [gt_cv_var=yes])])
+ if test $gt_cv_var = yes; then
+ AC_DEFINE([HAVE_]m4_translit($2, [a-z], [A-Z])[_DECL], 1,
+ [Define if you have the declaration of $2.])
+ fi
+ undefine([gt_cv_var])
+])
diff --git a/gnulib/m4/extensions.m4 b/gnulib/m4/extensions.m4
new file mode 100644
index 0000000..fd1ce81
--- /dev/null
+++ b/gnulib/m4/extensions.m4
@@ -0,0 +1,189 @@
+# serial 18 -*- Autoconf -*-
+# Enable extensions on systems that normally disable them.
+
+# Copyright (C) 2003, 2006-2019 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This definition of AC_USE_SYSTEM_EXTENSIONS is stolen from git
+# Autoconf. Perhaps we can remove this once we can assume Autoconf
+# 2.70 or later everywhere, but since Autoconf mutates rapidly
+# enough in this area it's likely we'll need to redefine
+# AC_USE_SYSTEM_EXTENSIONS for quite some time.
+
+# If autoconf reports a warning
+# warning: AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS
+# or warning: AC_RUN_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS
+# the fix is
+# 1) to ensure that AC_USE_SYSTEM_EXTENSIONS is never directly invoked
+# but always AC_REQUIREd,
+# 2) to ensure that for each occurrence of
+# AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+# or
+# AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+# the corresponding gnulib module description has 'extensions' among
+# its dependencies. This will ensure that the gl_USE_SYSTEM_EXTENSIONS
+# invocation occurs in gl_EARLY, not in gl_INIT.
+
+# AC_USE_SYSTEM_EXTENSIONS
+# ------------------------
+# Enable extensions on systems that normally disable them,
+# typically due to standards-conformance issues.
+#
+# Remember that #undef in AH_VERBATIM gets replaced with #define by
+# AC_DEFINE. The goal here is to define all known feature-enabling
+# macros, then, if reports of conflicts are made, disable macros that
+# cause problems on some platforms (such as __EXTENSIONS__).
+AC_DEFUN_ONCE([AC_USE_SYSTEM_EXTENSIONS],
+[AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl
+AC_BEFORE([$0], [AC_RUN_IFELSE])dnl
+
+ AC_CHECK_HEADER([minix/config.h], [MINIX=yes], [MINIX=])
+ if test "$MINIX" = yes; then
+ AC_DEFINE([_POSIX_SOURCE], [1],
+ [Define to 1 if you need to in order for 'stat' and other
+ things to work.])
+ AC_DEFINE([_POSIX_1_SOURCE], [2],
+ [Define to 2 if the system does not provide POSIX.1 features
+ except with this defined.])
+ AC_DEFINE([_MINIX], [1],
+ [Define to 1 if on MINIX.])
+ AC_DEFINE([_NETBSD_SOURCE], [1],
+ [Define to 1 to make NetBSD features available. MINIX 3 needs this.])
+ fi
+
+dnl Use a different key than __EXTENSIONS__, as that name broke existing
+dnl configure.ac when using autoheader 2.62.
+ AH_VERBATIM([USE_SYSTEM_EXTENSIONS],
+[/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable general extensions on macOS. */
+#ifndef _DARWIN_C_SOURCE
+# undef _DARWIN_C_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable NetBSD extensions on NetBSD. */
+#ifndef _NETBSD_SOURCE
+# undef _NETBSD_SOURCE
+#endif
+/* Enable OpenBSD extensions on NetBSD. */
+#ifndef _OPENBSD_SOURCE
+# undef _OPENBSD_SOURCE
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
+#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
+#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+# undef __STDC_WANT_IEC_60559_BFP_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
+#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
+# undef __STDC_WANT_IEC_60559_DFP_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
+#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
+# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */
+#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
+# undef __STDC_WANT_IEC_60559_TYPES_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
+#ifndef __STDC_WANT_LIB_EXT2__
+# undef __STDC_WANT_LIB_EXT2__
+#endif
+/* Enable extensions specified by ISO/IEC 24747:2009. */
+#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
+# undef __STDC_WANT_MATH_SPEC_FUNCS__
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable X/Open extensions if necessary. HP-UX 11.11 defines
+ mbstate_t only if _XOPEN_SOURCE is defined to 500, regardless of
+ whether compiling with -Ae or -D_HPUX_SOURCE=1. */
+#ifndef _XOPEN_SOURCE
+# undef _XOPEN_SOURCE
+#endif
+/* Enable X/Open compliant socket functions that do not require linking
+ with -lxnet on HP-UX 11.11. */
+#ifndef _HPUX_ALT_XOPEN_SOCKET_API
+# undef _HPUX_ALT_XOPEN_SOCKET_API
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+])
+ AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__],
+ [ac_cv_safe_to_define___extensions__],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+# define __EXTENSIONS__ 1
+ ]AC_INCLUDES_DEFAULT])],
+ [ac_cv_safe_to_define___extensions__=yes],
+ [ac_cv_safe_to_define___extensions__=no])])
+ test $ac_cv_safe_to_define___extensions__ = yes &&
+ AC_DEFINE([__EXTENSIONS__])
+ AC_DEFINE([_ALL_SOURCE])
+ AC_DEFINE([_DARWIN_C_SOURCE])
+ AC_DEFINE([_GNU_SOURCE])
+ AC_DEFINE([_NETBSD_SOURCE])
+ AC_DEFINE([_OPENBSD_SOURCE])
+ AC_DEFINE([_POSIX_PTHREAD_SEMANTICS])
+ AC_DEFINE([__STDC_WANT_IEC_60559_ATTRIBS_EXT__])
+ AC_DEFINE([__STDC_WANT_IEC_60559_BFP_EXT__])
+ AC_DEFINE([__STDC_WANT_IEC_60559_DFP_EXT__])
+ AC_DEFINE([__STDC_WANT_IEC_60559_FUNCS_EXT__])
+ AC_DEFINE([__STDC_WANT_IEC_60559_TYPES_EXT__])
+ AC_DEFINE([__STDC_WANT_LIB_EXT2__])
+ AC_DEFINE([__STDC_WANT_MATH_SPEC_FUNCS__])
+ AC_DEFINE([_TANDEM_SOURCE])
+ AC_CACHE_CHECK([whether _XOPEN_SOURCE should be defined],
+ [ac_cv_should_define__xopen_source],
+ [ac_cv_should_define__xopen_source=no
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #include <wchar.h>
+ mbstate_t x;]])],
+ [],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #define _XOPEN_SOURCE 500
+ #include <wchar.h>
+ mbstate_t x;]])],
+ [ac_cv_should_define__xopen_source=yes])])])
+ test $ac_cv_should_define__xopen_source = yes &&
+ AC_DEFINE([_XOPEN_SOURCE], [500])
+ AC_DEFINE([_HPUX_ALT_XOPEN_SOCKET_API])
+])# AC_USE_SYSTEM_EXTENSIONS
+
+# gl_USE_SYSTEM_EXTENSIONS
+# ------------------------
+# Enable extensions on systems that normally disable them,
+# typically due to standards-conformance issues.
+AC_DEFUN_ONCE([gl_USE_SYSTEM_EXTENSIONS],
+[
+ dnl Require this macro before AC_USE_SYSTEM_EXTENSIONS.
+ dnl gnulib does not need it. But if it gets required by third-party macros
+ dnl after AC_USE_SYSTEM_EXTENSIONS is required, autoconf 2.62..2.63 emit a
+ dnl warning: "AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS".
+ dnl Note: We can do this only for one of the macros AC_AIX, AC_GNU_SOURCE,
+ dnl AC_MINIX. If people still use AC_AIX or AC_MINIX, they are out of luck.
+ AC_REQUIRE([AC_GNU_SOURCE])
+
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+])
diff --git a/gnulib/m4/extern-inline.m4 b/gnulib/m4/extern-inline.m4
new file mode 100644
index 0000000..ec9f221
--- /dev/null
+++ b/gnulib/m4/extern-inline.m4
@@ -0,0 +1,114 @@
+dnl 'extern inline' a la ISO C99.
+
+dnl Copyright 2012-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_EXTERN_INLINE],
+[
+ AH_VERBATIM([extern_inline],
+[/* Please see the Gnulib manual for how to use these macros.
+
+ Suppress extern inline with HP-UX cc, as it appears to be broken; see
+ <https://lists.gnu.org/r/bug-texinfo/2013-02/msg00030.html>.
+
+ Suppress extern inline with Sun C in standards-conformance mode, as it
+ mishandles inline functions that call each other. E.g., for 'inline void f
+ (void) { } inline void g (void) { f (); }', c99 incorrectly complains
+ 'reference to static identifier "f" in extern inline function'.
+ This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16.
+
+ Suppress extern inline (with or without __attribute__ ((__gnu_inline__)))
+ on configurations that mistakenly use 'static inline' to implement
+ functions or macros in standard C headers like <ctype.h>. For example,
+ if isdigit is mistakenly implemented via a static inline function,
+ a program containing an extern inline function that calls isdigit
+ may not work since the C standard prohibits extern inline functions
+ from calling static functions (ISO C 99 section 6.7.4.(3).
+ This bug is known to occur on:
+
+ OS X 10.8 and earlier; see:
+ https://lists.gnu.org/r/bug-gnulib/2012-12/msg00023.html
+
+ DragonFly; see
+ http://muscles.dragonflybsd.org/bulk/bleeding-edge-potential/latest-per-pkg/ah-tty-0.3.12.log
+
+ FreeBSD; see:
+ https://lists.gnu.org/r/bug-gnulib/2014-07/msg00104.html
+
+ OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and
+ for clang but remains for g++; see <https://trac.macports.org/ticket/41033>.
+ Assume DragonFly and FreeBSD will be similar.
+
+ GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
+ inline semantics, unless -fgnu89-inline is used. It defines a macro
+ __GNUC_STDC_INLINE__ to indicate this situation or a macro
+ __GNUC_GNU_INLINE__ to indicate the opposite situation.
+ GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline
+ semantics but warns, unless -fgnu89-inline is used:
+ warning: C99 inline functions are not supported; using GNU89
+ warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute
+ It defines a macro __GNUC_GNU_INLINE__ to indicate this situation.
+ */
+#if (((defined __APPLE__ && defined __MACH__) \
+ || defined __DragonFly__ || defined __FreeBSD__) \
+ && (defined __header_inline \
+ ? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \
+ && ! defined __clang__) \
+ : ((! defined _DONT_USE_CTYPE_INLINE_ \
+ && (defined __GNUC__ || defined __cplusplus)) \
+ || (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \
+ && defined __GNUC__ && ! defined __cplusplus))))
+# define _GL_EXTERN_INLINE_STDHEADER_BUG
+#endif
+#if ((__GNUC__ \
+ ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \
+ : (199901L <= __STDC_VERSION__ \
+ && !defined __HP_cc \
+ && !defined __PGI \
+ && !(defined __SUNPRO_C && __STDC__))) \
+ && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)
+# define _GL_INLINE inline
+# define _GL_EXTERN_INLINE extern inline
+# define _GL_EXTERN_INLINE_IN_USE
+#elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \
+ && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)
+# if defined __GNUC_GNU_INLINE__ && __GNUC_GNU_INLINE__
+ /* __gnu_inline__ suppresses a GCC 4.2 diagnostic. */
+# define _GL_INLINE extern inline __attribute__ ((__gnu_inline__))
+# else
+# define _GL_INLINE extern inline
+# endif
+# define _GL_EXTERN_INLINE extern
+# define _GL_EXTERN_INLINE_IN_USE
+#else
+# define _GL_INLINE static _GL_UNUSED
+# define _GL_EXTERN_INLINE static _GL_UNUSED
+#endif
+
+/* In GCC 4.6 (inclusive) to 5.1 (exclusive),
+ suppress bogus "no previous prototype for 'FOO'"
+ and "no previous declaration for 'FOO'" diagnostics,
+ when FOO is an inline function in the header; see
+ <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113> and
+ <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63877>. */
+#if __GNUC__ == 4 && 6 <= __GNUC_MINOR__
+# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__
+# define _GL_INLINE_HEADER_CONST_PRAGMA
+# else
+# define _GL_INLINE_HEADER_CONST_PRAGMA \
+ _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"")
+# endif
+# define _GL_INLINE_HEADER_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \
+ _Pragma ("GCC diagnostic ignored \"-Wmissing-declarations\"") \
+ _GL_INLINE_HEADER_CONST_PRAGMA
+# define _GL_INLINE_HEADER_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+# define _GL_INLINE_HEADER_BEGIN
+# define _GL_INLINE_HEADER_END
+#endif])
+])
diff --git a/gnulib/m4/gnulib-cache.m4 b/gnulib/m4/gnulib-cache.m4
new file mode 100644
index 0000000..0a37303
--- /dev/null
+++ b/gnulib/m4/gnulib-cache.m4
@@ -0,0 +1,72 @@
+# Copyright (C) 2002-2019 Free Software Foundation, Inc.
+#
+# 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
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This file is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this file. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License,
+# this file may be distributed as part of a program that
+# contains a configuration script generated by Autoconf, under
+# the same distribution terms as the rest of that program.
+#
+# Generated by gnulib-tool.
+#
+# This file represents the specification of how gnulib-tool is used.
+# It acts as a cache: It is written and read by gnulib-tool.
+# In projects that use version control, this file is meant to be put under
+# version control, like the configure.ac and various Makefile.am files.
+
+
+# Specification in the form of a command-line invocation:
+# gnulib-tool --import \
+# --lib=libgnu \
+# --source-base=gnulib \
+# --m4-base=gnulib/m4 \
+# --doc-base=doc \
+# --tests-base=tests \
+# --aux-dir=build-aux \
+# --no-conditional-dependencies \
+# --libtool \
+# --macro-prefix=gl \
+# --no-vc-files \
+# dirent \
+# lib-msvc-compat \
+# malloc-gnu \
+# manywarnings \
+# realloc-gnu \
+# setenv \
+# strndup
+
+# Specification in the form of a few gnulib-tool.m4 macro invocations:
+gl_LOCAL_DIR([])
+gl_MODULES([
+ dirent
+ lib-msvc-compat
+ malloc-gnu
+ manywarnings
+ realloc-gnu
+ setenv
+ strndup
+])
+gl_AVOID([])
+gl_SOURCE_BASE([gnulib])
+gl_M4_BASE([gnulib/m4])
+gl_PO_BASE([])
+gl_DOC_BASE([doc])
+gl_TESTS_BASE([tests])
+gl_LIB([libgnu])
+gl_MAKEFILE_NAME([])
+gl_LIBTOOL
+gl_MACRO_PREFIX([gl])
+gl_PO_DOMAIN([])
+gl_WITNESS_C_MACRO([])
+gl_VC_FILES([false])
diff --git a/gnulib/m4/gnulib-common.m4 b/gnulib/m4/gnulib-common.m4
new file mode 100644
index 0000000..57b94ed
--- /dev/null
+++ b/gnulib/m4/gnulib-common.m4
@@ -0,0 +1,424 @@
+# gnulib-common.m4 serial 44
+dnl Copyright (C) 2007-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_PREREQ([2.62])
+
+# gl_COMMON
+# is expanded unconditionally through gnulib-tool magic.
+AC_DEFUN([gl_COMMON], [
+ dnl Use AC_REQUIRE here, so that the code is expanded once only.
+ AC_REQUIRE([gl_00GNULIB])
+ AC_REQUIRE([gl_COMMON_BODY])
+])
+AC_DEFUN([gl_COMMON_BODY], [
+ AH_VERBATIM([_Noreturn],
+[/* The _Noreturn keyword of C11. */
+#ifndef _Noreturn
+# if (defined __cplusplus \
+ && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \
+ || (defined _MSC_VER && 1900 <= _MSC_VER)))
+# define _Noreturn [[noreturn]]
+# elif ((!defined __cplusplus || defined __clang__) \
+ && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
+ || 4 < __GNUC__ + (7 <= __GNUC_MINOR__)))
+ /* _Noreturn works as-is. */
+# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C
+# define _Noreturn __attribute__ ((__noreturn__))
+# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn
+# endif
+#endif
+])
+ AH_VERBATIM([isoc99_inline],
+[/* Work around a bug in Apple GCC 4.0.1 build 5465: In C99 mode, it supports
+ the ISO C 99 semantics of 'extern inline' (unlike the GNU C semantics of
+ earlier versions), but does not display it by setting __GNUC_STDC_INLINE__.
+ __APPLE__ && __MACH__ test for Mac OS X.
+ __APPLE_CC__ tests for the Apple compiler and its version.
+ __STDC_VERSION__ tests for the C99 mode. */
+#if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__
+# define __GNUC_STDC_INLINE__ 1
+#endif])
+ AH_VERBATIM([unused_parameter],
+[/* Define as a marker that can be attached to declarations that might not
+ be used. This helps to reduce warnings, such as from
+ GCC -Wunused-parameter. */
+#if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+# define _GL_UNUSED __attribute__ ((__unused__))
+#else
+# define _GL_UNUSED
+#endif
+/* The name _UNUSED_PARAMETER_ is an earlier spelling, although the name
+ is a misnomer outside of parameter lists. */
+#define _UNUSED_PARAMETER_ _GL_UNUSED
+
+/* gcc supports the "unused" attribute on possibly unused labels, and
+ g++ has since version 4.5. Note to support C++ as well as C,
+ _GL_UNUSED_LABEL should be used with a trailing ; */
+#if !defined __cplusplus || __GNUC__ > 4 \
+ || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+# define _GL_UNUSED_LABEL _GL_UNUSED
+#else
+# define _GL_UNUSED_LABEL
+#endif
+
+/* The __pure__ attribute was added in gcc 2.96. */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
+# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
+#else
+# define _GL_ATTRIBUTE_PURE /* empty */
+#endif
+
+/* The __const__ attribute was added in gcc 2.95. */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
+# define _GL_ATTRIBUTE_CONST __attribute__ ((__const__))
+#else
+# define _GL_ATTRIBUTE_CONST /* empty */
+#endif
+
+/* The __malloc__ attribute was added in gcc 3. */
+#if 3 <= __GNUC__
+# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+#else
+# define _GL_ATTRIBUTE_MALLOC /* empty */
+#endif
+])
+ AH_VERBATIM([async_safe],
+[/* The _GL_ASYNC_SAFE marker should be attached to functions that are
+ signal handlers (for signals other than SIGABRT, SIGPIPE) or can be
+ invoked from such signal handlers. Such functions have some restrictions:
+ * All functions that it calls should be marked _GL_ASYNC_SAFE as well,
+ or should be listed as async-signal-safe in POSIX
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04>
+ section 2.4.3. Note that malloc(), sprintf(), and fwrite(), in
+ particular, are NOT async-signal-safe.
+ * All memory locations (variables and struct fields) that these functions
+ access must be marked 'volatile'. This holds for both read and write
+ accesses. Otherwise the compiler might optimize away stores to and
+ reads from such locations that occur in the program, depending on its
+ data flow analysis. For example, when the program contains a loop
+ that is intended to inspect a variable set from within a signal handler
+ while (!signal_occurred)
+ ;
+ the compiler is allowed to transform this into an endless loop if the
+ variable 'signal_occurred' is not declared 'volatile'.
+ Additionally, recall that:
+ * A signal handler should not modify errno (except if it is a handler
+ for a fatal signal and ends by raising the same signal again, thus
+ provoking the termination of the process). If it invokes a function
+ that may clobber errno, it needs to save and restore the value of
+ errno. */
+#define _GL_ASYNC_SAFE
+])
+ dnl Preparation for running test programs:
+ dnl Tell glibc to write diagnostics from -D_FORTIFY_SOURCE=2 to stderr, not
+ dnl to /dev/tty, so they can be redirected to log files. Such diagnostics
+ dnl arise e.g., in the macros gl_PRINTF_DIRECTIVE_N, gl_SNPRINTF_DIRECTIVE_N.
+ LIBC_FATAL_STDERR_=1
+ export LIBC_FATAL_STDERR_
+])
+
+# gl_MODULE_INDICATOR_CONDITION
+# expands to a C preprocessor expression that evaluates to 1 or 0, depending
+# whether a gnulib module that has been requested shall be considered present
+# or not.
+m4_define([gl_MODULE_INDICATOR_CONDITION], [1])
+
+# gl_MODULE_INDICATOR_SET_VARIABLE([modulename])
+# sets the shell variable that indicates the presence of the given module to
+# a C preprocessor expression that will evaluate to 1.
+AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE],
+[
+ gl_MODULE_INDICATOR_SET_VARIABLE_AUX(
+ [GNULIB_[]m4_translit([[$1]],
+ [abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])],
+ [gl_MODULE_INDICATOR_CONDITION])
+])
+
+# gl_MODULE_INDICATOR_SET_VARIABLE_AUX([variable])
+# modifies the shell variable to include the gl_MODULE_INDICATOR_CONDITION.
+# The shell variable's value is a C preprocessor expression that evaluates
+# to 0 or 1.
+AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE_AUX],
+[
+ m4_if(m4_defn([gl_MODULE_INDICATOR_CONDITION]), [1],
+ [
+ dnl Simplify the expression VALUE || 1 to 1.
+ $1=1
+ ],
+ [gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR([$1],
+ [gl_MODULE_INDICATOR_CONDITION])])
+])
+
+# gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR([variable], [condition])
+# modifies the shell variable to include the given condition. The shell
+# variable's value is a C preprocessor expression that evaluates to 0 or 1.
+AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR],
+[
+ dnl Simplify the expression 1 || CONDITION to 1.
+ if test "$[]$1" != 1; then
+ dnl Simplify the expression 0 || CONDITION to CONDITION.
+ if test "$[]$1" = 0; then
+ $1=$2
+ else
+ $1="($[]$1 || $2)"
+ fi
+ fi
+])
+
+# gl_MODULE_INDICATOR([modulename])
+# defines a C macro indicating the presence of the given module
+# in a location where it can be used.
+# | Value | Value |
+# | in lib/ | in tests/ |
+# --------------------------------------------+---------+-----------+
+# Module present among main modules: | 1 | 1 |
+# --------------------------------------------+---------+-----------+
+# Module present among tests-related modules: | 0 | 1 |
+# --------------------------------------------+---------+-----------+
+# Module not present at all: | 0 | 0 |
+# --------------------------------------------+---------+-----------+
+AC_DEFUN([gl_MODULE_INDICATOR],
+[
+ AC_DEFINE_UNQUOTED([GNULIB_]m4_translit([[$1]],
+ [abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___]),
+ [gl_MODULE_INDICATOR_CONDITION],
+ [Define to a C preprocessor expression that evaluates to 1 or 0,
+ depending whether the gnulib module $1 shall be considered present.])
+])
+
+# gl_MODULE_INDICATOR_FOR_TESTS([modulename])
+# defines a C macro indicating the presence of the given module
+# in lib or tests. This is useful to determine whether the module
+# should be tested.
+# | Value | Value |
+# | in lib/ | in tests/ |
+# --------------------------------------------+---------+-----------+
+# Module present among main modules: | 1 | 1 |
+# --------------------------------------------+---------+-----------+
+# Module present among tests-related modules: | 1 | 1 |
+# --------------------------------------------+---------+-----------+
+# Module not present at all: | 0 | 0 |
+# --------------------------------------------+---------+-----------+
+AC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS],
+[
+ AC_DEFINE([GNULIB_TEST_]m4_translit([[$1]],
+ [abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___]), [1],
+ [Define to 1 when the gnulib module $1 should be tested.])
+])
+
+# gl_ASSERT_NO_GNULIB_POSIXCHECK
+# asserts that there will never be a need to #define GNULIB_POSIXCHECK.
+# and thereby enables an optimization of configure and config.h.
+# Used by Emacs.
+AC_DEFUN([gl_ASSERT_NO_GNULIB_POSIXCHECK],
+[
+ dnl Override gl_WARN_ON_USE_PREPARE.
+ dnl But hide this definition from 'aclocal'.
+ AC_DEFUN([gl_W][ARN_ON_USE_PREPARE], [])
+])
+
+# gl_ASSERT_NO_GNULIB_TESTS
+# asserts that there will be no gnulib tests in the scope of the configure.ac
+# and thereby enables an optimization of config.h.
+# Used by Emacs.
+AC_DEFUN([gl_ASSERT_NO_GNULIB_TESTS],
+[
+ dnl Override gl_MODULE_INDICATOR_FOR_TESTS.
+ AC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS], [])
+])
+
+# Test whether <features.h> exists.
+# Set HAVE_FEATURES_H.
+AC_DEFUN([gl_FEATURES_H],
+[
+ AC_CHECK_HEADERS_ONCE([features.h])
+ if test $ac_cv_header_features_h = yes; then
+ HAVE_FEATURES_H=1
+ else
+ HAVE_FEATURES_H=0
+ fi
+ AC_SUBST([HAVE_FEATURES_H])
+])
+
+# AS_VAR_IF(VAR, VALUE, [IF-MATCH], [IF-NOT-MATCH])
+# ----------------------------------------------------
+# Backport of autoconf-2.63b's macro.
+# Remove this macro when we can assume autoconf >= 2.64.
+m4_ifndef([AS_VAR_IF],
+[m4_define([AS_VAR_IF],
+[AS_IF([test x"AS_VAR_GET([$1])" = x""$2], [$3], [$4])])])
+
+# gl_PROG_CC_C99
+# Modifies the value of the shell variable CC in an attempt to make $CC
+# understand ISO C99 source code.
+# This is like AC_PROG_CC_C99, except that
+# - AC_PROG_CC_C99 does not mix well with AC_PROG_CC_STDC
+# <https://lists.gnu.org/r/bug-gnulib/2011-09/msg00367.html>,
+# but many more packages use AC_PROG_CC_STDC than AC_PROG_CC_C99
+# <https://lists.gnu.org/r/bug-gnulib/2011-09/msg00441.html>.
+# Remaining problems:
+# - When AC_PROG_CC_STDC is invoked twice, it adds the C99 enabling options
+# to CC twice
+# <https://lists.gnu.org/r/bug-gnulib/2011-09/msg00431.html>.
+# - AC_PROG_CC_STDC is likely to change now that C11 is an ISO standard.
+AC_DEFUN([gl_PROG_CC_C99],
+[
+ dnl Change that version number to the minimum Autoconf version that supports
+ dnl mixing AC_PROG_CC_C99 calls with AC_PROG_CC_STDC calls.
+ m4_version_prereq([9.0],
+ [AC_REQUIRE([AC_PROG_CC_C99])],
+ [AC_REQUIRE([AC_PROG_CC_STDC])])
+])
+
+# gl_PROG_AR_RANLIB
+# Determines the values for AR, ARFLAGS, RANLIB that fit with the compiler.
+# The user can set the variables AR, ARFLAGS, RANLIB if he wants to override
+# the values.
+AC_DEFUN([gl_PROG_AR_RANLIB],
+[
+ dnl Minix 3 comes with two toolchains: The Amsterdam Compiler Kit compiler
+ dnl as "cc", and GCC as "gcc". They have different object file formats and
+ dnl library formats. In particular, the GNU binutils programs ar and ranlib
+ dnl produce libraries that work only with gcc, not with cc.
+ AC_REQUIRE([AC_PROG_CC])
+ dnl The '][' hides this use from 'aclocal'.
+ AC_BEFORE([$0], [A][M_PROG_AR])
+ AC_CACHE_CHECK([for Minix Amsterdam compiler], [gl_cv_c_amsterdam_compiler],
+ [
+ AC_EGREP_CPP([Amsterdam],
+ [
+#ifdef __ACK__
+Amsterdam
+#endif
+ ],
+ [gl_cv_c_amsterdam_compiler=yes],
+ [gl_cv_c_amsterdam_compiler=no])
+ ])
+
+ dnl Don't compete with AM_PROG_AR's decision about AR/ARFLAGS if we are not
+ dnl building with __ACK__.
+ if test $gl_cv_c_amsterdam_compiler = yes; then
+ if test -z "$AR"; then
+ AR='cc -c.a'
+ fi
+ if test -z "$ARFLAGS"; then
+ ARFLAGS='-o'
+ fi
+ else
+ dnl AM_PROG_AR was added in automake v1.11.2. AM_PROG_AR does not AC_SUBST
+ dnl ARFLAGS variable (it is filed into Makefile.in directly by automake
+ dnl script on-demand, if not specified by ./configure of course).
+ dnl Don't AC_REQUIRE the AM_PROG_AR otherwise the code for __ACK__ above
+ dnl will be ignored. Also, pay attention to call AM_PROG_AR in else block
+ dnl because AM_PROG_AR is written so it could re-set AR variable even for
+ dnl __ACK__. It may seem like its easier to avoid calling the macro here,
+ dnl but we need to AC_SUBST both AR/ARFLAGS (thus those must have some good
+ dnl default value and automake should usually know them).
+ dnl
+ dnl The '][' hides this use from 'aclocal'.
+ m4_ifdef([A][M_PROG_AR], [A][M_PROG_AR], [:])
+ fi
+
+ dnl In case the code above has not helped with setting AR/ARFLAGS, use
+ dnl Automake-documented default values for AR and ARFLAGS, but prefer
+ dnl ${host}-ar over ar (useful for cross-compiling).
+ AC_CHECK_TOOL([AR], [ar], [ar])
+ if test -z "$ARFLAGS"; then
+ ARFLAGS='cr'
+ fi
+
+ AC_SUBST([AR])
+ AC_SUBST([ARFLAGS])
+ if test -z "$RANLIB"; then
+ if test $gl_cv_c_amsterdam_compiler = yes; then
+ RANLIB=':'
+ else
+ dnl Use the ranlib program if it is available.
+ AC_PROG_RANLIB
+ fi
+ fi
+ AC_SUBST([RANLIB])
+])
+
+# AC_C_RESTRICT
+# This definition is copied from post-2.69 Autoconf and overrides the
+# AC_C_RESTRICT macro from autoconf 2.60..2.69. It can be removed
+# once autoconf >= 2.70 can be assumed. It's painful to check version
+# numbers, and in practice this macro is more up-to-date than Autoconf
+# is, so override Autoconf unconditionally.
+AC_DEFUN([AC_C_RESTRICT],
+[AC_CACHE_CHECK([for C/C++ restrict keyword], [ac_cv_c_restrict],
+ [ac_cv_c_restrict=no
+ # The order here caters to the fact that C++ does not require restrict.
+ for ac_kw in __restrict __restrict__ _Restrict restrict; do
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[typedef int *int_ptr;
+ int foo (int_ptr $ac_kw ip) { return ip[0]; }
+ int bar (int [$ac_kw]); /* Catch GCC bug 14050. */
+ int bar (int ip[$ac_kw]) { return ip[0]; }
+ ]],
+ [[int s[1];
+ int *$ac_kw t = s;
+ t[0] = 0;
+ return foo (t) + bar (t);
+ ]])],
+ [ac_cv_c_restrict=$ac_kw])
+ test "$ac_cv_c_restrict" != no && break
+ done
+ ])
+ AH_VERBATIM([restrict],
+[/* Define to the equivalent of the C99 'restrict' keyword, or to
+ nothing if this is not supported. Do not define if restrict is
+ supported directly. */
+#undef restrict
+/* Work around a bug in Sun C++: it does not support _Restrict or
+ __restrict__, even though the corresponding Sun C compiler ends up with
+ "#define restrict _Restrict" or "#define restrict __restrict__" in the
+ previous line. Perhaps some future version of Sun C++ will work with
+ restrict; if so, hopefully it defines __RESTRICT like Sun C does. */
+#if defined __SUNPRO_CC && !defined __RESTRICT
+# define _Restrict
+# define __restrict__
+#endif])
+ case $ac_cv_c_restrict in
+ restrict) ;;
+ no) AC_DEFINE([restrict], []) ;;
+ *) AC_DEFINE_UNQUOTED([restrict], [$ac_cv_c_restrict]) ;;
+ esac
+])# AC_C_RESTRICT
+
+# gl_BIGENDIAN
+# is like AC_C_BIGENDIAN, except that it can be AC_REQUIREd.
+# Note that AC_REQUIRE([AC_C_BIGENDIAN]) does not work reliably because some
+# macros invoke AC_C_BIGENDIAN with arguments.
+AC_DEFUN([gl_BIGENDIAN],
+[
+ AC_C_BIGENDIAN
+])
+
+# gl_CACHE_VAL_SILENT(cache-id, command-to-set-it)
+# is like AC_CACHE_VAL(cache-id, command-to-set-it), except that it does not
+# output a spurious "(cached)" mark in the midst of other configure output.
+# This macro should be used instead of AC_CACHE_VAL when it is not surrounded
+# by an AC_MSG_CHECKING/AC_MSG_RESULT pair.
+AC_DEFUN([gl_CACHE_VAL_SILENT],
+[
+ saved_as_echo_n="$as_echo_n"
+ as_echo_n=':'
+ AC_CACHE_VAL([$1], [$2])
+ as_echo_n="$saved_as_echo_n"
+])
+
+# AS_VAR_COPY was added in autoconf 2.63b
+m4_define_default([AS_VAR_COPY],
+[AS_LITERAL_IF([$1[]$2], [$1=$$2], [eval $1=\$$2])])
diff --git a/gnulib/m4/gnulib-comp.m4 b/gnulib/m4/gnulib-comp.m4
new file mode 100644
index 0000000..a6cb962
--- /dev/null
+++ b/gnulib/m4/gnulib-comp.m4
@@ -0,0 +1,340 @@
+# DO NOT EDIT! GENERATED AUTOMATICALLY!
+# Copyright (C) 2002-2019 Free Software Foundation, Inc.
+#
+# 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
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This file is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this file. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License,
+# this file may be distributed as part of a program that
+# contains a configuration script generated by Autoconf, under
+# the same distribution terms as the rest of that program.
+#
+# Generated by gnulib-tool.
+#
+# This file represents the compiled summary of the specification in
+# gnulib-cache.m4. It lists the computed macro invocations that need
+# to be invoked from configure.ac.
+# In projects that use version control, this file can be treated like
+# other built files.
+
+
+# This macro should be invoked from ./configure.ac, in the section
+# "Checks for programs", right after AC_PROG_CC, and certainly before
+# any checks for libraries, header files, types and library functions.
+AC_DEFUN([gl_EARLY],
+[
+ m4_pattern_forbid([^gl_[A-Z]])dnl the gnulib macro namespace
+ m4_pattern_allow([^gl_ES$])dnl a valid locale name
+ m4_pattern_allow([^gl_LIBOBJS$])dnl a variable
+ m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable
+
+ # Pre-early section.
+ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+ AC_REQUIRE([gl_PROG_AR_RANLIB])
+
+ # Code from module absolute-header:
+ # Code from module alloca-opt:
+ # Code from module dirent:
+ # Code from module environ:
+ # Code from module extensions:
+ # Code from module extern-inline:
+ # Code from module include_next:
+ # Code from module lib-msvc-compat:
+ # Code from module limits-h:
+ # Code from module malloc-gnu:
+ # Code from module malloc-posix:
+ # Code from module malloca:
+ # Code from module manywarnings:
+ # Code from module multiarch:
+ # Code from module realloc-gnu:
+ # Code from module realloc-posix:
+ # Code from module setenv:
+ # Code from module snippet/_Noreturn:
+ # Code from module snippet/arg-nonnull:
+ # Code from module snippet/c++defs:
+ # Code from module snippet/warn-on-use:
+ # Code from module ssize_t:
+ # Code from module stddef:
+ # Code from module stdint:
+ # Code from module stdlib:
+ # Code from module string:
+ # Code from module strndup:
+ # Code from module strnlen:
+ # Code from module sys_types:
+ # Code from module unistd:
+ # Code from module verify:
+ # Code from module warnings:
+ # Code from module xalloc-oversized:
+])
+
+# This macro should be invoked from ./configure.ac, in the section
+# "Check for header files, types and library functions".
+AC_DEFUN([gl_INIT],
+[
+ AM_CONDITIONAL([GL_COND_LIBTOOL], [true])
+ gl_cond_libtool=true
+ gl_m4_base='gnulib/m4'
+ m4_pushdef([AC_LIBOBJ], m4_defn([gl_LIBOBJ]))
+ m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gl_REPLACE_FUNCS]))
+ m4_pushdef([AC_LIBSOURCES], m4_defn([gl_LIBSOURCES]))
+ m4_pushdef([gl_LIBSOURCES_LIST], [])
+ m4_pushdef([gl_LIBSOURCES_DIR], [])
+ gl_COMMON
+ gl_source_base='gnulib'
+ gl_FUNC_ALLOCA
+ gl_DIRENT_H
+ gl_ENVIRON
+ gl_UNISTD_MODULE_INDICATOR([environ])
+ AC_REQUIRE([gl_EXTERN_INLINE])
+ gl_LD_OUTPUT_DEF
+ gl_LIMITS_H
+ gl_FUNC_MALLOC_GNU
+ if test $REPLACE_MALLOC = 1; then
+ AC_LIBOBJ([malloc])
+ fi
+ gl_MODULE_INDICATOR([malloc-gnu])
+ gl_FUNC_MALLOC_POSIX
+ if test $REPLACE_MALLOC = 1; then
+ AC_LIBOBJ([malloc])
+ fi
+ gl_STDLIB_MODULE_INDICATOR([malloc-posix])
+ gl_MALLOCA
+ gl_MULTIARCH
+ gl_FUNC_REALLOC_GNU
+ if test $REPLACE_REALLOC = 1; then
+ AC_LIBOBJ([realloc])
+ fi
+ gl_MODULE_INDICATOR([realloc-gnu])
+ gl_FUNC_REALLOC_POSIX
+ if test $REPLACE_REALLOC = 1; then
+ AC_LIBOBJ([realloc])
+ fi
+ gl_STDLIB_MODULE_INDICATOR([realloc-posix])
+ gl_FUNC_SETENV
+ if test $HAVE_SETENV = 0 || test $REPLACE_SETENV = 1; then
+ AC_LIBOBJ([setenv])
+ fi
+ gl_STDLIB_MODULE_INDICATOR([setenv])
+ gt_TYPE_SSIZE_T
+ gl_STDDEF_H
+ gl_STDINT_H
+ gl_STDLIB_H
+ gl_HEADER_STRING_H
+ gl_FUNC_STRNDUP
+ if test $HAVE_STRNDUP = 0 || test $REPLACE_STRNDUP = 1; then
+ AC_LIBOBJ([strndup])
+ fi
+ gl_STRING_MODULE_INDICATOR([strndup])
+ gl_FUNC_STRNLEN
+ if test $HAVE_DECL_STRNLEN = 0 || test $REPLACE_STRNLEN = 1; then
+ AC_LIBOBJ([strnlen])
+ gl_PREREQ_STRNLEN
+ fi
+ gl_STRING_MODULE_INDICATOR([strnlen])
+ gl_SYS_TYPES_H
+ AC_PROG_MKDIR_P
+ gl_UNISTD_H
+ # End of code from modules
+ m4_ifval(gl_LIBSOURCES_LIST, [
+ m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ ||
+ for gl_file in ]gl_LIBSOURCES_LIST[ ; do
+ if test ! -r ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file ; then
+ echo "missing file ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file" >&2
+ exit 1
+ fi
+ done])dnl
+ m4_if(m4_sysval, [0], [],
+ [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])])
+ ])
+ m4_popdef([gl_LIBSOURCES_DIR])
+ m4_popdef([gl_LIBSOURCES_LIST])
+ m4_popdef([AC_LIBSOURCES])
+ m4_popdef([AC_REPLACE_FUNCS])
+ m4_popdef([AC_LIBOBJ])
+ AC_CONFIG_COMMANDS_PRE([
+ gl_libobjs=
+ gl_ltlibobjs=
+ if test -n "$gl_LIBOBJS"; then
+ # Remove the extension.
+ sed_drop_objext='s/\.o$//;s/\.obj$//'
+ for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do
+ gl_libobjs="$gl_libobjs $i.$ac_objext"
+ gl_ltlibobjs="$gl_ltlibobjs $i.lo"
+ done
+ fi
+ AC_SUBST([gl_LIBOBJS], [$gl_libobjs])
+ AC_SUBST([gl_LTLIBOBJS], [$gl_ltlibobjs])
+ ])
+ gltests_libdeps=
+ gltests_ltlibdeps=
+ m4_pushdef([AC_LIBOBJ], m4_defn([gltests_LIBOBJ]))
+ m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gltests_REPLACE_FUNCS]))
+ m4_pushdef([AC_LIBSOURCES], m4_defn([gltests_LIBSOURCES]))
+ m4_pushdef([gltests_LIBSOURCES_LIST], [])
+ m4_pushdef([gltests_LIBSOURCES_DIR], [])
+ gl_COMMON
+ gl_source_base='tests'
+changequote(,)dnl
+ gltests_WITNESS=IN_`echo "${PACKAGE-$PACKAGE_TARNAME}" | LC_ALL=C tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | LC_ALL=C sed -e 's/[^A-Z0-9_]/_/g'`_GNULIB_TESTS
+changequote([, ])dnl
+ AC_SUBST([gltests_WITNESS])
+ gl_module_indicator_condition=$gltests_WITNESS
+ m4_pushdef([gl_MODULE_INDICATOR_CONDITION], [$gl_module_indicator_condition])
+ m4_popdef([gl_MODULE_INDICATOR_CONDITION])
+ m4_ifval(gltests_LIBSOURCES_LIST, [
+ m4_syscmd([test ! -d ]m4_defn([gltests_LIBSOURCES_DIR])[ ||
+ for gl_file in ]gltests_LIBSOURCES_LIST[ ; do
+ if test ! -r ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file ; then
+ echo "missing file ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file" >&2
+ exit 1
+ fi
+ done])dnl
+ m4_if(m4_sysval, [0], [],
+ [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])])
+ ])
+ m4_popdef([gltests_LIBSOURCES_DIR])
+ m4_popdef([gltests_LIBSOURCES_LIST])
+ m4_popdef([AC_LIBSOURCES])
+ m4_popdef([AC_REPLACE_FUNCS])
+ m4_popdef([AC_LIBOBJ])
+ AC_CONFIG_COMMANDS_PRE([
+ gltests_libobjs=
+ gltests_ltlibobjs=
+ if test -n "$gltests_LIBOBJS"; then
+ # Remove the extension.
+ sed_drop_objext='s/\.o$//;s/\.obj$//'
+ for i in `for i in $gltests_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do
+ gltests_libobjs="$gltests_libobjs $i.$ac_objext"
+ gltests_ltlibobjs="$gltests_ltlibobjs $i.lo"
+ done
+ fi
+ AC_SUBST([gltests_LIBOBJS], [$gltests_libobjs])
+ AC_SUBST([gltests_LTLIBOBJS], [$gltests_ltlibobjs])
+ ])
+])
+
+# Like AC_LIBOBJ, except that the module name goes
+# into gl_LIBOBJS instead of into LIBOBJS.
+AC_DEFUN([gl_LIBOBJ], [
+ AS_LITERAL_IF([$1], [gl_LIBSOURCES([$1.c])])dnl
+ gl_LIBOBJS="$gl_LIBOBJS $1.$ac_objext"
+])
+
+# Like AC_REPLACE_FUNCS, except that the module name goes
+# into gl_LIBOBJS instead of into LIBOBJS.
+AC_DEFUN([gl_REPLACE_FUNCS], [
+ m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl
+ AC_CHECK_FUNCS([$1], , [gl_LIBOBJ($ac_func)])
+])
+
+# Like AC_LIBSOURCES, except the directory where the source file is
+# expected is derived from the gnulib-tool parameterization,
+# and alloca is special cased (for the alloca-opt module).
+# We could also entirely rely on EXTRA_lib..._SOURCES.
+AC_DEFUN([gl_LIBSOURCES], [
+ m4_foreach([_gl_NAME], [$1], [
+ m4_if(_gl_NAME, [alloca.c], [], [
+ m4_define([gl_LIBSOURCES_DIR], [gnulib])
+ m4_append([gl_LIBSOURCES_LIST], _gl_NAME, [ ])
+ ])
+ ])
+])
+
+# Like AC_LIBOBJ, except that the module name goes
+# into gltests_LIBOBJS instead of into LIBOBJS.
+AC_DEFUN([gltests_LIBOBJ], [
+ AS_LITERAL_IF([$1], [gltests_LIBSOURCES([$1.c])])dnl
+ gltests_LIBOBJS="$gltests_LIBOBJS $1.$ac_objext"
+])
+
+# Like AC_REPLACE_FUNCS, except that the module name goes
+# into gltests_LIBOBJS instead of into LIBOBJS.
+AC_DEFUN([gltests_REPLACE_FUNCS], [
+ m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl
+ AC_CHECK_FUNCS([$1], , [gltests_LIBOBJ($ac_func)])
+])
+
+# Like AC_LIBSOURCES, except the directory where the source file is
+# expected is derived from the gnulib-tool parameterization,
+# and alloca is special cased (for the alloca-opt module).
+# We could also entirely rely on EXTRA_lib..._SOURCES.
+AC_DEFUN([gltests_LIBSOURCES], [
+ m4_foreach([_gl_NAME], [$1], [
+ m4_if(_gl_NAME, [alloca.c], [], [
+ m4_define([gltests_LIBSOURCES_DIR], [tests])
+ m4_append([gltests_LIBSOURCES_LIST], _gl_NAME, [ ])
+ ])
+ ])
+])
+
+# This macro records the list of files which have been installed by
+# gnulib-tool and may be removed by future gnulib-tool invocations.
+AC_DEFUN([gl_FILE_LIST], [
+ lib/_Noreturn.h
+ lib/alloca.in.h
+ lib/arg-nonnull.h
+ lib/c++defs.h
+ lib/dirent.in.h
+ lib/limits.in.h
+ lib/malloc.c
+ lib/malloca.c
+ lib/malloca.h
+ lib/realloc.c
+ lib/setenv.c
+ lib/stddef.in.h
+ lib/stdint.in.h
+ lib/stdlib.in.h
+ lib/string.in.h
+ lib/strndup.c
+ lib/strnlen.c
+ lib/sys_types.in.h
+ lib/unistd.c
+ lib/unistd.in.h
+ lib/verify.h
+ lib/warn-on-use.h
+ lib/xalloc-oversized.h
+ m4/00gnulib.m4
+ m4/absolute-header.m4
+ m4/alloca.m4
+ m4/dirent_h.m4
+ m4/eealloc.m4
+ m4/environ.m4
+ m4/extensions.m4
+ m4/extern-inline.m4
+ m4/gnulib-common.m4
+ m4/include_next.m4
+ m4/ld-output-def.m4
+ m4/limits-h.m4
+ m4/longlong.m4
+ m4/malloc.m4
+ m4/malloca.m4
+ m4/manywarnings-c++.m4
+ m4/manywarnings.m4
+ m4/multiarch.m4
+ m4/off_t.m4
+ m4/realloc.m4
+ m4/setenv.m4
+ m4/ssize_t.m4
+ m4/stddef_h.m4
+ m4/stdint.m4
+ m4/stdlib_h.m4
+ m4/string_h.m4
+ m4/strndup.m4
+ m4/strnlen.m4
+ m4/sys_types_h.m4
+ m4/unistd_h.m4
+ m4/warn-on-use.m4
+ m4/warnings.m4
+ m4/wchar_t.m4
+ m4/wint_t.m4
+])
diff --git a/gnulib/m4/gnulib-tool.m4 b/gnulib/m4/gnulib-tool.m4
new file mode 100644
index 0000000..98e6ade
--- /dev/null
+++ b/gnulib/m4/gnulib-tool.m4
@@ -0,0 +1,57 @@
+# gnulib-tool.m4 serial 2
+dnl Copyright (C) 2004-2005, 2009-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl The following macros need not be invoked explicitly.
+dnl Invoking them does nothing except to declare default arguments
+dnl for "gnulib-tool --import".
+
+dnl Usage: gl_LOCAL_DIR([DIR])
+AC_DEFUN([gl_LOCAL_DIR], [])
+
+dnl Usage: gl_MODULES([module1 module2 ...])
+AC_DEFUN([gl_MODULES], [])
+
+dnl Usage: gl_AVOID([module1 module2 ...])
+AC_DEFUN([gl_AVOID], [])
+
+dnl Usage: gl_SOURCE_BASE([DIR])
+AC_DEFUN([gl_SOURCE_BASE], [])
+
+dnl Usage: gl_M4_BASE([DIR])
+AC_DEFUN([gl_M4_BASE], [])
+
+dnl Usage: gl_PO_BASE([DIR])
+AC_DEFUN([gl_PO_BASE], [])
+
+dnl Usage: gl_DOC_BASE([DIR])
+AC_DEFUN([gl_DOC_BASE], [])
+
+dnl Usage: gl_TESTS_BASE([DIR])
+AC_DEFUN([gl_TESTS_BASE], [])
+
+dnl Usage: gl_WITH_TESTS
+AC_DEFUN([gl_WITH_TESTS], [])
+
+dnl Usage: gl_LIB([LIBNAME])
+AC_DEFUN([gl_LIB], [])
+
+dnl Usage: gl_LGPL or gl_LGPL([VERSION])
+AC_DEFUN([gl_LGPL], [])
+
+dnl Usage: gl_MAKEFILE_NAME([FILENAME])
+AC_DEFUN([gl_MAKEFILE_NAME], [])
+
+dnl Usage: gl_LIBTOOL
+AC_DEFUN([gl_LIBTOOL], [])
+
+dnl Usage: gl_MACRO_PREFIX([PREFIX])
+AC_DEFUN([gl_MACRO_PREFIX], [])
+
+dnl Usage: gl_PO_DOMAIN([DOMAIN])
+AC_DEFUN([gl_PO_DOMAIN], [])
+
+dnl Usage: gl_VC_FILES([BOOLEAN])
+AC_DEFUN([gl_VC_FILES], [])
diff --git a/gnulib/m4/include_next.m4 b/gnulib/m4/include_next.m4
new file mode 100644
index 0000000..86eb2c9
--- /dev/null
+++ b/gnulib/m4/include_next.m4
@@ -0,0 +1,224 @@
+# include_next.m4 serial 24
+dnl Copyright (C) 2006-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert and Derek Price.
+
+dnl Sets INCLUDE_NEXT, INCLUDE_NEXT_AS_FIRST_DIRECTIVE, PRAGMA_SYSTEM_HEADER,
+dnl and PRAGMA_COLUMNS.
+dnl
+dnl INCLUDE_NEXT expands to 'include_next' if the compiler supports it, or to
+dnl 'include' otherwise.
+dnl
+dnl INCLUDE_NEXT_AS_FIRST_DIRECTIVE expands to 'include_next' if the compiler
+dnl supports it in the special case that it is the first include directive in
+dnl the given file, or to 'include' otherwise.
+dnl
+dnl PRAGMA_SYSTEM_HEADER can be used in files that contain #include_next,
+dnl so as to avoid GCC warnings when the gcc option -pedantic is used.
+dnl '#pragma GCC system_header' has the same effect as if the file was found
+dnl through the include search path specified with '-isystem' options (as
+dnl opposed to the search path specified with '-I' options). Namely, gcc
+dnl does not warn about some things, and on some systems (Solaris and Interix)
+dnl __STDC__ evaluates to 0 instead of to 1. The latter is an undesired side
+dnl effect; we are therefore careful to use 'defined __STDC__' or '1' instead
+dnl of plain '__STDC__'.
+dnl
+dnl PRAGMA_COLUMNS can be used in files that override system header files, so
+dnl as to avoid compilation errors on HP NonStop systems when the gnulib file
+dnl is included by a system header file that does a "#pragma COLUMNS 80" (which
+dnl has the effect of truncating the lines of that file and all files that it
+dnl includes to 80 columns) and the gnulib file has lines longer than 80
+dnl columns.
+
+AC_DEFUN([gl_INCLUDE_NEXT],
+[
+ AC_LANG_PREPROC_REQUIRE()
+ AC_CACHE_CHECK([whether the preprocessor supports include_next],
+ [gl_cv_have_include_next],
+ [rm -rf conftestd1a conftestd1b conftestd2
+ mkdir conftestd1a conftestd1b conftestd2
+ dnl IBM C 9.0, 10.1 (original versions, prior to the 2009-01 updates) on
+ dnl AIX 6.1 support include_next when used as first preprocessor directive
+ dnl in a file, but not when preceded by another include directive. Check
+ dnl for this bug by including <stdio.h>.
+ dnl Additionally, with this same compiler, include_next is a no-op when
+ dnl used in a header file that was included by specifying its absolute
+ dnl file name. Despite these two bugs, include_next is used in the
+ dnl compiler's <math.h>. By virtue of the second bug, we need to use
+ dnl include_next as well in this case.
+ cat <<EOF > conftestd1a/conftest.h
+#define DEFINED_IN_CONFTESTD1
+#include_next <conftest.h>
+#ifdef DEFINED_IN_CONFTESTD2
+int foo;
+#else
+#error "include_next doesn't work"
+#endif
+EOF
+ cat <<EOF > conftestd1b/conftest.h
+#define DEFINED_IN_CONFTESTD1
+#include <stdio.h>
+#include_next <conftest.h>
+#ifdef DEFINED_IN_CONFTESTD2
+int foo;
+#else
+#error "include_next doesn't work"
+#endif
+EOF
+ cat <<EOF > conftestd2/conftest.h
+#ifndef DEFINED_IN_CONFTESTD1
+#error "include_next test doesn't work"
+#endif
+#define DEFINED_IN_CONFTESTD2
+EOF
+ gl_save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1b -Iconftestd2"
+dnl We intentionally avoid using AC_LANG_SOURCE here.
+ AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[#include <conftest.h>]],
+ [gl_cv_have_include_next=yes],
+ [CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1a -Iconftestd2"
+ AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[#include <conftest.h>]],
+ [gl_cv_have_include_next=buggy],
+ [gl_cv_have_include_next=no])
+ ])
+ CPPFLAGS="$gl_save_CPPFLAGS"
+ rm -rf conftestd1a conftestd1b conftestd2
+ ])
+ PRAGMA_SYSTEM_HEADER=
+ if test $gl_cv_have_include_next = yes; then
+ INCLUDE_NEXT=include_next
+ INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next
+ if test -n "$GCC"; then
+ PRAGMA_SYSTEM_HEADER='#pragma GCC system_header'
+ fi
+ else
+ if test $gl_cv_have_include_next = buggy; then
+ INCLUDE_NEXT=include
+ INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next
+ else
+ INCLUDE_NEXT=include
+ INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include
+ fi
+ fi
+ AC_SUBST([INCLUDE_NEXT])
+ AC_SUBST([INCLUDE_NEXT_AS_FIRST_DIRECTIVE])
+ AC_SUBST([PRAGMA_SYSTEM_HEADER])
+ AC_CACHE_CHECK([whether system header files limit the line length],
+ [gl_cv_pragma_columns],
+ [dnl HP NonStop systems, which define __TANDEM, have this misfeature.
+ AC_EGREP_CPP([choke me],
+ [
+#ifdef __TANDEM
+choke me
+#endif
+ ],
+ [gl_cv_pragma_columns=yes],
+ [gl_cv_pragma_columns=no])
+ ])
+ if test $gl_cv_pragma_columns = yes; then
+ PRAGMA_COLUMNS="#pragma COLUMNS 10000"
+ else
+ PRAGMA_COLUMNS=
+ fi
+ AC_SUBST([PRAGMA_COLUMNS])
+])
+
+# gl_CHECK_NEXT_HEADERS(HEADER1 HEADER2 ...)
+# ------------------------------------------
+# For each arg foo.h, if #include_next works, define NEXT_FOO_H to be
+# '<foo.h>'; otherwise define it to be
+# '"///usr/include/foo.h"', or whatever other absolute file name is suitable.
+# Also, if #include_next works as first preprocessing directive in a file,
+# define NEXT_AS_FIRST_DIRECTIVE_FOO_H to be '<foo.h>'; otherwise define it to
+# be
+# '"///usr/include/foo.h"', or whatever other absolute file name is suitable.
+# That way, a header file with the following line:
+# #@INCLUDE_NEXT@ @NEXT_FOO_H@
+# or
+# #@INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ @NEXT_AS_FIRST_DIRECTIVE_FOO_H@
+# behaves (after sed substitution) as if it contained
+# #include_next <foo.h>
+# even if the compiler does not support include_next.
+# The three "///" are to pacify Sun C 5.8, which otherwise would say
+# "warning: #include of /usr/include/... may be non-portable".
+# Use '""', not '<>', so that the /// cannot be confused with a C99 comment.
+# Note: This macro assumes that the header file is not empty after
+# preprocessing, i.e. it does not only define preprocessor macros but also
+# provides some type/enum definitions or function/variable declarations.
+#
+# This macro also checks whether each header exists, by invoking
+# AC_CHECK_HEADERS_ONCE or AC_CHECK_HEADERS on each argument.
+AC_DEFUN([gl_CHECK_NEXT_HEADERS],
+[
+ gl_NEXT_HEADERS_INTERNAL([$1], [check])
+])
+
+# gl_NEXT_HEADERS(HEADER1 HEADER2 ...)
+# ------------------------------------
+# Like gl_CHECK_NEXT_HEADERS, except do not check whether the headers exist.
+# This is suitable for headers like <stddef.h> that are standardized by C89
+# and therefore can be assumed to exist.
+AC_DEFUN([gl_NEXT_HEADERS],
+[
+ gl_NEXT_HEADERS_INTERNAL([$1], [assume])
+])
+
+# The guts of gl_CHECK_NEXT_HEADERS and gl_NEXT_HEADERS.
+AC_DEFUN([gl_NEXT_HEADERS_INTERNAL],
+[
+ AC_REQUIRE([gl_INCLUDE_NEXT])
+ AC_REQUIRE([AC_CANONICAL_HOST])
+
+ m4_if([$2], [check],
+ [AC_CHECK_HEADERS_ONCE([$1])
+ ])
+
+dnl FIXME: gl_next_header and gl_header_exists must be used unquoted
+dnl until we can assume autoconf 2.64 or newer.
+ m4_foreach_w([gl_HEADER_NAME], [$1],
+ [AS_VAR_PUSHDEF([gl_next_header],
+ [gl_cv_next_]m4_defn([gl_HEADER_NAME]))
+ if test $gl_cv_have_include_next = yes; then
+ AS_VAR_SET(gl_next_header, ['<'gl_HEADER_NAME'>'])
+ else
+ AC_CACHE_CHECK(
+ [absolute name of <]m4_defn([gl_HEADER_NAME])[>],
+ m4_defn([gl_next_header]),
+ [m4_if([$2], [check],
+ [AS_VAR_PUSHDEF([gl_header_exists],
+ [ac_cv_header_]m4_defn([gl_HEADER_NAME]))
+ if test AS_VAR_GET(gl_header_exists) = yes; then
+ AS_VAR_POPDEF([gl_header_exists])
+ ])
+ gl_ABSOLUTE_HEADER_ONE(gl_HEADER_NAME)
+ AS_VAR_COPY([gl_header], [gl_cv_absolute_]AS_TR_SH(gl_HEADER_NAME))
+ AS_VAR_SET(gl_next_header, ['"'$gl_header'"'])
+ m4_if([$2], [check],
+ [else
+ AS_VAR_SET(gl_next_header, ['<'gl_HEADER_NAME'>'])
+ fi
+ ])
+ ])
+ fi
+ AC_SUBST(
+ AS_TR_CPP([NEXT_]m4_defn([gl_HEADER_NAME])),
+ [AS_VAR_GET(gl_next_header)])
+ if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then
+ # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next'
+ gl_next_as_first_directive='<'gl_HEADER_NAME'>'
+ else
+ # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
+ gl_next_as_first_directive=AS_VAR_GET(gl_next_header)
+ fi
+ AC_SUBST(
+ AS_TR_CPP([NEXT_AS_FIRST_DIRECTIVE_]m4_defn([gl_HEADER_NAME])),
+ [$gl_next_as_first_directive])
+ AS_VAR_POPDEF([gl_next_header])])
+])
+
+# Autoconf 2.68 added warnings for our use of AC_COMPILE_IFELSE;
+# this fallback is safe for all earlier autoconf versions.
+m4_define_default([AC_LANG_DEFINES_PROVIDED])
diff --git a/gnulib/m4/ld-output-def.m4 b/gnulib/m4/ld-output-def.m4
new file mode 100644
index 0000000..acf5788
--- /dev/null
+++ b/gnulib/m4/ld-output-def.m4
@@ -0,0 +1,29 @@
+# ld-output-def.m4 serial 2
+dnl Copyright (C) 2008-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Simon Josefsson
+
+# gl_LD_OUTPUT_DEF()
+# -------------
+# Check if linker supports -Wl,--output-def and define automake
+# conditional HAVE_LD_OUTPUT_DEF if it is.
+AC_DEFUN([gl_LD_OUTPUT_DEF],
+[
+ AC_CACHE_CHECK([if gcc/ld supports -Wl,--output-def],
+ [gl_cv_ld_output_def],
+ [if test "$enable_shared" = no; then
+ gl_cv_ld_output_def="not needed, shared libraries are disabled"
+ else
+ gl_ldflags_save=$LDFLAGS
+ LDFLAGS="-Wl,--output-def,conftest.def"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([])],
+ [gl_cv_ld_output_def=yes],
+ [gl_cv_ld_output_def=no])
+ rm -f conftest.def
+ LDFLAGS="$gl_ldflags_save"
+ fi])
+ AM_CONDITIONAL([HAVE_LD_OUTPUT_DEF], test "x$gl_cv_ld_output_def" = "xyes")
+])
diff --git a/gnulib/m4/limits-h.m4 b/gnulib/m4/limits-h.m4
new file mode 100644
index 0000000..68f724c
--- /dev/null
+++ b/gnulib/m4/limits-h.m4
@@ -0,0 +1,43 @@
+dnl Check whether limits.h has needed features.
+
+dnl Copyright 2016-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+AC_DEFUN_ONCE([gl_LIMITS_H],
+[
+ gl_CHECK_NEXT_HEADERS([limits.h])
+
+ AC_CACHE_CHECK([whether limits.h has LLONG_MAX, WORD_BIT, ULLONG_WIDTH etc.],
+ [gl_cv_header_limits_width],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+ #define __STDC_WANT_IEC_60559_BFP_EXT__ 1
+ #endif
+ #include <limits.h>
+ long long llm = LLONG_MAX;
+ int wb = WORD_BIT;
+ int ullw = ULLONG_WIDTH;
+ ]])],
+ [gl_cv_header_limits_width=yes],
+ [gl_cv_header_limits_width=no])])
+ if test "$gl_cv_header_limits_width" = yes; then
+ LIMITS_H=
+ else
+ LIMITS_H=limits.h
+ fi
+ AC_SUBST([LIMITS_H])
+ AM_CONDITIONAL([GL_GENERATE_LIMITS_H], [test -n "$LIMITS_H"])
+])
+
+dnl Unconditionally enables the replacement of <limits.h>.
+AC_DEFUN([gl_REPLACE_LIMITS_H],
+[
+ AC_REQUIRE([gl_LIMITS_H])
+ LIMITS_H='limits.h'
+ AM_CONDITIONAL([GL_GENERATE_LIMITS_H], [test -n "$LIMITS_H"])
+])
diff --git a/gnulib/m4/longlong.m4 b/gnulib/m4/longlong.m4
new file mode 100644
index 0000000..08d0e36
--- /dev/null
+++ b/gnulib/m4/longlong.m4
@@ -0,0 +1,113 @@
+# longlong.m4 serial 18
+dnl Copyright (C) 1999-2007, 2009-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+AC_PREREQ([2.62])
+
+# Define HAVE_LONG_LONG_INT if 'long long int' works.
+# This can be faster than what's in Autoconf 2.62 through 2.68.
+
+# Note: If the type 'long long int' exists but is only 32 bits large
+# (as on some very old compilers), HAVE_LONG_LONG_INT will not be
+# defined. In this case you can treat 'long long int' like 'long int'.
+
+AC_DEFUN([AC_TYPE_LONG_LONG_INT],
+[
+ AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT])
+ AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int],
+ [ac_cv_type_long_long_int=yes
+ if test "x${ac_cv_prog_cc_c99-no}" = xno; then
+ ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int
+ if test $ac_cv_type_long_long_int = yes; then
+ dnl Catch a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004.
+ dnl If cross compiling, assume the bug is not important, since
+ dnl nobody cross compiles for this platform as far as we know.
+ AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[@%:@include <limits.h>
+ @%:@ifndef LLONG_MAX
+ @%:@ define HALF \
+ (1LL << (sizeof (long long int) * CHAR_BIT - 2))
+ @%:@ define LLONG_MAX (HALF - 1 + HALF)
+ @%:@endif]],
+ [[long long int n = 1;
+ int i;
+ for (i = 0; ; i++)
+ {
+ long long int m = n << i;
+ if (m >> i != n)
+ return 1;
+ if (LLONG_MAX / 2 < m)
+ break;
+ }
+ return 0;]])],
+ [],
+ [ac_cv_type_long_long_int=no],
+ [:])
+ fi
+ fi])
+ if test $ac_cv_type_long_long_int = yes; then
+ AC_DEFINE([HAVE_LONG_LONG_INT], [1],
+ [Define to 1 if the system has the type 'long long int'.])
+ fi
+])
+
+# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works.
+# This can be faster than what's in Autoconf 2.62 through 2.68.
+
+# Note: If the type 'unsigned long long int' exists but is only 32 bits
+# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT
+# will not be defined. In this case you can treat 'unsigned long long int'
+# like 'unsigned long int'.
+
+AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT],
+[
+ AC_CACHE_CHECK([for unsigned long long int],
+ [ac_cv_type_unsigned_long_long_int],
+ [ac_cv_type_unsigned_long_long_int=yes
+ if test "x${ac_cv_prog_cc_c99-no}" = xno; then
+ AC_LINK_IFELSE(
+ [_AC_TYPE_LONG_LONG_SNIPPET],
+ [],
+ [ac_cv_type_unsigned_long_long_int=no])
+ fi])
+ if test $ac_cv_type_unsigned_long_long_int = yes; then
+ AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1],
+ [Define to 1 if the system has the type 'unsigned long long int'.])
+ fi
+])
+
+# Expands to a C program that can be used to test for simultaneous support
+# of 'long long' and 'unsigned long long'. We don't want to say that
+# 'long long' is available if 'unsigned long long' is not, or vice versa,
+# because too many programs rely on the symmetry between signed and unsigned
+# integer types (excluding 'bool').
+AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET],
+[
+ AC_LANG_PROGRAM(
+ [[/* For now, do not test the preprocessor; as of 2007 there are too many
+ implementations with broken preprocessors. Perhaps this can
+ be revisited in 2012. In the meantime, code should not expect
+ #if to work with literals wider than 32 bits. */
+ /* Test literals. */
+ long long int ll = 9223372036854775807ll;
+ long long int nll = -9223372036854775807LL;
+ unsigned long long int ull = 18446744073709551615ULL;
+ /* Test constant expressions. */
+ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+ ? 1 : -1)];
+ typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
+ ? 1 : -1)];
+ int i = 63;]],
+ [[/* Test availability of runtime routines for shift and division. */
+ long long int llmax = 9223372036854775807ll;
+ unsigned long long int ullmax = 18446744073709551615ull;
+ return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
+ | (llmax / ll) | (llmax % ll)
+ | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+ | (ullmax / ull) | (ullmax % ull));]])
+])
diff --git a/gnulib/m4/malloc.m4 b/gnulib/m4/malloc.m4
new file mode 100644
index 0000000..c469c45
--- /dev/null
+++ b/gnulib/m4/malloc.m4
@@ -0,0 +1,108 @@
+# malloc.m4 serial 19
+dnl Copyright (C) 2007, 2009-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+m4_version_prereq([2.70], [] ,[
+
+# This is adapted with modifications from upstream Autoconf here:
+# https://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=04be2b7a29d65d9a08e64e8e56e594c91749598c
+AC_DEFUN([_AC_FUNC_MALLOC_IF],
+[
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
+ AC_CHECK_HEADERS([stdlib.h])
+ AC_CACHE_CHECK([for GNU libc compatible malloc],
+ [ac_cv_func_malloc_0_nonnull],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#if defined STDC_HEADERS || defined HAVE_STDLIB_H
+ # include <stdlib.h>
+ #else
+ char *malloc ();
+ #endif
+ ]],
+ [[char *p = malloc (0);
+ int result = !p;
+ free (p);
+ return result;]])
+ ],
+ [ac_cv_func_malloc_0_nonnull=yes],
+ [ac_cv_func_malloc_0_nonnull=no],
+ [case "$host_os" in
+ # Guess yes on platforms where we know the result.
+ *-gnu* | gnu* | *-musl* | freebsd* | netbsd* | openbsd* \
+ | hpux* | solaris* | cygwin* | mingw*)
+ ac_cv_func_malloc_0_nonnull="guessing yes" ;;
+ # If we don't know, assume the worst.
+ *) ac_cv_func_malloc_0_nonnull="guessing no" ;;
+ esac
+ ])
+ ])
+ case "$ac_cv_func_malloc_0_nonnull" in
+ *yes)
+ $1
+ ;;
+ *)
+ $2
+ ;;
+ esac
+])# _AC_FUNC_MALLOC_IF
+
+])
+
+# gl_FUNC_MALLOC_GNU
+# ------------------
+# Test whether 'malloc (0)' is handled like in GNU libc, and replace malloc if
+# it is not.
+AC_DEFUN([gl_FUNC_MALLOC_GNU],
+[
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ dnl _AC_FUNC_MALLOC_IF is defined in Autoconf.
+ _AC_FUNC_MALLOC_IF(
+ [AC_DEFINE([HAVE_MALLOC_GNU], [1],
+ [Define to 1 if your system has a GNU libc compatible 'malloc'
+ function, and to 0 otherwise.])],
+ [AC_DEFINE([HAVE_MALLOC_GNU], [0])
+ REPLACE_MALLOC=1
+ ])
+])
+
+# gl_FUNC_MALLOC_POSIX
+# --------------------
+# Test whether 'malloc' is POSIX compliant (sets errno to ENOMEM when it
+# fails), and replace malloc if it is not.
+AC_DEFUN([gl_FUNC_MALLOC_POSIX],
+[
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_REQUIRE([gl_CHECK_MALLOC_POSIX])
+ if test $gl_cv_func_malloc_posix = yes; then
+ AC_DEFINE([HAVE_MALLOC_POSIX], [1],
+ [Define if the 'malloc' function is POSIX compliant.])
+ else
+ REPLACE_MALLOC=1
+ fi
+])
+
+# Test whether malloc, realloc, calloc are POSIX compliant,
+# Set gl_cv_func_malloc_posix to yes or no accordingly.
+AC_DEFUN([gl_CHECK_MALLOC_POSIX],
+[
+ AC_CACHE_CHECK([whether malloc, realloc, calloc are POSIX compliant],
+ [gl_cv_func_malloc_posix],
+ [
+ dnl It is too dangerous to try to allocate a large amount of memory:
+ dnl some systems go to their knees when you do that. So assume that
+ dnl all Unix implementations of the function are POSIX compliant.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[]],
+ [[#if defined _WIN32 && ! defined __CYGWIN__
+ choke me
+ #endif
+ ]])],
+ [gl_cv_func_malloc_posix=yes],
+ [gl_cv_func_malloc_posix=no])
+ ])
+])
diff --git a/gnulib/m4/malloca.m4 b/gnulib/m4/malloca.m4
new file mode 100644
index 0000000..820f40a
--- /dev/null
+++ b/gnulib/m4/malloca.m4
@@ -0,0 +1,15 @@
+# malloca.m4 serial 1
+dnl Copyright (C) 2003-2004, 2006-2007, 2009-2019 Free Software Foundation,
+dnl Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_MALLOCA],
+[
+ dnl Use the autoconf tests for alloca(), but not the AC_SUBSTed variables
+ dnl @ALLOCA@ and @LTALLOCA@.
+ dnl gl_FUNC_ALLOCA dnl Already brought in by the module dependencies.
+ AC_REQUIRE([gl_EEMALLOC])
+ AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
+])
diff --git a/gnulib/m4/manywarnings-c++.m4 b/gnulib/m4/manywarnings-c++.m4
new file mode 100644
index 0000000..30b6204
--- /dev/null
+++ b/gnulib/m4/manywarnings-c++.m4
@@ -0,0 +1,245 @@
+# manywarnings-c++.m4 serial 3
+dnl Copyright (C) 2008-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Implementation of the specialization of gl_MANYWARN_ALL_GCC
+# for _AC_LANG = C++.
+AC_DEFUN([gl_MANYWARN_ALL_GCC_CXX_IMPL],
+[
+ AC_LANG_PUSH([C++])
+
+ dnl First, check for some issues that only occur when combining multiple
+ dnl gcc warning categories.
+ AC_REQUIRE([AC_PROG_CXX])
+ if test -n "$GXX"; then
+
+ dnl Check if -W -Werror -Wno-missing-field-initializers is supported
+ dnl with the current $CXX $CXXFLAGS $CPPFLAGS.
+ AC_CACHE_CHECK([whether -Wno-missing-field-initializers is supported],
+ [gl_cv_cxx_nomfi_supported],
+ [gl_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS -W -Werror -Wno-missing-field-initializers"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[]], [[]])],
+ [gl_cv_cxx_nomfi_supported=yes],
+ [gl_cv_cxx_nomfi_supported=no])
+ CXXFLAGS="$gl_save_CXXFLAGS"
+ ])
+
+ if test "$gl_cv_cxx_nomfi_supported" = yes; then
+ dnl Now check whether -Wno-missing-field-initializers is needed
+ dnl for the { 0, } construct.
+ AC_CACHE_CHECK([whether -Wno-missing-field-initializers is needed],
+ [gl_cv_cxx_nomfi_needed],
+ [gl_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS -W -Werror"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[int f (void)
+ {
+ typedef struct { int a; int b; } s_t;
+ s_t s1 = { 0, };
+ return s1.b;
+ }
+ ]],
+ [[]])],
+ [gl_cv_cxx_nomfi_needed=no],
+ [gl_cv_cxx_nomfi_needed=yes])
+ CXXFLAGS="$gl_save_CXXFLAGS"
+ ])
+ fi
+
+ dnl Next, check if -Werror -Wuninitialized is useful with the
+ dnl user's choice of $CXXFLAGS; some versions of gcc warn that it
+ dnl has no effect if -O is not also used
+ AC_CACHE_CHECK([whether -Wuninitialized is supported],
+ [gl_cv_cxx_uninitialized_supported],
+ [gl_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS -Werror -Wuninitialized"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[]], [[]])],
+ [gl_cv_cxx_uninitialized_supported=yes],
+ [gl_cv_cxx_uninitialized_supported=no])
+ CXXFLAGS="$gl_save_CXXFLAGS"
+ ])
+
+ fi
+
+ # List all gcc warning categories.
+ # To compare this list to your installed GCC's, run this Bash command:
+ #
+ # comm -3 \
+ # <(sed -n 's/^ *\(-[^ ]*\) .*/\1/p' manywarnings-c++.m4 | sort) \
+ # <(gcc --help=warnings | sed -n 's/^ \(-[^ ]*\) .*/\1/p' | sort |
+ # grep -v -x -f <(
+ # awk '/^[^#]/ {print $1}' ../build-aux/g++-warning.spec))
+
+ gl_manywarn_set=
+ for gl_manywarn_item in \
+ -W \
+ -Wabi \
+ -Wabi-tag \
+ -Waddress \
+ -Waggressive-loop-optimizations \
+ -Wall \
+ -Wattributes \
+ -Wbool-compare \
+ -Wbuiltin-macro-redefined \
+ -Wcast-align \
+ -Wchar-subscripts \
+ -Wchkp \
+ -Wclobbered \
+ -Wcomment \
+ -Wcomments \
+ -Wconditionally-supported \
+ -Wconversion-null \
+ -Wcoverage-mismatch \
+ -Wcpp \
+ -Wctor-dtor-privacy \
+ -Wdate-time \
+ -Wdelete-incomplete \
+ -Wdelete-non-virtual-dtor \
+ -Wdeprecated \
+ -Wdeprecated-declarations \
+ -Wdisabled-optimization \
+ -Wdiv-by-zero \
+ -Wdouble-promotion \
+ -Weffc++ \
+ -Wempty-body \
+ -Wendif-labels \
+ -Wenum-compare \
+ -Wextra \
+ -Wformat-contains-nul \
+ -Wformat-extra-args \
+ -Wformat-nonliteral \
+ -Wformat-security \
+ -Wformat-signedness \
+ -Wformat-y2k \
+ -Wformat-zero-length \
+ -Wfree-nonheap-object \
+ -Wignored-qualifiers \
+ -Winherited-variadic-ctor \
+ -Winit-self \
+ -Winline \
+ -Wint-to-pointer-cast \
+ -Winvalid-memory-model \
+ -Winvalid-offsetof \
+ -Winvalid-pch \
+ -Wliteral-suffix \
+ -Wlogical-not-parentheses \
+ -Wlogical-op \
+ -Wmain \
+ -Wmaybe-uninitialized \
+ -Wmemset-transposed-args \
+ -Wmissing-braces \
+ -Wmissing-declarations \
+ -Wmissing-field-initializers \
+ -Wmissing-include-dirs \
+ -Wmultichar \
+ -Wnarrowing \
+ -Wnoexcept \
+ -Wnon-template-friend \
+ -Wnon-virtual-dtor \
+ -Wnonnull \
+ -Wodr \
+ -Wold-style-cast \
+ -Wopenmp-simd \
+ -Woverflow \
+ -Woverlength-strings \
+ -Woverloaded-virtual \
+ -Wpacked \
+ -Wpacked-bitfield-compat \
+ -Wparentheses \
+ -Wpmf-conversions \
+ -Wpointer-arith \
+ -Wpragmas \
+ -Wreorder \
+ -Wreturn-local-addr \
+ -Wreturn-type \
+ -Wsequence-point \
+ -Wshadow \
+ -Wshift-count-negative \
+ -Wshift-count-overflow \
+ -Wsign-promo \
+ -Wsized-deallocation \
+ -Wsizeof-array-argument \
+ -Wsizeof-pointer-memaccess \
+ -Wstack-protector \
+ -Wstrict-aliasing \
+ -Wstrict-null-sentinel \
+ -Wstrict-overflow \
+ -Wsuggest-attribute=const \
+ -Wsuggest-attribute=format \
+ -Wsuggest-attribute=noreturn \
+ -Wsuggest-attribute=pure \
+ -Wsuggest-final-methods \
+ -Wsuggest-final-types \
+ -Wsuggest-override \
+ -Wswitch \
+ -Wswitch-bool \
+ -Wsync-nand \
+ -Wsystem-headers \
+ -Wtrampolines \
+ -Wtrigraphs \
+ -Wtype-limits \
+ -Wuninitialized \
+ -Wunknown-pragmas \
+ -Wunsafe-loop-optimizations \
+ -Wunused \
+ -Wunused-but-set-parameter \
+ -Wunused-but-set-variable \
+ -Wunused-function \
+ -Wunused-label \
+ -Wunused-local-typedefs \
+ -Wunused-macros \
+ -Wunused-parameter \
+ -Wunused-result \
+ -Wunused-value \
+ -Wunused-variable \
+ -Wuseless-cast \
+ -Wvarargs \
+ -Wvariadic-macros \
+ -Wvector-operation-performance \
+ -Wvirtual-move-assign \
+ -Wvla \
+ -Wvolatile-register-var \
+ -Wwrite-strings \
+ -Wzero-as-null-pointer-constant \
+ \
+ ; do
+ gl_manywarn_set="$gl_manywarn_set $gl_manywarn_item"
+ done
+
+ # gcc --help=warnings outputs an unusual form for these options; list
+ # them here so that the above 'comm' command doesn't report a false match.
+ gl_manywarn_set="$gl_manywarn_set -Warray-bounds=2"
+ gl_manywarn_set="$gl_manywarn_set -Wnormalized=nfc"
+ gl_manywarn_set="$gl_manywarn_set -Wshift-overflow=2"
+ gl_manywarn_set="$gl_manywarn_set -Wunused-const-variable=2"
+
+ # These are needed for older GCC versions.
+ if test -n "$GXX"; then
+ case `($CXX --version) 2>/dev/null` in
+ 'g++ (GCC) '[[0-3]].* | \
+ 'g++ (GCC) '4.[[0-7]].*)
+ gl_manywarn_set="$gl_manywarn_set -fdiagnostics-show-option"
+ gl_manywarn_set="$gl_manywarn_set -funit-at-a-time"
+ ;;
+ esac
+ fi
+
+ # Disable specific options as needed.
+ if test "$gl_cv_cxx_nomfi_needed" = yes; then
+ gl_manywarn_set="$gl_manywarn_set -Wno-missing-field-initializers"
+ fi
+
+ if test "$gl_cv_cxx_uninitialized_supported" = no; then
+ gl_manywarn_set="$gl_manywarn_set -Wno-uninitialized"
+ fi
+
+ $1=$gl_manywarn_set
+
+ AC_LANG_POP([C++])
+])
diff --git a/gnulib/m4/manywarnings.m4 b/gnulib/m4/manywarnings.m4
new file mode 100644
index 0000000..6bb9f8f
--- /dev/null
+++ b/gnulib/m4/manywarnings.m4
@@ -0,0 +1,339 @@
+# manywarnings.m4 serial 18
+dnl Copyright (C) 2008-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Simon Josefsson
+
+# gl_MANYWARN_COMPLEMENT(OUTVAR, LISTVAR, REMOVEVAR)
+# --------------------------------------------------
+# Copy LISTVAR to OUTVAR except for the entries in REMOVEVAR.
+# Elements separated by whitespace. In set logic terms, the function
+# does OUTVAR = LISTVAR \ REMOVEVAR.
+AC_DEFUN([gl_MANYWARN_COMPLEMENT],
+[
+ gl_warn_set=
+ set x $2; shift
+ for gl_warn_item
+ do
+ case " $3 " in
+ *" $gl_warn_item "*)
+ ;;
+ *)
+ gl_warn_set="$gl_warn_set $gl_warn_item"
+ ;;
+ esac
+ done
+ $1=$gl_warn_set
+])
+
+# gl_MANYWARN_ALL_GCC(VARIABLE)
+# -----------------------------
+# Add all documented GCC warning parameters to variable VARIABLE.
+# Note that you need to test them using gl_WARN_ADD if you want to
+# make sure your gcc understands it.
+#
+# The effects of this macro depend on the current language (_AC_LANG).
+AC_DEFUN([gl_MANYWARN_ALL_GCC],
+[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)])
+
+# Specialization for _AC_LANG = C.
+# Use of m4_defun rather than AC_DEFUN works around a bug in autoconf < 2.63b.
+m4_defun([gl_MANYWARN_ALL_GCC(C)],
+[
+ AC_LANG_PUSH([C])
+
+ dnl First, check for some issues that only occur when combining multiple
+ dnl gcc warning categories.
+ AC_REQUIRE([AC_PROG_CC])
+ if test -n "$GCC"; then
+
+ dnl Check if -W -Werror -Wno-missing-field-initializers is supported
+ dnl with the current $CC $CFLAGS $CPPFLAGS.
+ AC_CACHE_CHECK([whether -Wno-missing-field-initializers is supported],
+ [gl_cv_cc_nomfi_supported],
+ [gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -W -Werror -Wno-missing-field-initializers"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[]], [[]])],
+ [gl_cv_cc_nomfi_supported=yes],
+ [gl_cv_cc_nomfi_supported=no])
+ CFLAGS="$gl_save_CFLAGS"
+ ])
+
+ if test "$gl_cv_cc_nomfi_supported" = yes; then
+ dnl Now check whether -Wno-missing-field-initializers is needed
+ dnl for the { 0, } construct.
+ AC_CACHE_CHECK([whether -Wno-missing-field-initializers is needed],
+ [gl_cv_cc_nomfi_needed],
+ [gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -W -Werror"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[int f (void)
+ {
+ typedef struct { int a; int b; } s_t;
+ s_t s1 = { 0, };
+ return s1.b;
+ }
+ ]],
+ [[]])],
+ [gl_cv_cc_nomfi_needed=no],
+ [gl_cv_cc_nomfi_needed=yes])
+ CFLAGS="$gl_save_CFLAGS"
+ ])
+ fi
+
+ dnl Next, check if -Werror -Wuninitialized is useful with the
+ dnl user's choice of $CFLAGS; some versions of gcc warn that it
+ dnl has no effect if -O is not also used
+ AC_CACHE_CHECK([whether -Wuninitialized is supported],
+ [gl_cv_cc_uninitialized_supported],
+ [gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Werror -Wuninitialized"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[]], [[]])],
+ [gl_cv_cc_uninitialized_supported=yes],
+ [gl_cv_cc_uninitialized_supported=no])
+ CFLAGS="$gl_save_CFLAGS"
+ ])
+
+ fi
+
+ # List all gcc warning categories.
+ # To compare this list to your installed GCC's, run this Bash command:
+ #
+ # comm -3 \
+ # <((sed -n 's/^ *\(-[^ 0-9][^ ]*\) .*/\1/p' manywarnings.m4; \
+ # awk '/^[^#]/ {print $1}' ../build-aux/gcc-warning.spec) | sort) \
+ # <(LC_ALL=C gcc --help=warnings | sed -n 's/^ \(-[^ ]*\) .*/\1/p' | sort)
+
+ gl_manywarn_set=
+ for gl_manywarn_item in -fno-common \
+ -W \
+ -Wabsolute-value \
+ -Waddress \
+ -Waddress-of-packed-member \
+ -Waggressive-loop-optimizations \
+ -Wall \
+ -Wattribute-warning \
+ -Wattributes \
+ -Wbad-function-cast \
+ -Wbool-compare \
+ -Wbool-operation \
+ -Wbuiltin-declaration-mismatch \
+ -Wbuiltin-macro-redefined \
+ -Wcannot-profile \
+ -Wcast-align \
+ -Wcast-align=strict \
+ -Wcast-function-type \
+ -Wchar-subscripts \
+ -Wclobbered \
+ -Wcomment \
+ -Wcomments \
+ -Wcoverage-mismatch \
+ -Wcpp \
+ -Wdangling-else \
+ -Wdate-time \
+ -Wdeprecated \
+ -Wdeprecated-declarations \
+ -Wdesignated-init \
+ -Wdisabled-optimization \
+ -Wdiscarded-array-qualifiers \
+ -Wdiscarded-qualifiers \
+ -Wdiv-by-zero \
+ -Wdouble-promotion \
+ -Wduplicated-branches \
+ -Wduplicated-cond \
+ -Wduplicate-decl-specifier \
+ -Wempty-body \
+ -Wendif-labels \
+ -Wenum-compare \
+ -Wexpansion-to-defined \
+ -Wextra \
+ -Wformat-contains-nul \
+ -Wformat-extra-args \
+ -Wformat-nonliteral \
+ -Wformat-security \
+ -Wformat-signedness \
+ -Wformat-y2k \
+ -Wformat-zero-length \
+ -Wframe-address \
+ -Wfree-nonheap-object \
+ -Whsa \
+ -Wif-not-aligned \
+ -Wignored-attributes \
+ -Wignored-qualifiers \
+ -Wimplicit \
+ -Wimplicit-function-declaration \
+ -Wimplicit-int \
+ -Wincompatible-pointer-types \
+ -Winit-self \
+ -Winline \
+ -Wint-conversion \
+ -Wint-in-bool-context \
+ -Wint-to-pointer-cast \
+ -Winvalid-memory-model \
+ -Winvalid-pch \
+ -Wlogical-not-parentheses \
+ -Wlogical-op \
+ -Wmain \
+ -Wmaybe-uninitialized \
+ -Wmemset-elt-size \
+ -Wmemset-transposed-args \
+ -Wmisleading-indentation \
+ -Wmissing-attributes \
+ -Wmissing-braces \
+ -Wmissing-declarations \
+ -Wmissing-field-initializers \
+ -Wmissing-include-dirs \
+ -Wmissing-parameter-type \
+ -Wmissing-profile \
+ -Wmissing-prototypes \
+ -Wmultichar \
+ -Wmultistatement-macros \
+ -Wnarrowing \
+ -Wnested-externs \
+ -Wnonnull \
+ -Wnonnull-compare \
+ -Wnull-dereference \
+ -Wodr \
+ -Wold-style-declaration \
+ -Wold-style-definition \
+ -Wopenmp-simd \
+ -Woverflow \
+ -Woverlength-strings \
+ -Woverride-init \
+ -Wpacked \
+ -Wpacked-bitfield-compat \
+ -Wpacked-not-aligned \
+ -Wparentheses \
+ -Wpointer-arith \
+ -Wpointer-compare \
+ -Wpointer-sign \
+ -Wpointer-to-int-cast \
+ -Wpragmas \
+ -Wpsabi \
+ -Wrestrict \
+ -Wreturn-local-addr \
+ -Wreturn-type \
+ -Wscalar-storage-order \
+ -Wsequence-point \
+ -Wshadow \
+ -Wshift-count-negative \
+ -Wshift-count-overflow \
+ -Wshift-negative-value \
+ -Wsizeof-array-argument \
+ -Wsizeof-pointer-div \
+ -Wsizeof-pointer-memaccess \
+ -Wstack-protector \
+ -Wstrict-aliasing \
+ -Wstrict-overflow \
+ -Wstrict-prototypes \
+ -Wstringop-truncation \
+ -Wsuggest-attribute=cold \
+ -Wsuggest-attribute=const \
+ -Wsuggest-attribute=format \
+ -Wsuggest-attribute=malloc \
+ -Wsuggest-attribute=noreturn \
+ -Wsuggest-attribute=pure \
+ -Wsuggest-final-methods \
+ -Wsuggest-final-types \
+ -Wswitch \
+ -Wswitch-bool \
+ -Wswitch-unreachable \
+ -Wsync-nand \
+ -Wsystem-headers \
+ -Wtautological-compare \
+ -Wtrampolines \
+ -Wtrigraphs \
+ -Wtype-limits \
+ -Wuninitialized \
+ -Wunknown-pragmas \
+ -Wunsafe-loop-optimizations \
+ -Wunused \
+ -Wunused-but-set-parameter \
+ -Wunused-but-set-variable \
+ -Wunused-function \
+ -Wunused-label \
+ -Wunused-local-typedefs \
+ -Wunused-macros \
+ -Wunused-parameter \
+ -Wunused-result \
+ -Wunused-value \
+ -Wunused-variable \
+ -Wvarargs \
+ -Wvariadic-macros \
+ -Wvector-operation-performance \
+ -Wvla \
+ -Wvolatile-register-var \
+ -Wwrite-strings \
+ \
+ ; do
+ gl_manywarn_set="$gl_manywarn_set $gl_manywarn_item"
+ done
+
+ # gcc --help=warnings outputs an unusual form for these options; list
+ # them here so that the above 'comm' command doesn't report a false match.
+ # Would prefer "min (PTRDIFF_MAX, SIZE_MAX)", but it must be a literal.
+ # Also, AC_COMPUTE_INT requires it to fit in a long; it is 2**63 on
+ # the only platforms where it does not fit in a long, so make that
+ # a special case.
+ AC_MSG_CHECKING([max safe object size])
+ AC_COMPUTE_INT([gl_alloc_max],
+ [LONG_MAX < (PTRDIFF_MAX < (size_t) -1 ? PTRDIFF_MAX : (size_t) -1)
+ ? -1
+ : PTRDIFF_MAX < (size_t) -1 ? (long) PTRDIFF_MAX : (long) (size_t) -1],
+ [[#include <limits.h>
+ #include <stddef.h>
+ #include <stdint.h>
+ ]],
+ [gl_alloc_max=2147483647])
+ case $gl_alloc_max in
+ -1) gl_alloc_max=9223372036854775807;;
+ esac
+ AC_MSG_RESULT([$gl_alloc_max])
+ gl_manywarn_set="$gl_manywarn_set -Walloc-size-larger-than=$gl_alloc_max"
+ gl_manywarn_set="$gl_manywarn_set -Warray-bounds=2"
+ gl_manywarn_set="$gl_manywarn_set -Wattribute-alias=2"
+ gl_manywarn_set="$gl_manywarn_set -Wformat-overflow=2"
+ gl_manywarn_set="$gl_manywarn_set -Wformat-truncation=2"
+ gl_manywarn_set="$gl_manywarn_set -Wimplicit-fallthrough=5"
+ gl_manywarn_set="$gl_manywarn_set -Wnormalized=nfc"
+ gl_manywarn_set="$gl_manywarn_set -Wshift-overflow=2"
+ gl_manywarn_set="$gl_manywarn_set -Wstringop-overflow=2"
+ gl_manywarn_set="$gl_manywarn_set -Wunused-const-variable=2"
+ gl_manywarn_set="$gl_manywarn_set -Wvla-larger-than=4031"
+
+ # These are needed for older GCC versions.
+ if test -n "$GCC"; then
+ case `($CC --version) 2>/dev/null` in
+ 'gcc (GCC) '[[0-3]].* | \
+ 'gcc (GCC) '4.[[0-7]].*)
+ gl_manywarn_set="$gl_manywarn_set -fdiagnostics-show-option"
+ gl_manywarn_set="$gl_manywarn_set -funit-at-a-time"
+ ;;
+ esac
+ fi
+
+ # Disable specific options as needed.
+ if test "$gl_cv_cc_nomfi_needed" = yes; then
+ gl_manywarn_set="$gl_manywarn_set -Wno-missing-field-initializers"
+ fi
+
+ if test "$gl_cv_cc_uninitialized_supported" = no; then
+ gl_manywarn_set="$gl_manywarn_set -Wno-uninitialized"
+ fi
+
+ $1=$gl_manywarn_set
+
+ AC_LANG_POP([C])
+])
+
+# Specialization for _AC_LANG = C++.
+# Use of m4_defun rather than AC_DEFUN works around a bug in autoconf < 2.63b.
+m4_defun([gl_MANYWARN_ALL_GCC(C++)],
+[
+ gl_MANYWARN_ALL_GCC_CXX_IMPL([$1])
+])
diff --git a/gnulib/m4/multiarch.m4 b/gnulib/m4/multiarch.m4
new file mode 100644
index 0000000..d48316e
--- /dev/null
+++ b/gnulib/m4/multiarch.m4
@@ -0,0 +1,62 @@
+# multiarch.m4 serial 7
+dnl Copyright (C) 2008-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Determine whether the compiler is or may be producing universal binaries.
+#
+# On Mac OS X 10.5 and later systems, the user can create libraries and
+# executables that work on multiple system types--known as "fat" or
+# "universal" binaries--by specifying multiple '-arch' options to the
+# compiler but only a single '-arch' option to the preprocessor. Like
+# this:
+#
+# ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+# CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+# CPP="gcc -E" CXXCPP="g++ -E"
+#
+# Detect this situation and set APPLE_UNIVERSAL_BUILD accordingly.
+
+AC_DEFUN_ONCE([gl_MULTIARCH],
+[
+ dnl Code similar to autoconf-2.63 AC_C_BIGENDIAN.
+ gl_cv_c_multiarch=no
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+ ]])],
+ [
+ dnl Check for potential -arch flags. It is not universal unless
+ dnl there are at least two -arch flags with different values.
+ arch=
+ prev=
+ for word in ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}; do
+ if test -n "$prev"; then
+ case $word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$arch" || test "$arch" = "$word"; then
+ arch="$word"
+ else
+ gl_cv_c_multiarch=yes
+ fi
+ ;;
+ esac
+ prev=
+ else
+ if test "x$word" = "x-arch"; then
+ prev=arch
+ fi
+ fi
+ done
+ ])
+ if test $gl_cv_c_multiarch = yes; then
+ APPLE_UNIVERSAL_BUILD=1
+ else
+ APPLE_UNIVERSAL_BUILD=0
+ fi
+ AC_SUBST([APPLE_UNIVERSAL_BUILD])
+])
diff --git a/gnulib/m4/off_t.m4 b/gnulib/m4/off_t.m4
new file mode 100644
index 0000000..711a2d4
--- /dev/null
+++ b/gnulib/m4/off_t.m4
@@ -0,0 +1,18 @@
+# off_t.m4 serial 1
+dnl Copyright (C) 2012-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Check whether to override the 'off_t' type.
+dnl Set WINDOWS_64_BIT_OFF_T.
+
+AC_DEFUN([gl_TYPE_OFF_T],
+[
+ m4_ifdef([gl_LARGEFILE], [
+ AC_REQUIRE([gl_LARGEFILE])
+ ], [
+ WINDOWS_64_BIT_OFF_T=0
+ ])
+ AC_SUBST([WINDOWS_64_BIT_OFF_T])
+])
diff --git a/gnulib/m4/realloc.m4 b/gnulib/m4/realloc.m4
new file mode 100644
index 0000000..93066e8
--- /dev/null
+++ b/gnulib/m4/realloc.m4
@@ -0,0 +1,86 @@
+# realloc.m4 serial 17
+dnl Copyright (C) 2007, 2009-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+m4_version_prereq([2.70], [] ,[
+
+# This is adapted with modifications from upstream Autoconf here:
+# https://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=04be2b7a29d65d9a08e64e8e56e594c91749598c
+AC_DEFUN([_AC_FUNC_REALLOC_IF],
+[
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
+ AC_CHECK_HEADERS([stdlib.h])
+ AC_CACHE_CHECK([for GNU libc compatible realloc],
+ [ac_cv_func_realloc_0_nonnull],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#if defined STDC_HEADERS || defined HAVE_STDLIB_H
+ # include <stdlib.h>
+ #else
+ char *realloc ();
+ #endif
+ ]],
+ [[char *p = realloc (0, 0);
+ int result = !p;
+ free (p);
+ return result;]])
+ ],
+ [ac_cv_func_realloc_0_nonnull=yes],
+ [ac_cv_func_realloc_0_nonnull=no],
+ [case "$host_os" in
+ # Guess yes on platforms where we know the result.
+ *-gnu* | gnu* | *-musl* | freebsd* | netbsd* | openbsd* \
+ | hpux* | solaris* | cygwin* | mingw*)
+ ac_cv_func_realloc_0_nonnull="guessing yes" ;;
+ # If we don't know, assume the worst.
+ *) ac_cv_func_realloc_0_nonnull="guessing no" ;;
+ esac
+ ])
+ ])
+ case "$ac_cv_func_realloc_0_nonnull" in
+ *yes)
+ $1
+ ;;
+ *)
+ $2
+ ;;
+ esac
+])# AC_FUNC_REALLOC
+
+])
+
+# gl_FUNC_REALLOC_GNU
+# -------------------
+# Test whether 'realloc (0, 0)' is handled like in GNU libc, and replace
+# realloc if it is not.
+AC_DEFUN([gl_FUNC_REALLOC_GNU],
+[
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ dnl _AC_FUNC_REALLOC_IF is defined in Autoconf.
+ _AC_FUNC_REALLOC_IF(
+ [AC_DEFINE([HAVE_REALLOC_GNU], [1],
+ [Define to 1 if your system has a GNU libc compatible 'realloc'
+ function, and to 0 otherwise.])],
+ [AC_DEFINE([HAVE_REALLOC_GNU], [0])
+ REPLACE_REALLOC=1
+ ])
+])# gl_FUNC_REALLOC_GNU
+
+# gl_FUNC_REALLOC_POSIX
+# ---------------------
+# Test whether 'realloc' is POSIX compliant (sets errno to ENOMEM when it
+# fails), and replace realloc if it is not.
+AC_DEFUN([gl_FUNC_REALLOC_POSIX],
+[
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_REQUIRE([gl_CHECK_MALLOC_POSIX])
+ if test $gl_cv_func_malloc_posix = yes; then
+ AC_DEFINE([HAVE_REALLOC_POSIX], [1],
+ [Define if the 'realloc' function is POSIX compliant.])
+ else
+ REPLACE_REALLOC=1
+ fi
+])
diff --git a/gnulib/m4/setenv.m4 b/gnulib/m4/setenv.m4
new file mode 100644
index 0000000..a8f83d6
--- /dev/null
+++ b/gnulib/m4/setenv.m4
@@ -0,0 +1,162 @@
+# setenv.m4 serial 28
+dnl Copyright (C) 2001-2004, 2006-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_SETENV],
+[
+ AC_REQUIRE([gl_FUNC_SETENV_SEPARATE])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ if test $ac_cv_func_setenv = no; then
+ HAVE_SETENV=0
+ else
+ AC_CACHE_CHECK([whether setenv validates arguments],
+ [gl_cv_func_setenv_works],
+ [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+ #include <stdlib.h>
+ #include <errno.h>
+ #include <string.h>
+ ]], [[
+ int result = 0;
+ {
+ if (setenv ("", "", 0) != -1)
+ result |= 1;
+ else if (errno != EINVAL)
+ result |= 2;
+ }
+ {
+ if (setenv ("a", "=", 1) != 0)
+ result |= 4;
+ else if (strcmp (getenv ("a"), "=") != 0)
+ result |= 8;
+ }
+ return result;
+ ]])],
+ [gl_cv_func_setenv_works=yes], [gl_cv_func_setenv_works=no],
+ [case "$host_os" in
+ # Guess yes on glibc systems.
+ *-gnu* | gnu*) gl_cv_func_setenv_works="guessing yes" ;;
+ # Guess yes on musl systems.
+ *-musl*) gl_cv_func_setenv_works="guessing yes" ;;
+ # If we don't know, assume the worst.
+ *) gl_cv_func_setenv_works="guessing no" ;;
+ esac
+ ])])
+ case "$gl_cv_func_setenv_works" in
+ *yes) ;;
+ *)
+ REPLACE_SETENV=1
+ ;;
+ esac
+ fi
+])
+
+# Like gl_FUNC_SETENV, except prepare for separate compilation
+# (no REPLACE_SETENV, no AC_LIBOBJ).
+AC_DEFUN([gl_FUNC_SETENV_SEPARATE],
+[
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_CHECK_DECLS_ONCE([setenv])
+ if test $ac_cv_have_decl_setenv = no; then
+ HAVE_DECL_SETENV=0
+ fi
+ AC_CHECK_FUNCS_ONCE([setenv])
+ gl_PREREQ_SETENV
+])
+
+AC_DEFUN([gl_FUNC_UNSETENV],
+[
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CHECK_DECLS_ONCE([unsetenv])
+ if test $ac_cv_have_decl_unsetenv = no; then
+ HAVE_DECL_UNSETENV=0
+ fi
+ AC_CHECK_FUNCS([unsetenv])
+ if test $ac_cv_func_unsetenv = no; then
+ HAVE_UNSETENV=0
+ else
+ HAVE_UNSETENV=1
+ dnl Some BSDs return void, failing to do error checking.
+ AC_CACHE_CHECK([for unsetenv() return type], [gt_cv_func_unsetenv_ret],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#undef _BSD
+#define _BSD 1 /* unhide unsetenv declaration in OSF/1 5.1 <stdlib.h> */
+#include <stdlib.h>
+extern
+#ifdef __cplusplus
+"C"
+#endif
+int unsetenv (const char *name);
+ ]],
+ [[]])],
+ [gt_cv_func_unsetenv_ret='int'],
+ [gt_cv_func_unsetenv_ret='void'])])
+ if test $gt_cv_func_unsetenv_ret = 'void'; then
+ AC_DEFINE([VOID_UNSETENV], [1], [Define to 1 if unsetenv returns void
+ instead of int.])
+ REPLACE_UNSETENV=1
+ fi
+
+ dnl Solaris 10 unsetenv does not remove all copies of a name.
+ dnl Haiku alpha 2 unsetenv gets confused by assignment to environ.
+ dnl OpenBSD 4.7 unsetenv("") does not fail.
+ AC_CACHE_CHECK([whether unsetenv obeys POSIX],
+ [gl_cv_func_unsetenv_works],
+ [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+ #include <stdlib.h>
+ #include <errno.h>
+ extern char **environ;
+ ]], [[
+ char entry1[] = "a=1";
+ char entry2[] = "b=2";
+ char *env[] = { entry1, entry2, NULL };
+ if (putenv ((char *) "a=1")) return 1;
+ if (putenv (entry2)) return 2;
+ entry2[0] = 'a';
+ unsetenv ("a");
+ if (getenv ("a")) return 3;
+ if (!unsetenv ("") || errno != EINVAL) return 4;
+ entry2[0] = 'b';
+ environ = env;
+ if (!getenv ("a")) return 5;
+ entry2[0] = 'a';
+ unsetenv ("a");
+ if (getenv ("a")) return 6;
+ ]])],
+ [gl_cv_func_unsetenv_works=yes], [gl_cv_func_unsetenv_works=no],
+ [case "$host_os" in
+ # Guess yes on glibc systems.
+ *-gnu*) gl_cv_func_unsetenv_works="guessing yes" ;;
+ # If we don't know, assume the worst.
+ *) gl_cv_func_unsetenv_works="guessing no" ;;
+ esac
+ ])])
+ case "$gl_cv_func_unsetenv_works" in
+ *yes) ;;
+ *)
+ REPLACE_UNSETENV=1
+ ;;
+ esac
+ fi
+])
+
+# Prerequisites of lib/setenv.c.
+AC_DEFUN([gl_PREREQ_SETENV],
+[
+ AC_REQUIRE([AC_FUNC_ALLOCA])
+ AC_REQUIRE([gl_ENVIRON])
+ AC_CHECK_HEADERS_ONCE([unistd.h])
+ AC_CHECK_HEADERS([search.h])
+ AC_CHECK_FUNCS([tsearch])
+])
+
+# Prerequisites of lib/unsetenv.c.
+AC_DEFUN([gl_PREREQ_UNSETENV],
+[
+ AC_REQUIRE([gl_ENVIRON])
+ AC_CHECK_HEADERS_ONCE([unistd.h])
+])
diff --git a/gnulib/m4/ssize_t.m4 b/gnulib/m4/ssize_t.m4
new file mode 100644
index 0000000..38bcee1
--- /dev/null
+++ b/gnulib/m4/ssize_t.m4
@@ -0,0 +1,23 @@
+# ssize_t.m4 serial 5 (gettext-0.18.2)
+dnl Copyright (C) 2001-2003, 2006, 2010-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Test whether ssize_t is defined.
+
+AC_DEFUN([gt_TYPE_SSIZE_T],
+[
+ AC_CACHE_CHECK([for ssize_t], [gt_cv_ssize_t],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <sys/types.h>]],
+ [[int x = sizeof (ssize_t *) + sizeof (ssize_t);
+ return !x;]])],
+ [gt_cv_ssize_t=yes], [gt_cv_ssize_t=no])])
+ if test $gt_cv_ssize_t = no; then
+ AC_DEFINE([ssize_t], [int],
+ [Define as a signed type of the same size as size_t.])
+ fi
+])
diff --git a/gnulib/m4/stddef_h.m4 b/gnulib/m4/stddef_h.m4
new file mode 100644
index 0000000..979e3cf
--- /dev/null
+++ b/gnulib/m4/stddef_h.m4
@@ -0,0 +1,72 @@
+dnl A placeholder for <stddef.h>, for platforms that have issues.
+# stddef_h.m4 serial 6
+dnl Copyright (C) 2009-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_STDDEF_H],
+[
+ AC_REQUIRE([gl_STDDEF_H_DEFAULTS])
+ AC_REQUIRE([gt_TYPE_WCHAR_T])
+ STDDEF_H=
+
+ dnl Test whether the type max_align_t exists and whether its alignment
+ dnl "is as great as is supported by the implementation in all contexts".
+ AC_CACHE_CHECK([for good max_align_t],
+ [gl_cv_type_max_align_t],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <stddef.h>
+ unsigned int s = sizeof (max_align_t);
+ #if defined __GNUC__ || defined __IBM__ALIGNOF__
+ int check1[2 * (__alignof__ (double) <= __alignof__ (max_align_t)) - 1];
+ int check2[2 * (__alignof__ (long double) <= __alignof__ (max_align_t)) - 1];
+ #endif
+ ]])],
+ [gl_cv_type_max_align_t=yes],
+ [gl_cv_type_max_align_t=no])
+ ])
+ if test $gl_cv_type_max_align_t = no; then
+ HAVE_MAX_ALIGN_T=0
+ STDDEF_H=stddef.h
+ fi
+
+ if test $gt_cv_c_wchar_t = no; then
+ HAVE_WCHAR_T=0
+ STDDEF_H=stddef.h
+ fi
+
+ AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions],
+ [gl_cv_decl_null_works],
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stddef.h>
+ int test[2 * (sizeof NULL == sizeof (void *)) -1];
+]])],
+ [gl_cv_decl_null_works=yes],
+ [gl_cv_decl_null_works=no])])
+ if test $gl_cv_decl_null_works = no; then
+ REPLACE_NULL=1
+ STDDEF_H=stddef.h
+ fi
+
+ AC_SUBST([STDDEF_H])
+ AM_CONDITIONAL([GL_GENERATE_STDDEF_H], [test -n "$STDDEF_H"])
+ if test -n "$STDDEF_H"; then
+ gl_NEXT_HEADERS([stddef.h])
+ fi
+])
+
+AC_DEFUN([gl_STDDEF_MODULE_INDICATOR],
+[
+ dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+ AC_REQUIRE([gl_STDDEF_H_DEFAULTS])
+ gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+])
+
+AC_DEFUN([gl_STDDEF_H_DEFAULTS],
+[
+ dnl Assume proper GNU behavior unless another module says otherwise.
+ REPLACE_NULL=0; AC_SUBST([REPLACE_NULL])
+ HAVE_MAX_ALIGN_T=1; AC_SUBST([HAVE_MAX_ALIGN_T])
+ HAVE_WCHAR_T=1; AC_SUBST([HAVE_WCHAR_T])
+])
diff --git a/gnulib/m4/stdint.m4 b/gnulib/m4/stdint.m4
new file mode 100644
index 0000000..11d8e8e
--- /dev/null
+++ b/gnulib/m4/stdint.m4
@@ -0,0 +1,544 @@
+# stdint.m4 serial 53
+dnl Copyright (C) 2001-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert and Bruno Haible.
+dnl Test whether <stdint.h> is supported or must be substituted.
+
+AC_PREREQ([2.61])
+
+AC_DEFUN_ONCE([gl_STDINT_H],
+[
+ AC_PREREQ([2.59])dnl
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+ AC_REQUIRE([gl_LIMITS_H])
+ AC_REQUIRE([gt_TYPE_WINT_T])
+
+ dnl Check for long long int and unsigned long long int.
+ AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
+ if test $ac_cv_type_long_long_int = yes; then
+ HAVE_LONG_LONG_INT=1
+ else
+ HAVE_LONG_LONG_INT=0
+ fi
+ AC_SUBST([HAVE_LONG_LONG_INT])
+ AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT])
+ if test $ac_cv_type_unsigned_long_long_int = yes; then
+ HAVE_UNSIGNED_LONG_LONG_INT=1
+ else
+ HAVE_UNSIGNED_LONG_LONG_INT=0
+ fi
+ AC_SUBST([HAVE_UNSIGNED_LONG_LONG_INT])
+
+ dnl Check for <wchar.h>, in the same way as gl_WCHAR_H does.
+ AC_CHECK_HEADERS_ONCE([wchar.h])
+ if test $ac_cv_header_wchar_h = yes; then
+ HAVE_WCHAR_H=1
+ else
+ HAVE_WCHAR_H=0
+ fi
+ AC_SUBST([HAVE_WCHAR_H])
+
+ dnl Check for <inttypes.h>.
+ dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_inttypes_h.
+ if test $ac_cv_header_inttypes_h = yes; then
+ HAVE_INTTYPES_H=1
+ else
+ HAVE_INTTYPES_H=0
+ fi
+ AC_SUBST([HAVE_INTTYPES_H])
+
+ dnl Check for <sys/types.h>.
+ dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_sys_types_h.
+ if test $ac_cv_header_sys_types_h = yes; then
+ HAVE_SYS_TYPES_H=1
+ else
+ HAVE_SYS_TYPES_H=0
+ fi
+ AC_SUBST([HAVE_SYS_TYPES_H])
+
+ gl_CHECK_NEXT_HEADERS([stdint.h])
+ if test $ac_cv_header_stdint_h = yes; then
+ HAVE_STDINT_H=1
+ else
+ HAVE_STDINT_H=0
+ fi
+ AC_SUBST([HAVE_STDINT_H])
+
+ dnl Now see whether we need a substitute <stdint.h>.
+ if test $ac_cv_header_stdint_h = yes; then
+ AC_CACHE_CHECK([whether stdint.h conforms to C99],
+ [gl_cv_header_working_stdint_h],
+ [gl_cv_header_working_stdint_h=no
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([[
+#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */
+#define __STDC_CONSTANT_MACROS 1
+#define __STDC_LIMIT_MACROS 1
+#include <stdint.h>
+/* Dragonfly defines WCHAR_MIN, WCHAR_MAX only in <wchar.h>. */
+#if !(defined WCHAR_MIN && defined WCHAR_MAX)
+#error "WCHAR_MIN, WCHAR_MAX not defined in <stdint.h>"
+#endif
+]
+gl_STDINT_INCLUDES
+[
+#ifdef INT8_MAX
+int8_t a1 = INT8_MAX;
+int8_t a1min = INT8_MIN;
+#endif
+#ifdef INT16_MAX
+int16_t a2 = INT16_MAX;
+int16_t a2min = INT16_MIN;
+#endif
+#ifdef INT32_MAX
+int32_t a3 = INT32_MAX;
+int32_t a3min = INT32_MIN;
+#endif
+#ifdef INT64_MAX
+int64_t a4 = INT64_MAX;
+int64_t a4min = INT64_MIN;
+#endif
+#ifdef UINT8_MAX
+uint8_t b1 = UINT8_MAX;
+#else
+typedef int b1[(unsigned char) -1 != 255 ? 1 : -1];
+#endif
+#ifdef UINT16_MAX
+uint16_t b2 = UINT16_MAX;
+#endif
+#ifdef UINT32_MAX
+uint32_t b3 = UINT32_MAX;
+#endif
+#ifdef UINT64_MAX
+uint64_t b4 = UINT64_MAX;
+#endif
+int_least8_t c1 = INT8_C (0x7f);
+int_least8_t c1max = INT_LEAST8_MAX;
+int_least8_t c1min = INT_LEAST8_MIN;
+int_least16_t c2 = INT16_C (0x7fff);
+int_least16_t c2max = INT_LEAST16_MAX;
+int_least16_t c2min = INT_LEAST16_MIN;
+int_least32_t c3 = INT32_C (0x7fffffff);
+int_least32_t c3max = INT_LEAST32_MAX;
+int_least32_t c3min = INT_LEAST32_MIN;
+int_least64_t c4 = INT64_C (0x7fffffffffffffff);
+int_least64_t c4max = INT_LEAST64_MAX;
+int_least64_t c4min = INT_LEAST64_MIN;
+uint_least8_t d1 = UINT8_C (0xff);
+uint_least8_t d1max = UINT_LEAST8_MAX;
+uint_least16_t d2 = UINT16_C (0xffff);
+uint_least16_t d2max = UINT_LEAST16_MAX;
+uint_least32_t d3 = UINT32_C (0xffffffff);
+uint_least32_t d3max = UINT_LEAST32_MAX;
+uint_least64_t d4 = UINT64_C (0xffffffffffffffff);
+uint_least64_t d4max = UINT_LEAST64_MAX;
+int_fast8_t e1 = INT_FAST8_MAX;
+int_fast8_t e1min = INT_FAST8_MIN;
+int_fast16_t e2 = INT_FAST16_MAX;
+int_fast16_t e2min = INT_FAST16_MIN;
+int_fast32_t e3 = INT_FAST32_MAX;
+int_fast32_t e3min = INT_FAST32_MIN;
+int_fast64_t e4 = INT_FAST64_MAX;
+int_fast64_t e4min = INT_FAST64_MIN;
+uint_fast8_t f1 = UINT_FAST8_MAX;
+uint_fast16_t f2 = UINT_FAST16_MAX;
+uint_fast32_t f3 = UINT_FAST32_MAX;
+uint_fast64_t f4 = UINT_FAST64_MAX;
+#ifdef INTPTR_MAX
+intptr_t g = INTPTR_MAX;
+intptr_t gmin = INTPTR_MIN;
+#endif
+#ifdef UINTPTR_MAX
+uintptr_t h = UINTPTR_MAX;
+#endif
+intmax_t i = INTMAX_MAX;
+uintmax_t j = UINTMAX_MAX;
+
+/* Check that SIZE_MAX has the correct type, if possible. */
+#if 201112 <= __STDC_VERSION__
+int k = _Generic (SIZE_MAX, size_t: 0);
+#elif (2 <= __GNUC__ || defined __IBM__TYPEOF__ \
+ || (0x5110 <= __SUNPRO_C && !__STDC__))
+extern size_t k;
+extern __typeof__ (SIZE_MAX) k;
+#endif
+
+#include <limits.h> /* for CHAR_BIT */
+#define TYPE_MINIMUM(t) \
+ ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ TYPE_MAXIMUM (t)))
+#define TYPE_MAXIMUM(t) \
+ ((t) ((t) 0 < (t) -1 \
+ ? (t) -1 \
+ : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
+struct s {
+ int check_PTRDIFF:
+ PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t)
+ && PTRDIFF_MAX == TYPE_MAXIMUM (ptrdiff_t)
+ ? 1 : -1;
+ /* Detect bug in FreeBSD 6.0 / ia64. */
+ int check_SIG_ATOMIC:
+ SIG_ATOMIC_MIN == TYPE_MINIMUM (sig_atomic_t)
+ && SIG_ATOMIC_MAX == TYPE_MAXIMUM (sig_atomic_t)
+ ? 1 : -1;
+ int check_SIZE: SIZE_MAX == TYPE_MAXIMUM (size_t) ? 1 : -1;
+ int check_WCHAR:
+ WCHAR_MIN == TYPE_MINIMUM (wchar_t)
+ && WCHAR_MAX == TYPE_MAXIMUM (wchar_t)
+ ? 1 : -1;
+ /* Detect bug in mingw. */
+ int check_WINT:
+ WINT_MIN == TYPE_MINIMUM (wint_t)
+ && WINT_MAX == TYPE_MAXIMUM (wint_t)
+ ? 1 : -1;
+
+ /* Detect bugs in glibc 2.4 and Solaris 10 stdint.h, among others. */
+ int check_UINT8_C:
+ (-1 < UINT8_C (0)) == (-1 < (uint_least8_t) 0) ? 1 : -1;
+ int check_UINT16_C:
+ (-1 < UINT16_C (0)) == (-1 < (uint_least16_t) 0) ? 1 : -1;
+
+ /* Detect bugs in OpenBSD 3.9 stdint.h. */
+#ifdef UINT8_MAX
+ int check_uint8: (uint8_t) -1 == UINT8_MAX ? 1 : -1;
+#endif
+#ifdef UINT16_MAX
+ int check_uint16: (uint16_t) -1 == UINT16_MAX ? 1 : -1;
+#endif
+#ifdef UINT32_MAX
+ int check_uint32: (uint32_t) -1 == UINT32_MAX ? 1 : -1;
+#endif
+#ifdef UINT64_MAX
+ int check_uint64: (uint64_t) -1 == UINT64_MAX ? 1 : -1;
+#endif
+ int check_uint_least8: (uint_least8_t) -1 == UINT_LEAST8_MAX ? 1 : -1;
+ int check_uint_least16: (uint_least16_t) -1 == UINT_LEAST16_MAX ? 1 : -1;
+ int check_uint_least32: (uint_least32_t) -1 == UINT_LEAST32_MAX ? 1 : -1;
+ int check_uint_least64: (uint_least64_t) -1 == UINT_LEAST64_MAX ? 1 : -1;
+ int check_uint_fast8: (uint_fast8_t) -1 == UINT_FAST8_MAX ? 1 : -1;
+ int check_uint_fast16: (uint_fast16_t) -1 == UINT_FAST16_MAX ? 1 : -1;
+ int check_uint_fast32: (uint_fast32_t) -1 == UINT_FAST32_MAX ? 1 : -1;
+ int check_uint_fast64: (uint_fast64_t) -1 == UINT_FAST64_MAX ? 1 : -1;
+ int check_uintptr: (uintptr_t) -1 == UINTPTR_MAX ? 1 : -1;
+ int check_uintmax: (uintmax_t) -1 == UINTMAX_MAX ? 1 : -1;
+ int check_size: (size_t) -1 == SIZE_MAX ? 1 : -1;
+};
+ ]])],
+ [dnl Determine whether the various *_MIN, *_MAX macros are usable
+ dnl in preprocessor expression. We could do it by compiling a test
+ dnl program for each of these macros. It is faster to run a program
+ dnl that inspects the macro expansion.
+ dnl This detects a bug on HP-UX 11.23/ia64.
+ AC_RUN_IFELSE([
+ AC_LANG_PROGRAM([[
+#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */
+#define __STDC_CONSTANT_MACROS 1
+#define __STDC_LIMIT_MACROS 1
+#include <stdint.h>
+]
+gl_STDINT_INCLUDES
+[
+#include <stdio.h>
+#include <string.h>
+#define MVAL(macro) MVAL1(macro)
+#define MVAL1(expression) #expression
+static const char *macro_values[] =
+ {
+#ifdef INT8_MAX
+ MVAL (INT8_MAX),
+#endif
+#ifdef INT16_MAX
+ MVAL (INT16_MAX),
+#endif
+#ifdef INT32_MAX
+ MVAL (INT32_MAX),
+#endif
+#ifdef INT64_MAX
+ MVAL (INT64_MAX),
+#endif
+#ifdef UINT8_MAX
+ MVAL (UINT8_MAX),
+#endif
+#ifdef UINT16_MAX
+ MVAL (UINT16_MAX),
+#endif
+#ifdef UINT32_MAX
+ MVAL (UINT32_MAX),
+#endif
+#ifdef UINT64_MAX
+ MVAL (UINT64_MAX),
+#endif
+ NULL
+ };
+]], [[
+ const char **mv;
+ for (mv = macro_values; *mv != NULL; mv++)
+ {
+ const char *value = *mv;
+ /* Test whether it looks like a cast expression. */
+ if (strncmp (value, "((unsigned int)"/*)*/, 15) == 0
+ || strncmp (value, "((unsigned short)"/*)*/, 17) == 0
+ || strncmp (value, "((unsigned char)"/*)*/, 16) == 0
+ || strncmp (value, "((int)"/*)*/, 6) == 0
+ || strncmp (value, "((signed short)"/*)*/, 15) == 0
+ || strncmp (value, "((signed char)"/*)*/, 14) == 0)
+ return mv - macro_values + 1;
+ }
+ return 0;
+]])],
+ [gl_cv_header_working_stdint_h=yes],
+ [],
+ [case "$host_os" in
+ # Guess yes on native Windows.
+ mingw*) gl_cv_header_working_stdint_h="guessing yes" ;;
+ # In general, assume it works.
+ *) gl_cv_header_working_stdint_h="guessing yes" ;;
+ esac
+ ])
+ ])
+ ])
+ fi
+
+ HAVE_C99_STDINT_H=0
+ HAVE_SYS_BITYPES_H=0
+ HAVE_SYS_INTTYPES_H=0
+ STDINT_H=stdint.h
+ case "$gl_cv_header_working_stdint_h" in
+ *yes)
+ HAVE_C99_STDINT_H=1
+ dnl Now see whether the system <stdint.h> works without
+ dnl __STDC_CONSTANT_MACROS/__STDC_LIMIT_MACROS defined.
+ AC_CACHE_CHECK([whether stdint.h predates C++11],
+ [gl_cv_header_stdint_predates_cxx11_h],
+ [gl_cv_header_stdint_predates_cxx11_h=yes
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([[
+#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */
+#include <stdint.h>
+]
+gl_STDINT_INCLUDES
+[
+intmax_t im = INTMAX_MAX;
+int32_t i32 = INT32_C (0x7fffffff);
+ ]])],
+ [gl_cv_header_stdint_predates_cxx11_h=no])])
+
+ if test "$gl_cv_header_stdint_predates_cxx11_h" = yes; then
+ AC_DEFINE([__STDC_CONSTANT_MACROS], [1],
+ [Define to 1 if the system <stdint.h> predates C++11.])
+ AC_DEFINE([__STDC_LIMIT_MACROS], [1],
+ [Define to 1 if the system <stdint.h> predates C++11.])
+ fi
+ AC_CACHE_CHECK([whether stdint.h has UINTMAX_WIDTH etc.],
+ [gl_cv_header_stdint_width],
+ [gl_cv_header_stdint_width=no
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ /* Work if build is not clean. */
+ #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1
+ #ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+ #define __STDC_WANT_IEC_60559_BFP_EXT__ 1
+ #endif
+ #include <stdint.h>
+ ]gl_STDINT_INCLUDES[
+ int iw = UINTMAX_WIDTH;
+ ]])],
+ [gl_cv_header_stdint_width=yes])])
+ if test "$gl_cv_header_stdint_width" = yes; then
+ STDINT_H=
+ fi
+ ;;
+ *)
+ dnl Check for <sys/inttypes.h>, and for
+ dnl <sys/bitypes.h> (used in Linux libc4 >= 4.6.7 and libc5).
+ AC_CHECK_HEADERS([sys/inttypes.h sys/bitypes.h])
+ if test $ac_cv_header_sys_inttypes_h = yes; then
+ HAVE_SYS_INTTYPES_H=1
+ fi
+ if test $ac_cv_header_sys_bitypes_h = yes; then
+ HAVE_SYS_BITYPES_H=1
+ fi
+ gl_STDINT_TYPE_PROPERTIES
+ ;;
+ esac
+
+ dnl The substitute stdint.h needs the substitute limit.h's _GL_INTEGER_WIDTH.
+ gl_REPLACE_LIMITS_H
+
+ AC_SUBST([HAVE_C99_STDINT_H])
+ AC_SUBST([HAVE_SYS_BITYPES_H])
+ AC_SUBST([HAVE_SYS_INTTYPES_H])
+ AC_SUBST([STDINT_H])
+ AM_CONDITIONAL([GL_GENERATE_STDINT_H], [test -n "$STDINT_H"])
+])
+
+dnl gl_STDINT_BITSIZEOF(TYPES, INCLUDES)
+dnl Determine the size of each of the given types in bits.
+AC_DEFUN([gl_STDINT_BITSIZEOF],
+[
+ dnl Use a shell loop, to avoid bloating configure, and
+ dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into
+ dnl config.h.in,
+ dnl - extra AC_SUBST calls, so that the right substitutions are made.
+ m4_foreach_w([gltype], [$1],
+ [AH_TEMPLATE([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]),
+ [Define to the number of bits in type ']gltype['.])])
+ for gltype in $1 ; do
+ AC_CACHE_CHECK([for bit size of $gltype], [gl_cv_bitsizeof_${gltype}],
+ [AC_COMPUTE_INT([result], [sizeof ($gltype) * CHAR_BIT],
+ [$2
+#include <limits.h>], [result=unknown])
+ eval gl_cv_bitsizeof_${gltype}=\$result
+ ])
+ eval result=\$gl_cv_bitsizeof_${gltype}
+ if test $result = unknown; then
+ dnl Use a nonempty default, because some compilers, such as IRIX 5 cc,
+ dnl do a syntax check even on unused #if conditions and give an error
+ dnl on valid C code like this:
+ dnl #if 0
+ dnl # if > 32
+ dnl # endif
+ dnl #endif
+ result=0
+ fi
+ GLTYPE=`echo "$gltype" | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+ AC_DEFINE_UNQUOTED([BITSIZEOF_${GLTYPE}], [$result])
+ eval BITSIZEOF_${GLTYPE}=\$result
+ done
+ m4_foreach_w([gltype], [$1],
+ [AC_SUBST([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))])
+])
+
+dnl gl_CHECK_TYPES_SIGNED(TYPES, INCLUDES)
+dnl Determine the signedness of each of the given types.
+dnl Define HAVE_SIGNED_TYPE if type is signed.
+AC_DEFUN([gl_CHECK_TYPES_SIGNED],
+[
+ dnl Use a shell loop, to avoid bloating configure, and
+ dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into
+ dnl config.h.in,
+ dnl - extra AC_SUBST calls, so that the right substitutions are made.
+ m4_foreach_w([gltype], [$1],
+ [AH_TEMPLATE([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]),
+ [Define to 1 if ']gltype[' is a signed integer type.])])
+ for gltype in $1 ; do
+ AC_CACHE_CHECK([whether $gltype is signed], [gl_cv_type_${gltype}_signed],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([$2[
+ int verify[2 * (($gltype) -1 < ($gltype) 0) - 1];]])],
+ result=yes, result=no)
+ eval gl_cv_type_${gltype}_signed=\$result
+ ])
+ eval result=\$gl_cv_type_${gltype}_signed
+ GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+ if test "$result" = yes; then
+ AC_DEFINE_UNQUOTED([HAVE_SIGNED_${GLTYPE}], [1])
+ eval HAVE_SIGNED_${GLTYPE}=1
+ else
+ eval HAVE_SIGNED_${GLTYPE}=0
+ fi
+ done
+ m4_foreach_w([gltype], [$1],
+ [AC_SUBST([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))])
+])
+
+dnl gl_INTEGER_TYPE_SUFFIX(TYPES, INCLUDES)
+dnl Determine the suffix to use for integer constants of the given types.
+dnl Define t_SUFFIX for each such type.
+AC_DEFUN([gl_INTEGER_TYPE_SUFFIX],
+[
+ dnl Use a shell loop, to avoid bloating configure, and
+ dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into
+ dnl config.h.in,
+ dnl - extra AC_SUBST calls, so that the right substitutions are made.
+ m4_foreach_w([gltype], [$1],
+ [AH_TEMPLATE(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX],
+ [Define to l, ll, u, ul, ull, etc., as suitable for
+ constants of type ']gltype['.])])
+ for gltype in $1 ; do
+ AC_CACHE_CHECK([for $gltype integer literal suffix],
+ [gl_cv_type_${gltype}_suffix],
+ [eval gl_cv_type_${gltype}_suffix=no
+ eval result=\$gl_cv_type_${gltype}_signed
+ if test "$result" = yes; then
+ glsufu=
+ else
+ glsufu=u
+ fi
+ for glsuf in "$glsufu" ${glsufu}l ${glsufu}ll ${glsufu}i64; do
+ case $glsuf in
+ '') gltype1='int';;
+ l) gltype1='long int';;
+ ll) gltype1='long long int';;
+ i64) gltype1='__int64';;
+ u) gltype1='unsigned int';;
+ ul) gltype1='unsigned long int';;
+ ull) gltype1='unsigned long long int';;
+ ui64)gltype1='unsigned __int64';;
+ esac
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([$2[
+ extern $gltype foo;
+ extern $gltype1 foo;]])],
+ [eval gl_cv_type_${gltype}_suffix=\$glsuf])
+ eval result=\$gl_cv_type_${gltype}_suffix
+ test "$result" != no && break
+ done])
+ GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+ eval result=\$gl_cv_type_${gltype}_suffix
+ test "$result" = no && result=
+ eval ${GLTYPE}_SUFFIX=\$result
+ AC_DEFINE_UNQUOTED([${GLTYPE}_SUFFIX], [$result])
+ done
+ m4_foreach_w([gltype], [$1],
+ [AC_SUBST(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX])])
+])
+
+dnl gl_STDINT_INCLUDES
+AC_DEFUN([gl_STDINT_INCLUDES],
+[[
+ /* BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+ included before <wchar.h>. */
+ #include <stddef.h>
+ #include <signal.h>
+ #if HAVE_WCHAR_H
+ # include <stdio.h>
+ # include <time.h>
+ # include <wchar.h>
+ #endif
+]])
+
+dnl gl_STDINT_TYPE_PROPERTIES
+dnl Compute HAVE_SIGNED_t, BITSIZEOF_t and t_SUFFIX, for all the types t
+dnl of interest to stdint.in.h.
+AC_DEFUN([gl_STDINT_TYPE_PROPERTIES],
+[
+ AC_REQUIRE([gl_MULTIARCH])
+ if test $APPLE_UNIVERSAL_BUILD = 0; then
+ gl_STDINT_BITSIZEOF([ptrdiff_t size_t],
+ [gl_STDINT_INCLUDES])
+ fi
+ gl_STDINT_BITSIZEOF([sig_atomic_t wchar_t wint_t],
+ [gl_STDINT_INCLUDES])
+ gl_CHECK_TYPES_SIGNED([sig_atomic_t wchar_t wint_t],
+ [gl_STDINT_INCLUDES])
+ gl_cv_type_ptrdiff_t_signed=yes
+ gl_cv_type_size_t_signed=no
+ if test $APPLE_UNIVERSAL_BUILD = 0; then
+ gl_INTEGER_TYPE_SUFFIX([ptrdiff_t size_t],
+ [gl_STDINT_INCLUDES])
+ fi
+ gl_INTEGER_TYPE_SUFFIX([sig_atomic_t wchar_t wint_t],
+ [gl_STDINT_INCLUDES])
+
+ dnl If wint_t is smaller than 'int', it cannot satisfy the ISO C 99
+ dnl requirement that wint_t is "unchanged by default argument promotions".
+ dnl In this case gnulib's <wchar.h> and <wctype.h> override wint_t.
+ dnl Set the variable BITSIZEOF_WINT_T accordingly.
+ if test $GNULIB_OVERRIDES_WINT_T = 1; then
+ BITSIZEOF_WINT_T=32
+ fi
+])
diff --git a/gnulib/m4/stdlib_h.m4 b/gnulib/m4/stdlib_h.m4
new file mode 100644
index 0000000..6121602
--- /dev/null
+++ b/gnulib/m4/stdlib_h.m4
@@ -0,0 +1,136 @@
+# stdlib_h.m4 serial 48
+dnl Copyright (C) 2007-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_STDLIB_H],
+[
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ gl_NEXT_HEADERS([stdlib.h])
+
+ dnl Check for declarations of anything we want to poison if the
+ dnl corresponding gnulib module is not in use, and which is not
+ dnl guaranteed by C89.
+ gl_WARN_ON_USE_PREPARE([[#include <stdlib.h>
+#if HAVE_SYS_LOADAVG_H
+/* OpenIndiana has a bug: <sys/time.h> must be included before
+ <sys/loadavg.h>. */
+# include <sys/time.h>
+# include <sys/loadavg.h>
+#endif
+#if HAVE_RANDOM_H
+# include <random.h>
+#endif
+ ]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt
+ initstate initstate_r mbtowc mkdtemp mkostemp mkostemps mkstemp mkstemps
+ posix_openpt ptsname ptsname_r qsort_r random random_r reallocarray
+ realpath rpmatch secure_getenv setenv setstate setstate_r srandom
+ srandom_r strtod strtold strtoll strtoull unlockpt unsetenv])
+])
+
+AC_DEFUN([gl_STDLIB_MODULE_INDICATOR],
+[
+ dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+ AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+ gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+ dnl Define it also as a C macro, for the benefit of the unit tests.
+ gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+AC_DEFUN([gl_STDLIB_H_DEFAULTS],
+[
+ GNULIB__EXIT=0; AC_SUBST([GNULIB__EXIT])
+ GNULIB_ATOLL=0; AC_SUBST([GNULIB_ATOLL])
+ GNULIB_CALLOC_POSIX=0; AC_SUBST([GNULIB_CALLOC_POSIX])
+ GNULIB_CANONICALIZE_FILE_NAME=0; AC_SUBST([GNULIB_CANONICALIZE_FILE_NAME])
+ GNULIB_GETLOADAVG=0; AC_SUBST([GNULIB_GETLOADAVG])
+ GNULIB_GETSUBOPT=0; AC_SUBST([GNULIB_GETSUBOPT])
+ GNULIB_GRANTPT=0; AC_SUBST([GNULIB_GRANTPT])
+ GNULIB_MALLOC_POSIX=0; AC_SUBST([GNULIB_MALLOC_POSIX])
+ GNULIB_MBTOWC=0; AC_SUBST([GNULIB_MBTOWC])
+ GNULIB_MKDTEMP=0; AC_SUBST([GNULIB_MKDTEMP])
+ GNULIB_MKOSTEMP=0; AC_SUBST([GNULIB_MKOSTEMP])
+ GNULIB_MKOSTEMPS=0; AC_SUBST([GNULIB_MKOSTEMPS])
+ GNULIB_MKSTEMP=0; AC_SUBST([GNULIB_MKSTEMP])
+ GNULIB_MKSTEMPS=0; AC_SUBST([GNULIB_MKSTEMPS])
+ GNULIB_POSIX_OPENPT=0; AC_SUBST([GNULIB_POSIX_OPENPT])
+ GNULIB_PTSNAME=0; AC_SUBST([GNULIB_PTSNAME])
+ GNULIB_PTSNAME_R=0; AC_SUBST([GNULIB_PTSNAME_R])
+ GNULIB_PUTENV=0; AC_SUBST([GNULIB_PUTENV])
+ GNULIB_QSORT_R=0; AC_SUBST([GNULIB_QSORT_R])
+ GNULIB_RANDOM=0; AC_SUBST([GNULIB_RANDOM])
+ GNULIB_RANDOM_R=0; AC_SUBST([GNULIB_RANDOM_R])
+ GNULIB_REALLOCARRAY=0; AC_SUBST([GNULIB_REALLOCARRAY])
+ GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX])
+ GNULIB_REALPATH=0; AC_SUBST([GNULIB_REALPATH])
+ GNULIB_RPMATCH=0; AC_SUBST([GNULIB_RPMATCH])
+ GNULIB_SECURE_GETENV=0; AC_SUBST([GNULIB_SECURE_GETENV])
+ GNULIB_SETENV=0; AC_SUBST([GNULIB_SETENV])
+ GNULIB_STRTOD=0; AC_SUBST([GNULIB_STRTOD])
+ GNULIB_STRTOLD=0; AC_SUBST([GNULIB_STRTOLD])
+ GNULIB_STRTOLL=0; AC_SUBST([GNULIB_STRTOLL])
+ GNULIB_STRTOULL=0; AC_SUBST([GNULIB_STRTOULL])
+ GNULIB_SYSTEM_POSIX=0; AC_SUBST([GNULIB_SYSTEM_POSIX])
+ GNULIB_UNLOCKPT=0; AC_SUBST([GNULIB_UNLOCKPT])
+ GNULIB_UNSETENV=0; AC_SUBST([GNULIB_UNSETENV])
+ GNULIB_WCTOMB=0; AC_SUBST([GNULIB_WCTOMB])
+ dnl Assume proper GNU behavior unless another module says otherwise.
+ HAVE__EXIT=1; AC_SUBST([HAVE__EXIT])
+ HAVE_ATOLL=1; AC_SUBST([HAVE_ATOLL])
+ HAVE_CANONICALIZE_FILE_NAME=1; AC_SUBST([HAVE_CANONICALIZE_FILE_NAME])
+ HAVE_DECL_GETLOADAVG=1; AC_SUBST([HAVE_DECL_GETLOADAVG])
+ HAVE_GETSUBOPT=1; AC_SUBST([HAVE_GETSUBOPT])
+ HAVE_GRANTPT=1; AC_SUBST([HAVE_GRANTPT])
+ HAVE_INITSTATE=1; AC_SUBST([HAVE_INITSTATE])
+ HAVE_DECL_INITSTATE=1; AC_SUBST([HAVE_DECL_INITSTATE])
+ HAVE_MBTOWC=1; AC_SUBST([HAVE_MBTOWC])
+ HAVE_MKDTEMP=1; AC_SUBST([HAVE_MKDTEMP])
+ HAVE_MKOSTEMP=1; AC_SUBST([HAVE_MKOSTEMP])
+ HAVE_MKOSTEMPS=1; AC_SUBST([HAVE_MKOSTEMPS])
+ HAVE_MKSTEMP=1; AC_SUBST([HAVE_MKSTEMP])
+ HAVE_MKSTEMPS=1; AC_SUBST([HAVE_MKSTEMPS])
+ HAVE_POSIX_OPENPT=1; AC_SUBST([HAVE_POSIX_OPENPT])
+ HAVE_PTSNAME=1; AC_SUBST([HAVE_PTSNAME])
+ HAVE_PTSNAME_R=1; AC_SUBST([HAVE_PTSNAME_R])
+ HAVE_QSORT_R=1; AC_SUBST([HAVE_QSORT_R])
+ HAVE_RANDOM=1; AC_SUBST([HAVE_RANDOM])
+ HAVE_RANDOM_H=1; AC_SUBST([HAVE_RANDOM_H])
+ HAVE_RANDOM_R=1; AC_SUBST([HAVE_RANDOM_R])
+ HAVE_REALLOCARRAY=1; AC_SUBST([HAVE_REALLOCARRAY])
+ HAVE_REALPATH=1; AC_SUBST([HAVE_REALPATH])
+ HAVE_RPMATCH=1; AC_SUBST([HAVE_RPMATCH])
+ HAVE_SECURE_GETENV=1; AC_SUBST([HAVE_SECURE_GETENV])
+ HAVE_SETENV=1; AC_SUBST([HAVE_SETENV])
+ HAVE_DECL_SETENV=1; AC_SUBST([HAVE_DECL_SETENV])
+ HAVE_SETSTATE=1; AC_SUBST([HAVE_SETSTATE])
+ HAVE_DECL_SETSTATE=1; AC_SUBST([HAVE_DECL_SETSTATE])
+ HAVE_STRTOD=1; AC_SUBST([HAVE_STRTOD])
+ HAVE_STRTOLD=1; AC_SUBST([HAVE_STRTOLD])
+ HAVE_STRTOLL=1; AC_SUBST([HAVE_STRTOLL])
+ HAVE_STRTOULL=1; AC_SUBST([HAVE_STRTOULL])
+ HAVE_STRUCT_RANDOM_DATA=1; AC_SUBST([HAVE_STRUCT_RANDOM_DATA])
+ HAVE_SYS_LOADAVG_H=0; AC_SUBST([HAVE_SYS_LOADAVG_H])
+ HAVE_UNLOCKPT=1; AC_SUBST([HAVE_UNLOCKPT])
+ HAVE_DECL_UNSETENV=1; AC_SUBST([HAVE_DECL_UNSETENV])
+ REPLACE_CALLOC=0; AC_SUBST([REPLACE_CALLOC])
+ REPLACE_CANONICALIZE_FILE_NAME=0; AC_SUBST([REPLACE_CANONICALIZE_FILE_NAME])
+ REPLACE_INITSTATE=0; AC_SUBST([REPLACE_INITSTATE])
+ REPLACE_MALLOC=0; AC_SUBST([REPLACE_MALLOC])
+ REPLACE_MBTOWC=0; AC_SUBST([REPLACE_MBTOWC])
+ REPLACE_MKSTEMP=0; AC_SUBST([REPLACE_MKSTEMP])
+ REPLACE_PTSNAME=0; AC_SUBST([REPLACE_PTSNAME])
+ REPLACE_PTSNAME_R=0; AC_SUBST([REPLACE_PTSNAME_R])
+ REPLACE_PUTENV=0; AC_SUBST([REPLACE_PUTENV])
+ REPLACE_QSORT_R=0; AC_SUBST([REPLACE_QSORT_R])
+ REPLACE_RANDOM=0; AC_SUBST([REPLACE_RANDOM])
+ REPLACE_RANDOM_R=0; AC_SUBST([REPLACE_RANDOM_R])
+ REPLACE_REALLOC=0; AC_SUBST([REPLACE_REALLOC])
+ REPLACE_REALPATH=0; AC_SUBST([REPLACE_REALPATH])
+ REPLACE_SETENV=0; AC_SUBST([REPLACE_SETENV])
+ REPLACE_SETSTATE=0; AC_SUBST([REPLACE_SETSTATE])
+ REPLACE_STRTOD=0; AC_SUBST([REPLACE_STRTOD])
+ REPLACE_STRTOLD=0; AC_SUBST([REPLACE_STRTOLD])
+ REPLACE_UNSETENV=0; AC_SUBST([REPLACE_UNSETENV])
+ REPLACE_WCTOMB=0; AC_SUBST([REPLACE_WCTOMB])
+])
diff --git a/gnulib/m4/string_h.m4 b/gnulib/m4/string_h.m4
new file mode 100644
index 0000000..0c0e3a7
--- /dev/null
+++ b/gnulib/m4/string_h.m4
@@ -0,0 +1,122 @@
+# Configure a GNU-like replacement for <string.h>.
+
+# Copyright (C) 2007-2019 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 22
+
+# Written by Paul Eggert.
+
+AC_DEFUN([gl_HEADER_STRING_H],
+[
+ dnl Use AC_REQUIRE here, so that the default behavior below is expanded
+ dnl once only, before all statements that occur in other macros.
+ AC_REQUIRE([gl_HEADER_STRING_H_BODY])
+])
+
+AC_DEFUN([gl_HEADER_STRING_H_BODY],
+[
+ AC_REQUIRE([AC_C_RESTRICT])
+ AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+ gl_NEXT_HEADERS([string.h])
+
+ dnl Check for declarations of anything we want to poison if the
+ dnl corresponding gnulib module is not in use, and which is not
+ dnl guaranteed by C89.
+ gl_WARN_ON_USE_PREPARE([[#include <string.h>
+ ]],
+ [ffsl ffsll memmem mempcpy memrchr rawmemchr stpcpy stpncpy strchrnul
+ strdup strncat strndup strnlen strpbrk strsep strcasestr strtok_r
+ strerror_r strsignal strverscmp])
+])
+
+AC_DEFUN([gl_STRING_MODULE_INDICATOR],
+[
+ dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+ AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+ gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+ dnl Define it also as a C macro, for the benefit of the unit tests.
+ gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
+[
+ GNULIB_EXPLICIT_BZERO=0; AC_SUBST([GNULIB_EXPLICIT_BZERO])
+ GNULIB_FFSL=0; AC_SUBST([GNULIB_FFSL])
+ GNULIB_FFSLL=0; AC_SUBST([GNULIB_FFSLL])
+ GNULIB_MEMCHR=0; AC_SUBST([GNULIB_MEMCHR])
+ GNULIB_MEMMEM=0; AC_SUBST([GNULIB_MEMMEM])
+ GNULIB_MEMPCPY=0; AC_SUBST([GNULIB_MEMPCPY])
+ GNULIB_MEMRCHR=0; AC_SUBST([GNULIB_MEMRCHR])
+ GNULIB_RAWMEMCHR=0; AC_SUBST([GNULIB_RAWMEMCHR])
+ GNULIB_STPCPY=0; AC_SUBST([GNULIB_STPCPY])
+ GNULIB_STPNCPY=0; AC_SUBST([GNULIB_STPNCPY])
+ GNULIB_STRCHRNUL=0; AC_SUBST([GNULIB_STRCHRNUL])
+ GNULIB_STRDUP=0; AC_SUBST([GNULIB_STRDUP])
+ GNULIB_STRNCAT=0; AC_SUBST([GNULIB_STRNCAT])
+ GNULIB_STRNDUP=0; AC_SUBST([GNULIB_STRNDUP])
+ GNULIB_STRNLEN=0; AC_SUBST([GNULIB_STRNLEN])
+ GNULIB_STRPBRK=0; AC_SUBST([GNULIB_STRPBRK])
+ GNULIB_STRSEP=0; AC_SUBST([GNULIB_STRSEP])
+ GNULIB_STRSTR=0; AC_SUBST([GNULIB_STRSTR])
+ GNULIB_STRCASESTR=0; AC_SUBST([GNULIB_STRCASESTR])
+ GNULIB_STRTOK_R=0; AC_SUBST([GNULIB_STRTOK_R])
+ GNULIB_MBSLEN=0; AC_SUBST([GNULIB_MBSLEN])
+ GNULIB_MBSNLEN=0; AC_SUBST([GNULIB_MBSNLEN])
+ GNULIB_MBSCHR=0; AC_SUBST([GNULIB_MBSCHR])
+ GNULIB_MBSRCHR=0; AC_SUBST([GNULIB_MBSRCHR])
+ GNULIB_MBSSTR=0; AC_SUBST([GNULIB_MBSSTR])
+ GNULIB_MBSCASECMP=0; AC_SUBST([GNULIB_MBSCASECMP])
+ GNULIB_MBSNCASECMP=0; AC_SUBST([GNULIB_MBSNCASECMP])
+ GNULIB_MBSPCASECMP=0; AC_SUBST([GNULIB_MBSPCASECMP])
+ GNULIB_MBSCASESTR=0; AC_SUBST([GNULIB_MBSCASESTR])
+ GNULIB_MBSCSPN=0; AC_SUBST([GNULIB_MBSCSPN])
+ GNULIB_MBSPBRK=0; AC_SUBST([GNULIB_MBSPBRK])
+ GNULIB_MBSSPN=0; AC_SUBST([GNULIB_MBSSPN])
+ GNULIB_MBSSEP=0; AC_SUBST([GNULIB_MBSSEP])
+ GNULIB_MBSTOK_R=0; AC_SUBST([GNULIB_MBSTOK_R])
+ GNULIB_STRERROR=0; AC_SUBST([GNULIB_STRERROR])
+ GNULIB_STRERROR_R=0; AC_SUBST([GNULIB_STRERROR_R])
+ GNULIB_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL])
+ GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP])
+ HAVE_MBSLEN=0; AC_SUBST([HAVE_MBSLEN])
+ dnl Assume proper GNU behavior unless another module says otherwise.
+ HAVE_EXPLICIT_BZERO=1; AC_SUBST([HAVE_EXPLICIT_BZERO])
+ HAVE_FFSL=1; AC_SUBST([HAVE_FFSL])
+ HAVE_FFSLL=1; AC_SUBST([HAVE_FFSLL])
+ HAVE_MEMCHR=1; AC_SUBST([HAVE_MEMCHR])
+ HAVE_DECL_MEMMEM=1; AC_SUBST([HAVE_DECL_MEMMEM])
+ HAVE_MEMPCPY=1; AC_SUBST([HAVE_MEMPCPY])
+ HAVE_DECL_MEMRCHR=1; AC_SUBST([HAVE_DECL_MEMRCHR])
+ HAVE_RAWMEMCHR=1; AC_SUBST([HAVE_RAWMEMCHR])
+ HAVE_STPCPY=1; AC_SUBST([HAVE_STPCPY])
+ HAVE_STPNCPY=1; AC_SUBST([HAVE_STPNCPY])
+ HAVE_STRCHRNUL=1; AC_SUBST([HAVE_STRCHRNUL])
+ HAVE_DECL_STRDUP=1; AC_SUBST([HAVE_DECL_STRDUP])
+ HAVE_DECL_STRNDUP=1; AC_SUBST([HAVE_DECL_STRNDUP])
+ HAVE_DECL_STRNLEN=1; AC_SUBST([HAVE_DECL_STRNLEN])
+ HAVE_STRPBRK=1; AC_SUBST([HAVE_STRPBRK])
+ HAVE_STRSEP=1; AC_SUBST([HAVE_STRSEP])
+ HAVE_STRCASESTR=1; AC_SUBST([HAVE_STRCASESTR])
+ HAVE_DECL_STRTOK_R=1; AC_SUBST([HAVE_DECL_STRTOK_R])
+ HAVE_DECL_STRERROR_R=1; AC_SUBST([HAVE_DECL_STRERROR_R])
+ HAVE_DECL_STRSIGNAL=1; AC_SUBST([HAVE_DECL_STRSIGNAL])
+ HAVE_STRVERSCMP=1; AC_SUBST([HAVE_STRVERSCMP])
+ REPLACE_MEMCHR=0; AC_SUBST([REPLACE_MEMCHR])
+ REPLACE_MEMMEM=0; AC_SUBST([REPLACE_MEMMEM])
+ REPLACE_STPNCPY=0; AC_SUBST([REPLACE_STPNCPY])
+ REPLACE_STRCHRNUL=0; AC_SUBST([REPLACE_STRCHRNUL])
+ REPLACE_STRDUP=0; AC_SUBST([REPLACE_STRDUP])
+ REPLACE_STRNCAT=0; AC_SUBST([REPLACE_STRNCAT])
+ REPLACE_STRNDUP=0; AC_SUBST([REPLACE_STRNDUP])
+ REPLACE_STRNLEN=0; AC_SUBST([REPLACE_STRNLEN])
+ REPLACE_STRSTR=0; AC_SUBST([REPLACE_STRSTR])
+ REPLACE_STRCASESTR=0; AC_SUBST([REPLACE_STRCASESTR])
+ REPLACE_STRTOK_R=0; AC_SUBST([REPLACE_STRTOK_R])
+ REPLACE_STRERROR=0; AC_SUBST([REPLACE_STRERROR])
+ REPLACE_STRERROR_R=0; AC_SUBST([REPLACE_STRERROR_R])
+ REPLACE_STRSIGNAL=0; AC_SUBST([REPLACE_STRSIGNAL])
+ UNDEFINE_STRTOK_R=0; AC_SUBST([UNDEFINE_STRTOK_R])
+])
diff --git a/gnulib/m4/strndup.m4 b/gnulib/m4/strndup.m4
new file mode 100644
index 0000000..325af5d
--- /dev/null
+++ b/gnulib/m4/strndup.m4
@@ -0,0 +1,58 @@
+# strndup.m4 serial 22
+dnl Copyright (C) 2002-2003, 2005-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_STRNDUP],
+[
+ dnl Persuade glibc <string.h> to declare strndup().
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+ AC_CHECK_DECLS_ONCE([strndup])
+ AC_CHECK_FUNCS_ONCE([strndup])
+ if test $ac_cv_have_decl_strndup = no; then
+ HAVE_DECL_STRNDUP=0
+ fi
+
+ if test $ac_cv_func_strndup = yes; then
+ HAVE_STRNDUP=1
+ # AIX 4.3.3, AIX 5.1 have a function that fails to add the terminating '\0'.
+ AC_CACHE_CHECK([for working strndup], [gl_cv_func_strndup_works],
+ [AC_RUN_IFELSE([
+ AC_LANG_PROGRAM([[#include <string.h>
+ #include <stdlib.h>]], [[
+#if !HAVE_DECL_STRNDUP
+ extern
+ #ifdef __cplusplus
+ "C"
+ #endif
+ char *strndup (const char *, size_t);
+#endif
+ int result;
+ char *s;
+ s = strndup ("some longer string", 15);
+ free (s);
+ s = strndup ("shorter string", 13);
+ result = s[13] != '\0';
+ free (s);
+ return result;]])],
+ [gl_cv_func_strndup_works=yes],
+ [gl_cv_func_strndup_works=no],
+ [
+changequote(,)dnl
+ case $host_os in
+ aix | aix[3-6]*) gl_cv_func_strndup_works="guessing no";;
+ *) gl_cv_func_strndup_works="guessing yes";;
+ esac
+changequote([,])dnl
+ ])])
+ case $gl_cv_func_strndup_works in
+ *no) REPLACE_STRNDUP=1 ;;
+ esac
+ else
+ HAVE_STRNDUP=0
+ fi
+])
diff --git a/gnulib/m4/strnlen.m4 b/gnulib/m4/strnlen.m4
new file mode 100644
index 0000000..c283c3e
--- /dev/null
+++ b/gnulib/m4/strnlen.m4
@@ -0,0 +1,30 @@
+# strnlen.m4 serial 13
+dnl Copyright (C) 2002-2003, 2005-2007, 2009-2019 Free Software Foundation,
+dnl Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_STRNLEN],
+[
+ AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
+
+ dnl Persuade glibc <string.h> to declare strnlen().
+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+ AC_CHECK_DECLS_ONCE([strnlen])
+ if test $ac_cv_have_decl_strnlen = no; then
+ HAVE_DECL_STRNLEN=0
+ else
+ m4_pushdef([AC_LIBOBJ], [:])
+ dnl Note: AC_FUNC_STRNLEN does AC_LIBOBJ([strnlen]).
+ AC_FUNC_STRNLEN
+ m4_popdef([AC_LIBOBJ])
+ if test $ac_cv_func_strnlen_working = no; then
+ REPLACE_STRNLEN=1
+ fi
+ fi
+])
+
+# Prerequisites of lib/strnlen.c.
+AC_DEFUN([gl_PREREQ_STRNLEN], [:])
diff --git a/gnulib/m4/sys_types_h.m4 b/gnulib/m4/sys_types_h.m4
new file mode 100644
index 0000000..be06559
--- /dev/null
+++ b/gnulib/m4/sys_types_h.m4
@@ -0,0 +1,60 @@
+# sys_types_h.m4 serial 9
+dnl Copyright (C) 2011-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN_ONCE([gl_SYS_TYPES_H],
+[
+ dnl Use sane struct stat types in OpenVMS 8.2 and later.
+ AC_DEFINE([_USE_STD_STAT], 1, [For standard stat data types on VMS.])
+
+ AC_REQUIRE([gl_SYS_TYPES_H_DEFAULTS])
+ gl_NEXT_HEADERS([sys/types.h])
+
+ dnl Ensure the type pid_t gets defined.
+ AC_REQUIRE([AC_TYPE_PID_T])
+
+ dnl Ensure the type mode_t gets defined.
+ AC_REQUIRE([AC_TYPE_MODE_T])
+
+ dnl Whether to override the 'off_t' type.
+ AC_REQUIRE([gl_TYPE_OFF_T])
+
+ dnl Whether to override the 'dev_t' and 'ino_t' types.
+ m4_ifdef([gl_WINDOWS_STAT_INODES], [
+ AC_REQUIRE([gl_WINDOWS_STAT_INODES])
+ ], [
+ WINDOWS_STAT_INODES=0
+ ])
+ AC_SUBST([WINDOWS_STAT_INODES])
+])
+
+AC_DEFUN([gl_SYS_TYPES_H_DEFAULTS],
+[
+])
+
+# This works around a buggy version in autoconf <= 2.69.
+# See <https://lists.gnu.org/r/autoconf/2016-08/msg00014.html>
+
+m4_version_prereq([2.70], [], [
+
+# This is taken from the following Autoconf patch:
+# https://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=e17a30e987d7ee695fb4294a82d987ec3dc9b974
+
+m4_undefine([AC_HEADER_MAJOR])
+AC_DEFUN([AC_HEADER_MAJOR],
+[AC_CHECK_HEADERS_ONCE([sys/types.h])
+AC_CHECK_HEADER([sys/mkdev.h],
+ [AC_DEFINE([MAJOR_IN_MKDEV], [1],
+ [Define to 1 if `major', `minor', and `makedev' are declared in
+ <mkdev.h>.])])
+if test $ac_cv_header_sys_mkdev_h = no; then
+ AC_CHECK_HEADER([sys/sysmacros.h],
+ [AC_DEFINE([MAJOR_IN_SYSMACROS], [1],
+ [Define to 1 if `major', `minor', and `makedev' are declared in
+ <sysmacros.h>.])])
+fi
+])
+
+])
diff --git a/gnulib/m4/unistd_h.m4 b/gnulib/m4/unistd_h.m4
new file mode 100644
index 0000000..a3b3905
--- /dev/null
+++ b/gnulib/m4/unistd_h.m4
@@ -0,0 +1,199 @@
+# unistd_h.m4 serial 75
+dnl Copyright (C) 2006-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Written by Simon Josefsson, Bruno Haible.
+
+AC_DEFUN([gl_UNISTD_H],
+[
+ dnl Use AC_REQUIRE here, so that the default behavior below is expanded
+ dnl once only, before all statements that occur in other macros.
+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+
+ gl_CHECK_NEXT_HEADERS([unistd.h])
+ if test $ac_cv_header_unistd_h = yes; then
+ HAVE_UNISTD_H=1
+ else
+ HAVE_UNISTD_H=0
+ fi
+ AC_SUBST([HAVE_UNISTD_H])
+
+ dnl Ensure the type pid_t gets defined.
+ AC_REQUIRE([AC_TYPE_PID_T])
+
+ dnl Determine WINDOWS_64_BIT_OFF_T.
+ AC_REQUIRE([gl_TYPE_OFF_T])
+
+ dnl Check for declarations of anything we want to poison if the
+ dnl corresponding gnulib module is not in use.
+ gl_WARN_ON_USE_PREPARE([[
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+/* Some systems declare various items in the wrong headers. */
+#if !(defined __GLIBC__ && !defined __UCLIBC__)
+# include <fcntl.h>
+# include <stdio.h>
+# include <stdlib.h>
+# if defined _WIN32 && ! defined __CYGWIN__
+# include <io.h>
+# endif
+#endif
+ ]], [chdir chown dup dup2 dup3 environ euidaccess faccessat fchdir fchownat
+ fdatasync fsync ftruncate getcwd getdomainname getdtablesize getgroups
+ gethostname getlogin getlogin_r getpagesize getpass
+ getusershell setusershell endusershell
+ group_member isatty lchown link linkat lseek pipe pipe2 pread pwrite
+ readlink readlinkat rmdir sethostname sleep symlink symlinkat
+ truncate ttyname_r unlink unlinkat usleep])
+])
+
+AC_DEFUN([gl_UNISTD_MODULE_INDICATOR],
+[
+ dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+ gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+ dnl Define it also as a C macro, for the benefit of the unit tests.
+ gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+AC_DEFUN([gl_UNISTD_H_DEFAULTS],
+[
+ GNULIB_CHDIR=0; AC_SUBST([GNULIB_CHDIR])
+ GNULIB_CHOWN=0; AC_SUBST([GNULIB_CHOWN])
+ GNULIB_CLOSE=0; AC_SUBST([GNULIB_CLOSE])
+ GNULIB_COPY_FILE_RANGE=0; AC_SUBST([GNULIB_COPY_FILE_RANGE])
+ GNULIB_DUP=0; AC_SUBST([GNULIB_DUP])
+ GNULIB_DUP2=0; AC_SUBST([GNULIB_DUP2])
+ GNULIB_DUP3=0; AC_SUBST([GNULIB_DUP3])
+ GNULIB_ENVIRON=0; AC_SUBST([GNULIB_ENVIRON])
+ GNULIB_EUIDACCESS=0; AC_SUBST([GNULIB_EUIDACCESS])
+ GNULIB_FACCESSAT=0; AC_SUBST([GNULIB_FACCESSAT])
+ GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR])
+ GNULIB_FCHOWNAT=0; AC_SUBST([GNULIB_FCHOWNAT])
+ GNULIB_FDATASYNC=0; AC_SUBST([GNULIB_FDATASYNC])
+ GNULIB_FSYNC=0; AC_SUBST([GNULIB_FSYNC])
+ GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE])
+ GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD])
+ GNULIB_GETDOMAINNAME=0; AC_SUBST([GNULIB_GETDOMAINNAME])
+ GNULIB_GETDTABLESIZE=0; AC_SUBST([GNULIB_GETDTABLESIZE])
+ GNULIB_GETGROUPS=0; AC_SUBST([GNULIB_GETGROUPS])
+ GNULIB_GETHOSTNAME=0; AC_SUBST([GNULIB_GETHOSTNAME])
+ GNULIB_GETLOGIN=0; AC_SUBST([GNULIB_GETLOGIN])
+ GNULIB_GETLOGIN_R=0; AC_SUBST([GNULIB_GETLOGIN_R])
+ GNULIB_GETPAGESIZE=0; AC_SUBST([GNULIB_GETPAGESIZE])
+ GNULIB_GETPASS=0; AC_SUBST([GNULIB_GETPASS])
+ GNULIB_GETUSERSHELL=0; AC_SUBST([GNULIB_GETUSERSHELL])
+ GNULIB_GROUP_MEMBER=0; AC_SUBST([GNULIB_GROUP_MEMBER])
+ GNULIB_ISATTY=0; AC_SUBST([GNULIB_ISATTY])
+ GNULIB_LCHOWN=0; AC_SUBST([GNULIB_LCHOWN])
+ GNULIB_LINK=0; AC_SUBST([GNULIB_LINK])
+ GNULIB_LINKAT=0; AC_SUBST([GNULIB_LINKAT])
+ GNULIB_LSEEK=0; AC_SUBST([GNULIB_LSEEK])
+ GNULIB_PIPE=0; AC_SUBST([GNULIB_PIPE])
+ GNULIB_PIPE2=0; AC_SUBST([GNULIB_PIPE2])
+ GNULIB_PREAD=0; AC_SUBST([GNULIB_PREAD])
+ GNULIB_PWRITE=0; AC_SUBST([GNULIB_PWRITE])
+ GNULIB_READ=0; AC_SUBST([GNULIB_READ])
+ GNULIB_READLINK=0; AC_SUBST([GNULIB_READLINK])
+ GNULIB_READLINKAT=0; AC_SUBST([GNULIB_READLINKAT])
+ GNULIB_RMDIR=0; AC_SUBST([GNULIB_RMDIR])
+ GNULIB_SETHOSTNAME=0; AC_SUBST([GNULIB_SETHOSTNAME])
+ GNULIB_SLEEP=0; AC_SUBST([GNULIB_SLEEP])
+ GNULIB_SYMLINK=0; AC_SUBST([GNULIB_SYMLINK])
+ GNULIB_SYMLINKAT=0; AC_SUBST([GNULIB_SYMLINKAT])
+ GNULIB_TRUNCATE=0; AC_SUBST([GNULIB_TRUNCATE])
+ GNULIB_TTYNAME_R=0; AC_SUBST([GNULIB_TTYNAME_R])
+ GNULIB_UNISTD_H_NONBLOCKING=0; AC_SUBST([GNULIB_UNISTD_H_NONBLOCKING])
+ GNULIB_UNISTD_H_SIGPIPE=0; AC_SUBST([GNULIB_UNISTD_H_SIGPIPE])
+ GNULIB_UNLINK=0; AC_SUBST([GNULIB_UNLINK])
+ GNULIB_UNLINKAT=0; AC_SUBST([GNULIB_UNLINKAT])
+ GNULIB_USLEEP=0; AC_SUBST([GNULIB_USLEEP])
+ GNULIB_WRITE=0; AC_SUBST([GNULIB_WRITE])
+ dnl Assume proper GNU behavior unless another module says otherwise.
+ HAVE_CHOWN=1; AC_SUBST([HAVE_CHOWN])
+ HAVE_COPY_FILE_RANGE=1; AC_SUBST([HAVE_COPY_FILE_RANGE])
+ HAVE_DUP2=1; AC_SUBST([HAVE_DUP2])
+ HAVE_DUP3=1; AC_SUBST([HAVE_DUP3])
+ HAVE_EUIDACCESS=1; AC_SUBST([HAVE_EUIDACCESS])
+ HAVE_FACCESSAT=1; AC_SUBST([HAVE_FACCESSAT])
+ HAVE_FCHDIR=1; AC_SUBST([HAVE_FCHDIR])
+ HAVE_FCHOWNAT=1; AC_SUBST([HAVE_FCHOWNAT])
+ HAVE_FDATASYNC=1; AC_SUBST([HAVE_FDATASYNC])
+ HAVE_FSYNC=1; AC_SUBST([HAVE_FSYNC])
+ HAVE_FTRUNCATE=1; AC_SUBST([HAVE_FTRUNCATE])
+ HAVE_GETDTABLESIZE=1; AC_SUBST([HAVE_GETDTABLESIZE])
+ HAVE_GETGROUPS=1; AC_SUBST([HAVE_GETGROUPS])
+ HAVE_GETHOSTNAME=1; AC_SUBST([HAVE_GETHOSTNAME])
+ HAVE_GETLOGIN=1; AC_SUBST([HAVE_GETLOGIN])
+ HAVE_GETPAGESIZE=1; AC_SUBST([HAVE_GETPAGESIZE])
+ HAVE_GETPASS=1; AC_SUBST([HAVE_GETPASS])
+ HAVE_GROUP_MEMBER=1; AC_SUBST([HAVE_GROUP_MEMBER])
+ HAVE_LCHOWN=1; AC_SUBST([HAVE_LCHOWN])
+ HAVE_LINK=1; AC_SUBST([HAVE_LINK])
+ HAVE_LINKAT=1; AC_SUBST([HAVE_LINKAT])
+ HAVE_PIPE=1; AC_SUBST([HAVE_PIPE])
+ HAVE_PIPE2=1; AC_SUBST([HAVE_PIPE2])
+ HAVE_PREAD=1; AC_SUBST([HAVE_PREAD])
+ HAVE_PWRITE=1; AC_SUBST([HAVE_PWRITE])
+ HAVE_READLINK=1; AC_SUBST([HAVE_READLINK])
+ HAVE_READLINKAT=1; AC_SUBST([HAVE_READLINKAT])
+ HAVE_SETHOSTNAME=1; AC_SUBST([HAVE_SETHOSTNAME])
+ HAVE_SLEEP=1; AC_SUBST([HAVE_SLEEP])
+ HAVE_SYMLINK=1; AC_SUBST([HAVE_SYMLINK])
+ HAVE_SYMLINKAT=1; AC_SUBST([HAVE_SYMLINKAT])
+ HAVE_UNLINKAT=1; AC_SUBST([HAVE_UNLINKAT])
+ HAVE_USLEEP=1; AC_SUBST([HAVE_USLEEP])
+ HAVE_DECL_ENVIRON=1; AC_SUBST([HAVE_DECL_ENVIRON])
+ HAVE_DECL_FCHDIR=1; AC_SUBST([HAVE_DECL_FCHDIR])
+ HAVE_DECL_FDATASYNC=1; AC_SUBST([HAVE_DECL_FDATASYNC])
+ HAVE_DECL_GETDOMAINNAME=1; AC_SUBST([HAVE_DECL_GETDOMAINNAME])
+ HAVE_DECL_GETLOGIN=1; AC_SUBST([HAVE_DECL_GETLOGIN])
+ HAVE_DECL_GETLOGIN_R=1; AC_SUBST([HAVE_DECL_GETLOGIN_R])
+ HAVE_DECL_GETPAGESIZE=1; AC_SUBST([HAVE_DECL_GETPAGESIZE])
+ HAVE_DECL_GETUSERSHELL=1; AC_SUBST([HAVE_DECL_GETUSERSHELL])
+ HAVE_DECL_SETHOSTNAME=1; AC_SUBST([HAVE_DECL_SETHOSTNAME])
+ HAVE_DECL_TRUNCATE=1; AC_SUBST([HAVE_DECL_TRUNCATE])
+ HAVE_DECL_TTYNAME_R=1; AC_SUBST([HAVE_DECL_TTYNAME_R])
+ HAVE_OS_H=0; AC_SUBST([HAVE_OS_H])
+ HAVE_SYS_PARAM_H=0; AC_SUBST([HAVE_SYS_PARAM_H])
+ REPLACE_CHOWN=0; AC_SUBST([REPLACE_CHOWN])
+ REPLACE_CLOSE=0; AC_SUBST([REPLACE_CLOSE])
+ REPLACE_DUP=0; AC_SUBST([REPLACE_DUP])
+ REPLACE_DUP2=0; AC_SUBST([REPLACE_DUP2])
+ REPLACE_FACCESSAT=0; AC_SUBST([REPLACE_FACCESSAT])
+ REPLACE_FCHOWNAT=0; AC_SUBST([REPLACE_FCHOWNAT])
+ REPLACE_FTRUNCATE=0; AC_SUBST([REPLACE_FTRUNCATE])
+ REPLACE_GETCWD=0; AC_SUBST([REPLACE_GETCWD])
+ REPLACE_GETDOMAINNAME=0; AC_SUBST([REPLACE_GETDOMAINNAME])
+ REPLACE_GETDTABLESIZE=0; AC_SUBST([REPLACE_GETDTABLESIZE])
+ REPLACE_GETLOGIN_R=0; AC_SUBST([REPLACE_GETLOGIN_R])
+ REPLACE_GETGROUPS=0; AC_SUBST([REPLACE_GETGROUPS])
+ REPLACE_GETPAGESIZE=0; AC_SUBST([REPLACE_GETPAGESIZE])
+ REPLACE_GETPASS=0; AC_SUBST([REPLACE_GETPASS])
+ REPLACE_ISATTY=0; AC_SUBST([REPLACE_ISATTY])
+ REPLACE_LCHOWN=0; AC_SUBST([REPLACE_LCHOWN])
+ REPLACE_LINK=0; AC_SUBST([REPLACE_LINK])
+ REPLACE_LINKAT=0; AC_SUBST([REPLACE_LINKAT])
+ REPLACE_LSEEK=0; AC_SUBST([REPLACE_LSEEK])
+ REPLACE_PREAD=0; AC_SUBST([REPLACE_PREAD])
+ REPLACE_PWRITE=0; AC_SUBST([REPLACE_PWRITE])
+ REPLACE_READ=0; AC_SUBST([REPLACE_READ])
+ REPLACE_READLINK=0; AC_SUBST([REPLACE_READLINK])
+ REPLACE_READLINKAT=0; AC_SUBST([REPLACE_READLINKAT])
+ REPLACE_RMDIR=0; AC_SUBST([REPLACE_RMDIR])
+ REPLACE_SLEEP=0; AC_SUBST([REPLACE_SLEEP])
+ REPLACE_SYMLINK=0; AC_SUBST([REPLACE_SYMLINK])
+ REPLACE_SYMLINKAT=0; AC_SUBST([REPLACE_SYMLINKAT])
+ REPLACE_TRUNCATE=0; AC_SUBST([REPLACE_TRUNCATE])
+ REPLACE_TTYNAME_R=0; AC_SUBST([REPLACE_TTYNAME_R])
+ REPLACE_UNLINK=0; AC_SUBST([REPLACE_UNLINK])
+ REPLACE_UNLINKAT=0; AC_SUBST([REPLACE_UNLINKAT])
+ REPLACE_USLEEP=0; AC_SUBST([REPLACE_USLEEP])
+ REPLACE_WRITE=0; AC_SUBST([REPLACE_WRITE])
+ UNISTD_H_HAVE_WINSOCK2_H=0; AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H])
+ UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS=0;
+ AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS])
+])
diff --git a/gnulib/m4/warn-on-use.m4 b/gnulib/m4/warn-on-use.m4
new file mode 100644
index 0000000..7ebe2d3
--- /dev/null
+++ b/gnulib/m4/warn-on-use.m4
@@ -0,0 +1,51 @@
+# warn-on-use.m4 serial 6
+dnl Copyright (C) 2010-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# gl_WARN_ON_USE_PREPARE(INCLUDES, NAMES)
+# ---------------------------------------
+# If the module 'posixcheck' is in use:
+#
+# For each whitespace-separated element in the list of NAMES, define
+# HAVE_RAW_DECL_name if the function has a declaration among INCLUDES
+# even after being undefined as a macro.
+#
+# See warn-on-use.h for some hints on how to poison function names, as
+# well as ideas on poisoning global variables and macros. NAMES may
+# include global variables, but remember that only functions work with
+# _GL_WARN_ON_USE. Typically, INCLUDES only needs to list a single
+# header, but if the replacement header pulls in other headers because
+# some systems declare functions in the wrong header, then INCLUDES
+# should do likewise.
+#
+# It is generally safe to assume declarations for functions declared
+# in the intersection of C89 and C11 (such as printf) without
+# needing gl_WARN_ON_USE_PREPARE.
+AC_DEFUN([gl_WARN_ON_USE_PREPARE],
+[
+ m4_ifdef([gl_POSIXCHECK],
+ [m4_foreach_w([gl_decl], [$2],
+ [AH_TEMPLATE([HAVE_RAW_DECL_]AS_TR_CPP(m4_defn([gl_decl])),
+ [Define to 1 if ]m4_defn([gl_decl])[ is declared even after
+ undefining macros.])])dnl
+dnl FIXME: gl_Symbol must be used unquoted until we can assume
+dnl autoconf 2.64 or newer.
+ for gl_func in m4_flatten([$2]); do
+ AS_VAR_PUSHDEF([gl_Symbol], [gl_cv_have_raw_decl_$gl_func])dnl
+ AC_CACHE_CHECK([whether $gl_func is declared without a macro],
+ gl_Symbol,
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$1],
+[@%:@undef $gl_func
+ (void) $gl_func;])],
+ [AS_VAR_SET(gl_Symbol, [yes])], [AS_VAR_SET(gl_Symbol, [no])])])
+ AS_VAR_IF(gl_Symbol, [yes],
+ [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_RAW_DECL_$gl_func]), [1])
+ dnl shortcut - if the raw declaration exists, then set a cache
+ dnl variable to allow skipping any later AC_CHECK_DECL efforts
+ eval ac_cv_have_decl_$gl_func=yes])
+ AS_VAR_POPDEF([gl_Symbol])dnl
+ done
+ ])
+])
diff --git a/gnulib/m4/warnings.m4 b/gnulib/m4/warnings.m4
new file mode 100644
index 0000000..235cac6
--- /dev/null
+++ b/gnulib/m4/warnings.m4
@@ -0,0 +1,115 @@
+# warnings.m4 serial 14
+dnl Copyright (C) 2008-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Simon Josefsson
+
+# gl_AS_VAR_APPEND(VAR, VALUE)
+# ----------------------------
+# Provide the functionality of AS_VAR_APPEND if Autoconf does not have it.
+m4_ifdef([AS_VAR_APPEND],
+[m4_copy([AS_VAR_APPEND], [gl_AS_VAR_APPEND])],
+[m4_define([gl_AS_VAR_APPEND],
+[AS_VAR_SET([$1], [AS_VAR_GET([$1])$2])])])
+
+
+# gl_COMPILER_OPTION_IF(OPTION, [IF-SUPPORTED], [IF-NOT-SUPPORTED],
+# [PROGRAM = AC_LANG_PROGRAM()])
+# -----------------------------------------------------------------
+# Check if the compiler supports OPTION when compiling PROGRAM.
+#
+# The effects of this macro depend on the current language (_AC_LANG).
+AC_DEFUN([gl_COMPILER_OPTION_IF],
+[
+dnl FIXME: gl_Warn must be used unquoted until we can assume Autoconf
+dnl 2.64 or newer.
+AS_VAR_PUSHDEF([gl_Warn], [gl_cv_warn_[]_AC_LANG_ABBREV[]_$1])dnl
+AS_VAR_PUSHDEF([gl_Flags], [_AC_LANG_PREFIX[]FLAGS])dnl
+AS_LITERAL_IF([$1],
+ [m4_pushdef([gl_Positive], m4_bpatsubst([$1], [^-Wno-], [-W]))],
+ [gl_positive="$1"
+case $gl_positive in
+ -Wno-*) gl_positive=-W`expr "X$gl_positive" : 'X-Wno-\(.*\)'` ;;
+esac
+m4_pushdef([gl_Positive], [$gl_positive])])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler handles $1], m4_defn([gl_Warn]), [
+ gl_save_compiler_FLAGS="$gl_Flags"
+ gl_AS_VAR_APPEND(m4_defn([gl_Flags]),
+ [" $gl_unknown_warnings_are_errors ]m4_defn([gl_Positive])["])
+ AC_LINK_IFELSE([m4_default([$4], [AC_LANG_PROGRAM([])])],
+ [AS_VAR_SET(gl_Warn, [yes])],
+ [AS_VAR_SET(gl_Warn, [no])])
+ gl_Flags="$gl_save_compiler_FLAGS"
+])
+AS_VAR_IF(gl_Warn, [yes], [$2], [$3])
+m4_popdef([gl_Positive])dnl
+AS_VAR_POPDEF([gl_Flags])dnl
+AS_VAR_POPDEF([gl_Warn])dnl
+])
+
+# gl_UNKNOWN_WARNINGS_ARE_ERRORS
+# ------------------------------
+# Clang doesn't complain about unknown warning options unless one also
+# specifies -Wunknown-warning-option -Werror. Detect this.
+#
+# The effects of this macro depend on the current language (_AC_LANG).
+AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS],
+[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)])
+
+# Specialization for _AC_LANG = C. This macro can be AC_REQUIREd.
+# Use of m4_defun rather than AC_DEFUN works around a bug in autoconf < 2.63b.
+m4_defun([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C)],
+[
+ AC_LANG_PUSH([C])
+ gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL
+ AC_LANG_POP([C])
+])
+
+# Specialization for _AC_LANG = C++. This macro can be AC_REQUIREd.
+# Use of m4_defun rather than AC_DEFUN works around a bug in autoconf < 2.63b.
+m4_defun([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C++)],
+[
+ AC_LANG_PUSH([C++])
+ gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL
+ AC_LANG_POP([C++])
+])
+
+# Specialization for _AC_LANG = Objective C. This macro can be AC_REQUIREd.
+# Use of m4_defun rather than AC_DEFUN works around a bug in autoconf < 2.63b.
+m4_defun([gl_UNKNOWN_WARNINGS_ARE_ERRORS(Objective C)],
+[
+ AC_LANG_PUSH([Objective C])
+ gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL
+ AC_LANG_POP([Objective C])
+])
+
+AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL],
+[gl_COMPILER_OPTION_IF([-Werror -Wunknown-warning-option],
+ [gl_unknown_warnings_are_errors='-Wunknown-warning-option -Werror'],
+ [gl_unknown_warnings_are_errors=])])
+
+# gl_WARN_ADD(OPTION, [VARIABLE = WARN_CFLAGS/WARN_CXXFLAGS],
+# [PROGRAM = AC_LANG_PROGRAM()])
+# -----------------------------------------------------------
+# Adds parameter to WARN_CFLAGS/WARN_CXXFLAGS if the compiler supports it
+# when compiling PROGRAM. For example, gl_WARN_ADD([-Wparentheses]).
+#
+# If VARIABLE is a variable name, AC_SUBST it.
+#
+# The effects of this macro depend on the current language (_AC_LANG).
+AC_DEFUN([gl_WARN_ADD],
+[AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS(]_AC_LANG[)])
+gl_COMPILER_OPTION_IF([$1],
+ [gl_AS_VAR_APPEND(m4_if([$2], [], [[WARN_]_AC_LANG_PREFIX[FLAGS]], [[$2]]), [" $1"])],
+ [],
+ [$3])
+m4_ifval([$2],
+ [AS_LITERAL_IF([$2], [AC_SUBST([$2])])],
+ [AC_SUBST([WARN_]_AC_LANG_PREFIX[FLAGS])])dnl
+])
+
+# Local Variables:
+# mode: autoconf
+# End:
diff --git a/gnulib/m4/wchar_t.m4 b/gnulib/m4/wchar_t.m4
new file mode 100644
index 0000000..5db5815
--- /dev/null
+++ b/gnulib/m4/wchar_t.m4
@@ -0,0 +1,24 @@
+# wchar_t.m4 serial 4 (gettext-0.18.2)
+dnl Copyright (C) 2002-2003, 2008-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Test whether <stddef.h> has the 'wchar_t' type.
+dnl Prerequisite: AC_PROG_CC
+
+AC_DEFUN([gt_TYPE_WCHAR_T],
+[
+ AC_CACHE_CHECK([for wchar_t], [gt_cv_c_wchar_t],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <stddef.h>
+ wchar_t foo = (wchar_t)'\0';]],
+ [[]])],
+ [gt_cv_c_wchar_t=yes],
+ [gt_cv_c_wchar_t=no])])
+ if test $gt_cv_c_wchar_t = yes; then
+ AC_DEFINE([HAVE_WCHAR_T], [1], [Define if you have the 'wchar_t' type.])
+ fi
+])
diff --git a/gnulib/m4/wint_t.m4 b/gnulib/m4/wint_t.m4
new file mode 100644
index 0000000..61e8a23
--- /dev/null
+++ b/gnulib/m4/wint_t.m4
@@ -0,0 +1,74 @@
+# wint_t.m4 serial 7
+dnl Copyright (C) 2003, 2007-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Test whether <wchar.h> has the 'wint_t' type and whether gnulib's
+dnl <wchar.h> or <wctype.h> would, if present, override 'wint_t'.
+dnl Prerequisite: AC_PROG_CC
+
+AC_DEFUN([gt_TYPE_WINT_T],
+[
+ AC_CACHE_CHECK([for wint_t], [gt_cv_c_wint_t],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+ <wchar.h>.
+ BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be included
+ before <wchar.h>. */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+ wint_t foo = (wchar_t)'\0';]],
+ [[]])],
+ [gt_cv_c_wint_t=yes],
+ [gt_cv_c_wint_t=no])])
+ if test $gt_cv_c_wint_t = yes; then
+ AC_DEFINE([HAVE_WINT_T], [1], [Define if you have the 'wint_t' type.])
+
+ dnl Determine whether gnulib's <wchar.h> or <wctype.h> would, if present,
+ dnl override 'wint_t'.
+ AC_CACHE_CHECK([whether wint_t is too small],
+ [gl_cv_type_wint_t_too_small],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+ <wchar.h>.
+ BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+ included before <wchar.h>. */
+#if !(defined __GLIBC__ && !defined __UCLIBC__)
+# include <stddef.h>
+# include <stdio.h>
+# include <time.h>
+#endif
+#include <wchar.h>
+ int verify[sizeof (wint_t) < sizeof (int) ? -1 : 1];
+ ]])],
+ [gl_cv_type_wint_t_too_small=no],
+ [gl_cv_type_wint_t_too_small=yes])])
+ if test $gl_cv_type_wint_t_too_small = yes; then
+ GNULIB_OVERRIDES_WINT_T=1
+ else
+ GNULIB_OVERRIDES_WINT_T=0
+ fi
+ else
+ GNULIB_OVERRIDES_WINT_T=0
+ fi
+ AC_SUBST([GNULIB_OVERRIDES_WINT_T])
+])
+
+dnl Prerequisites of the 'wint_t' override.
+AC_DEFUN([gl_TYPE_WINT_T_PREREQ],
+[
+ AC_CHECK_HEADERS_ONCE([crtdefs.h])
+ if test $ac_cv_header_crtdefs_h = yes; then
+ HAVE_CRTDEFS_H=1
+ else
+ HAVE_CRTDEFS_H=0
+ fi
+ AC_SUBST([HAVE_CRTDEFS_H])
+])
diff --git a/gnulib/malloc.c b/gnulib/malloc.c
new file mode 100644
index 0000000..76e6ff7
--- /dev/null
+++ b/gnulib/malloc.c
@@ -0,0 +1,56 @@
+/* malloc() function that is glibc compatible.
+
+ Copyright (C) 1997-1998, 2006-2007, 2009-2019 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+/* written by Jim Meyering and Bruno Haible */
+
+#define _GL_USE_STDLIB_ALLOC 1
+#include <config.h>
+/* Only the AC_FUNC_MALLOC macro defines 'malloc' already in config.h. */
+#ifdef malloc
+# define NEED_MALLOC_GNU 1
+# undef malloc
+/* Whereas the gnulib module 'malloc-gnu' defines HAVE_MALLOC_GNU. */
+#elif GNULIB_MALLOC_GNU && !HAVE_MALLOC_GNU
+# define NEED_MALLOC_GNU 1
+#endif
+
+#include <stdlib.h>
+
+#include <errno.h>
+
+/* Allocate an N-byte block of memory from the heap.
+ If N is zero, allocate a 1-byte block. */
+
+void *
+rpl_malloc (size_t n)
+{
+ void *result;
+
+#if NEED_MALLOC_GNU
+ if (n == 0)
+ n = 1;
+#endif
+
+ result = malloc (n);
+
+#if !HAVE_MALLOC_POSIX
+ if (result == NULL)
+ errno = ENOMEM;
+#endif
+
+ return result;
+}
diff --git a/gnulib/malloca.c b/gnulib/malloca.c
new file mode 100644
index 0000000..f60c5fb
--- /dev/null
+++ b/gnulib/malloca.c
@@ -0,0 +1,105 @@
+/* Safe automatic memory allocation.
+ Copyright (C) 2003, 2006-2007, 2009-2019 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2003, 2018.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+#define _GL_USE_STDLIB_ALLOC 1
+#include <config.h>
+
+/* Specification. */
+#include "malloca.h"
+
+#include "verify.h"
+
+/* The speed critical point in this file is freea() applied to an alloca()
+ result: it must be fast, to match the speed of alloca(). The speed of
+ mmalloca() and freea() in the other case are not critical, because they
+ are only invoked for big memory sizes.
+ Here we use a bit in the address as an indicator, an idea by Ondřej Bílka.
+ malloca() can return three types of pointers:
+ - Pointers ≡ 0 mod 2*sa_alignment_max come from stack allocation.
+ - Pointers ≡ sa_alignment_max mod 2*sa_alignment_max come from heap
+ allocation.
+ - NULL comes from a failed heap allocation. */
+
+/* Type for holding very small pointer differences. */
+typedef unsigned char small_t;
+/* Verify that it is wide enough. */
+verify (2 * sa_alignment_max - 1 <= (small_t) -1);
+
+void *
+mmalloca (size_t n)
+{
+#if HAVE_ALLOCA
+ /* Allocate one more word, used to determine the address to pass to freea(),
+ and room for the alignment ≡ sa_alignment_max mod 2*sa_alignment_max. */
+ size_t nplus = n + sizeof (small_t) + 2 * sa_alignment_max - 1;
+
+ if (nplus >= n)
+ {
+ char *mem = (char *) malloc (nplus);
+
+ if (mem != NULL)
+ {
+ char *p =
+ (char *)((((uintptr_t)mem + sizeof (small_t) + sa_alignment_max - 1)
+ & ~(uintptr_t)(2 * sa_alignment_max - 1))
+ + sa_alignment_max);
+ /* Here p >= mem + sizeof (small_t),
+ and p <= mem + sizeof (small_t) + 2 * sa_alignment_max - 1
+ hence p + n <= mem + nplus.
+ So, the memory range [p, p+n) lies in the allocated memory range
+ [mem, mem + nplus). */
+ ((small_t *) p)[-1] = p - mem;
+ /* p ≡ sa_alignment_max mod 2*sa_alignment_max. */
+ return p;
+ }
+ }
+ /* Out of memory. */
+ return NULL;
+#else
+# if !MALLOC_0_IS_NONNULL
+ if (n == 0)
+ n = 1;
+# endif
+ return malloc (n);
+#endif
+}
+
+#if HAVE_ALLOCA
+void
+freea (void *p)
+{
+ /* Check argument. */
+ if ((uintptr_t) p & (sa_alignment_max - 1))
+ {
+ /* p was not the result of a malloca() call. Invalid argument. */
+ abort ();
+ }
+ /* Determine whether p was a non-NULL pointer returned by mmalloca(). */
+ if ((uintptr_t) p & sa_alignment_max)
+ {
+ void *mem = (char *) p - ((small_t *) p)[-1];
+ free (mem);
+ }
+}
+#endif
+
+/*
+ * Hey Emacs!
+ * Local Variables:
+ * coding: utf-8
+ * End:
+ */
diff --git a/gnulib/malloca.h b/gnulib/malloca.h
new file mode 100644
index 0000000..d80c316
--- /dev/null
+++ b/gnulib/malloca.h
@@ -0,0 +1,127 @@
+/* Safe automatic memory allocation.
+ Copyright (C) 2003-2007, 2009-2019 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2003.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _MALLOCA_H
+#define _MALLOCA_H
+
+#include <alloca.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "xalloc-oversized.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* safe_alloca(N) is equivalent to alloca(N) when it is safe to call
+ alloca(N); otherwise it returns NULL. It either returns N bytes of
+ memory allocated on the stack, that lasts until the function returns,
+ or NULL.
+ Use of safe_alloca should be avoided:
+ - inside arguments of function calls - undefined behaviour,
+ - in inline functions - the allocation may actually last until the
+ calling function returns.
+*/
+#if HAVE_ALLOCA
+/* The OS usually guarantees only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ allocate anything larger than 4096 bytes. Also care for the possibility
+ of a few compiler-allocated temporary stack slots.
+ This must be a macro, not a function. */
+# define safe_alloca(N) ((N) < 4032 ? alloca (N) : NULL)
+#else
+# define safe_alloca(N) ((void) (N), NULL)
+#endif
+
+/* malloca(N) is a safe variant of alloca(N). It allocates N bytes of
+ memory allocated on the stack, that must be freed using freea() before
+ the function returns. Upon failure, it returns NULL. */
+#if HAVE_ALLOCA
+# define malloca(N) \
+ ((N) < 4032 - (2 * sa_alignment_max - 1) \
+ ? (void *) (((uintptr_t) (char *) alloca ((N) + 2 * sa_alignment_max - 1) \
+ + (2 * sa_alignment_max - 1)) \
+ & ~(uintptr_t)(2 * sa_alignment_max - 1)) \
+ : mmalloca (N))
+#else
+# define malloca(N) \
+ mmalloca (N)
+#endif
+extern void * mmalloca (size_t n);
+
+/* Free a block of memory allocated through malloca(). */
+#if HAVE_ALLOCA
+extern void freea (void *p);
+#else
+# define freea free
+#endif
+
+/* nmalloca(N,S) is an overflow-safe variant of malloca (N * S).
+ It allocates an array of N objects, each with S bytes of memory,
+ on the stack. S must be positive and N must be nonnegative.
+ The array must be freed using freea() before the function returns. */
+#define nmalloca(n, s) (xalloc_oversized (n, s) ? NULL : malloca ((n) * (s)))
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* ------------------- Auxiliary, non-public definitions ------------------- */
+
+/* Determine the alignment of a type at compile time. */
+#if defined __GNUC__ || defined __IBM__ALIGNOF__
+# define sa_alignof __alignof__
+#elif defined __cplusplus
+ template <class type> struct sa_alignof_helper { char __slot1; type __slot2; };
+# define sa_alignof(type) offsetof (sa_alignof_helper<type>, __slot2)
+#elif defined __hpux
+ /* Work around a HP-UX 10.20 cc bug with enums constants defined as offsetof
+ values. */
+# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
+#elif defined _AIX
+ /* Work around an AIX 3.2.5 xlc bug with enums constants defined as offsetof
+ values. */
+# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
+#else
+# define sa_alignof(type) offsetof (struct { char __slot1; type __slot2; }, __slot2)
+#endif
+
+enum
+{
+/* The desired alignment of memory allocations is the maximum alignment
+ among all elementary types. */
+ sa_alignment_long = sa_alignof (long),
+ sa_alignment_double = sa_alignof (double),
+#if HAVE_LONG_LONG_INT
+ sa_alignment_longlong = sa_alignof (long long),
+#endif
+ sa_alignment_longdouble = sa_alignof (long double),
+ sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1)
+#if HAVE_LONG_LONG_INT
+ | (sa_alignment_longlong - 1)
+#endif
+ | (sa_alignment_longdouble - 1)
+ ) + 1
+};
+
+#endif /* _MALLOCA_H */
diff --git a/gnulib/realloc.c b/gnulib/realloc.c
new file mode 100644
index 0000000..a81ce3b
--- /dev/null
+++ b/gnulib/realloc.c
@@ -0,0 +1,79 @@
+/* realloc() function that is glibc compatible.
+
+ Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2019 Free Software
+ Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* written by Jim Meyering and Bruno Haible */
+
+#define _GL_USE_STDLIB_ALLOC 1
+#include <config.h>
+
+/* Only the AC_FUNC_REALLOC macro defines 'realloc' already in config.h. */
+#ifdef realloc
+# define NEED_REALLOC_GNU 1
+/* Whereas the gnulib module 'realloc-gnu' defines HAVE_REALLOC_GNU. */
+#elif GNULIB_REALLOC_GNU && !HAVE_REALLOC_GNU
+# define NEED_REALLOC_GNU 1
+#endif
+
+/* Infer the properties of the system's malloc function.
+ The gnulib module 'malloc-gnu' defines HAVE_MALLOC_GNU. */
+#if GNULIB_MALLOC_GNU && HAVE_MALLOC_GNU
+# define SYSTEM_MALLOC_GLIBC_COMPATIBLE 1
+#endif
+
+#include <stdlib.h>
+
+#include <errno.h>
+
+/* Change the size of an allocated block of memory P to N bytes,
+ with error checking. If N is zero, change it to 1. If P is NULL,
+ use malloc. */
+
+void *
+rpl_realloc (void *p, size_t n)
+{
+ void *result;
+
+#if NEED_REALLOC_GNU
+ if (n == 0)
+ {
+ n = 1;
+
+ /* In theory realloc might fail, so don't rely on it to free. */
+ free (p);
+ p = NULL;
+ }
+#endif
+
+ if (p == NULL)
+ {
+#if GNULIB_REALLOC_GNU && !NEED_REALLOC_GNU && !SYSTEM_MALLOC_GLIBC_COMPATIBLE
+ if (n == 0)
+ n = 1;
+#endif
+ result = malloc (n);
+ }
+ else
+ result = realloc (p, n);
+
+#if !HAVE_REALLOC_POSIX
+ if (result == NULL)
+ errno = ENOMEM;
+#endif
+
+ return result;
+}
diff --git a/gnulib/setenv.c b/gnulib/setenv.c
new file mode 100644
index 0000000..733b257
--- /dev/null
+++ b/gnulib/setenv.c
@@ -0,0 +1,390 @@
+/* Copyright (C) 1992, 1995-2003, 2005-2019 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#if !_LIBC
+/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
+ optimizes away the name == NULL test below. */
+# define _GL_ARG_NONNULL(params)
+
+# define _GL_USE_STDLIB_ALLOC 1
+# include <config.h>
+#endif
+
+#include <alloca.h>
+
+/* Specification. */
+#include <stdlib.h>
+
+#include <errno.h>
+#ifndef __set_errno
+# define __set_errno(ev) ((errno) = (ev))
+#endif
+
+#include <string.h>
+#if _LIBC || HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if !_LIBC
+# include "malloca.h"
+#endif
+
+#if _LIBC || !HAVE_SETENV
+
+#if !_LIBC
+# define __environ environ
+#endif
+
+#if _LIBC
+/* This lock protects against simultaneous modifications of 'environ'. */
+# include <bits/libc-lock.h>
+__libc_lock_define_initialized (static, envlock)
+# define LOCK __libc_lock_lock (envlock)
+# define UNLOCK __libc_lock_unlock (envlock)
+#else
+# define LOCK
+# define UNLOCK
+#endif
+
+/* In the GNU C library we must keep the namespace clean. */
+#ifdef _LIBC
+# define setenv __setenv
+# define clearenv __clearenv
+# define tfind __tfind
+# define tsearch __tsearch
+#endif
+
+/* In the GNU C library implementation we try to be more clever and
+ allow arbitrarily many changes of the environment given that the used
+ values are from a small set. Outside glibc this will eat up all
+ memory after a while. */
+#if defined _LIBC || (defined HAVE_SEARCH_H && defined HAVE_TSEARCH \
+ && defined __GNUC__)
+# define USE_TSEARCH 1
+# include <search.h>
+typedef int (*compar_fn_t) (const void *, const void *);
+
+/* This is a pointer to the root of the search tree with the known
+ values. */
+static void *known_values;
+
+# define KNOWN_VALUE(Str) \
+ ({ \
+ void *value = tfind (Str, &known_values, (compar_fn_t) strcmp); \
+ value != NULL ? *(char **) value : NULL; \
+ })
+# define STORE_VALUE(Str) \
+ tsearch (Str, &known_values, (compar_fn_t) strcmp)
+
+#else
+# undef USE_TSEARCH
+
+# define KNOWN_VALUE(Str) NULL
+# define STORE_VALUE(Str) do { } while (0)
+
+#endif
+
+
+/* If this variable is not a null pointer we allocated the current
+ environment. */
+static char **last_environ;
+
+
+/* This function is used by 'setenv' and 'putenv'. The difference between
+ the two functions is that for the former must create a new string which
+ is then placed in the environment, while the argument of 'putenv'
+ must be used directly. This is all complicated by the fact that we try
+ to reuse values once generated for a 'setenv' call since we can never
+ free the strings. */
+int
+__add_to_environ (const char *name, const char *value, const char *combined,
+ int replace)
+{
+ char **ep;
+ size_t size;
+ const size_t namelen = strlen (name);
+ const size_t vallen = value != NULL ? strlen (value) + 1 : 0;
+
+ LOCK;
+
+ /* We have to get the pointer now that we have the lock and not earlier
+ since another thread might have created a new environment. */
+ ep = __environ;
+
+ size = 0;
+ if (ep != NULL)
+ {
+ for (; *ep != NULL; ++ep)
+ if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
+ break;
+ else
+ ++size;
+ }
+
+ if (ep == NULL || *ep == NULL)
+ {
+ char **new_environ;
+#ifdef USE_TSEARCH
+ char *new_value;
+#endif
+
+ /* We allocated this space; we can extend it. */
+ new_environ =
+ (char **) (last_environ == NULL
+ ? malloc ((size + 2) * sizeof (char *))
+ : realloc (last_environ, (size + 2) * sizeof (char *)));
+ if (new_environ == NULL)
+ {
+ /* It's easier to set errno to ENOMEM than to rely on the
+ 'malloc-posix' and 'realloc-posix' gnulib modules. */
+ __set_errno (ENOMEM);
+ UNLOCK;
+ return -1;
+ }
+
+ /* If the whole entry is given add it. */
+ if (combined != NULL)
+ /* We must not add the string to the search tree since it belongs
+ to the user. */
+ new_environ[size] = (char *) combined;
+ else
+ {
+ /* See whether the value is already known. */
+#ifdef USE_TSEARCH
+# ifdef _LIBC
+ new_value = (char *) alloca (namelen + 1 + vallen);
+ __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
+ value, vallen);
+# else
+ new_value = (char *) malloca (namelen + 1 + vallen);
+ if (new_value == NULL)
+ {
+ __set_errno (ENOMEM);
+ UNLOCK;
+ return -1;
+ }
+ memcpy (new_value, name, namelen);
+ new_value[namelen] = '=';
+ memcpy (&new_value[namelen + 1], value, vallen);
+# endif
+
+ new_environ[size] = KNOWN_VALUE (new_value);
+ if (new_environ[size] == NULL)
+#endif
+ {
+ new_environ[size] = (char *) malloc (namelen + 1 + vallen);
+ if (new_environ[size] == NULL)
+ {
+#if defined USE_TSEARCH && !defined _LIBC
+ freea (new_value);
+#endif
+ __set_errno (ENOMEM);
+ UNLOCK;
+ return -1;
+ }
+
+#ifdef USE_TSEARCH
+ memcpy (new_environ[size], new_value, namelen + 1 + vallen);
+#else
+ memcpy (new_environ[size], name, namelen);
+ new_environ[size][namelen] = '=';
+ memcpy (&new_environ[size][namelen + 1], value, vallen);
+#endif
+ /* And save the value now. We cannot do this when we remove
+ the string since then we cannot decide whether it is a
+ user string or not. */
+ STORE_VALUE (new_environ[size]);
+ }
+#if defined USE_TSEARCH && !defined _LIBC
+ freea (new_value);
+#endif
+ }
+
+ if (__environ != last_environ)
+ memcpy ((char *) new_environ, (char *) __environ,
+ size * sizeof (char *));
+
+ new_environ[size + 1] = NULL;
+
+ last_environ = __environ = new_environ;
+ }
+ else if (replace)
+ {
+ char *np;
+
+ /* Use the user string if given. */
+ if (combined != NULL)
+ np = (char *) combined;
+ else
+ {
+#ifdef USE_TSEARCH
+ char *new_value;
+# ifdef _LIBC
+ new_value = alloca (namelen + 1 + vallen);
+ __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
+ value, vallen);
+# else
+ new_value = malloca (namelen + 1 + vallen);
+ if (new_value == NULL)
+ {
+ __set_errno (ENOMEM);
+ UNLOCK;
+ return -1;
+ }
+ memcpy (new_value, name, namelen);
+ new_value[namelen] = '=';
+ memcpy (&new_value[namelen + 1], value, vallen);
+# endif
+
+ np = KNOWN_VALUE (new_value);
+ if (np == NULL)
+#endif
+ {
+ np = (char *) malloc (namelen + 1 + vallen);
+ if (np == NULL)
+ {
+#if defined USE_TSEARCH && !defined _LIBC
+ freea (new_value);
+#endif
+ __set_errno (ENOMEM);
+ UNLOCK;
+ return -1;
+ }
+
+#ifdef USE_TSEARCH
+ memcpy (np, new_value, namelen + 1 + vallen);
+#else
+ memcpy (np, name, namelen);
+ np[namelen] = '=';
+ memcpy (&np[namelen + 1], value, vallen);
+#endif
+ /* And remember the value. */
+ STORE_VALUE (np);
+ }
+#if defined USE_TSEARCH && !defined _LIBC
+ freea (new_value);
+#endif
+ }
+
+ *ep = np;
+ }
+
+ UNLOCK;
+
+ return 0;
+}
+
+int
+setenv (const char *name, const char *value, int replace)
+{
+ if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ return __add_to_environ (name, value, NULL, replace);
+}
+
+/* The 'clearenv' was planned to be added to POSIX.1 but probably
+ never made it. Nevertheless the POSIX.9 standard (POSIX bindings
+ for Fortran 77) requires this function. */
+int
+clearenv (void)
+{
+ LOCK;
+
+ if (__environ == last_environ && __environ != NULL)
+ {
+ /* We allocated this environment so we can free it. */
+ free (__environ);
+ last_environ = NULL;
+ }
+
+ /* Clear the environment pointer removes the whole environment. */
+ __environ = NULL;
+
+ UNLOCK;
+
+ return 0;
+}
+
+#ifdef _LIBC
+static void
+free_mem (void)
+{
+ /* Remove all traces. */
+ clearenv ();
+
+ /* Now remove the search tree. */
+ __tdestroy (known_values, free);
+ known_values = NULL;
+}
+text_set_element (__libc_subfreeres, free_mem);
+
+
+# undef setenv
+# undef clearenv
+weak_alias (__setenv, setenv)
+weak_alias (__clearenv, clearenv)
+#endif
+
+#endif /* _LIBC || !HAVE_SETENV */
+
+/* The rest of this file is called into use when replacing an existing
+ but buggy setenv. Known bugs include failure to diagnose invalid
+ name, and consuming a leading '=' from value. */
+#if HAVE_SETENV
+
+# undef setenv
+# if !HAVE_DECL_SETENV
+extern int setenv (const char *, const char *, int);
+# endif
+# define STREQ(a, b) (strcmp (a, b) == 0)
+
+int
+rpl_setenv (const char *name, const char *value, int replace)
+{
+ int result;
+ if (!name || !*name || strchr (name, '='))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ /* Call the real setenv even if replace is 0, in case implementation
+ has underlying data to update, such as when environ changes. */
+ result = setenv (name, value, replace);
+ if (result == 0 && replace && *value == '=')
+ {
+ char *tmp = getenv (name);
+ if (!STREQ (tmp, value))
+ {
+ int saved_errno;
+ size_t len = strlen (value);
+ tmp = malloca (len + 2);
+ /* Since leading '=' is eaten, double it up. */
+ *tmp = '=';
+ memcpy (tmp + 1, value, len + 1);
+ result = setenv (name, tmp, replace);
+ saved_errno = errno;
+ freea (tmp);
+ errno = saved_errno;
+ }
+ }
+ return result;
+}
+
+#endif /* HAVE_SETENV */
diff --git a/gnulib/stddef.in.h b/gnulib/stddef.in.h
new file mode 100644
index 0000000..5aad121
--- /dev/null
+++ b/gnulib/stddef.in.h
@@ -0,0 +1,114 @@
+/* A substitute for POSIX 2008 <stddef.h>, for platforms that have issues.
+
+ Copyright (C) 2009-2019 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Eric Blake. */
+
+/*
+ * POSIX 2008 <stddef.h> for platforms that have issues.
+ * <http://www.opengroup.org/susv3xbd/stddef.h.html>
+ */
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+#if defined __need_wchar_t || defined __need_size_t \
+ || defined __need_ptrdiff_t || defined __need_NULL \
+ || defined __need_wint_t
+/* Special invocation convention inside gcc header files. In
+ particular, gcc provides a version of <stddef.h> that blindly
+ redefines NULL even when __need_wint_t was defined, even though
+ wint_t is not normally provided by <stddef.h>. Hence, we must
+ remember if special invocation has ever been used to obtain wint_t,
+ in which case we need to clean up NULL yet again. */
+
+# if !(defined _@GUARD_PREFIX@_STDDEF_H && defined _GL_STDDEF_WINT_T)
+# ifdef __need_wint_t
+# define _GL_STDDEF_WINT_T
+# endif
+# @INCLUDE_NEXT@ @NEXT_STDDEF_H@
+# endif
+
+#else
+/* Normal invocation convention. */
+
+# ifndef _@GUARD_PREFIX@_STDDEF_H
+
+/* The include_next requires a split double-inclusion guard. */
+
+# @INCLUDE_NEXT@ @NEXT_STDDEF_H@
+
+/* On NetBSD 5.0, the definition of NULL lacks proper parentheses. */
+# if (@REPLACE_NULL@ \
+ && (!defined _@GUARD_PREFIX@_STDDEF_H || defined _GL_STDDEF_WINT_T))
+# undef NULL
+# ifdef __cplusplus
+ /* ISO C++ says that the macro NULL must expand to an integer constant
+ expression, hence '((void *) 0)' is not allowed in C++. */
+# if __GNUG__ >= 3
+ /* GNU C++ has a __null macro that behaves like an integer ('int' or
+ 'long') but has the same size as a pointer. Use that, to avoid
+ warnings. */
+# define NULL __null
+# else
+# define NULL 0L
+# endif
+# else
+# define NULL ((void *) 0)
+# endif
+# endif
+
+# ifndef _@GUARD_PREFIX@_STDDEF_H
+# define _@GUARD_PREFIX@_STDDEF_H
+
+/* Some platforms lack wchar_t. */
+#if !@HAVE_WCHAR_T@
+# define wchar_t int
+#endif
+
+/* Some platforms lack max_align_t. The check for _GCC_MAX_ALIGN_T is
+ a hack in case the configure-time test was done with g++ even though
+ we are currently compiling with gcc. */
+#if ! (@HAVE_MAX_ALIGN_T@ || defined _GCC_MAX_ALIGN_T)
+# if !GNULIB_defined_max_align_t
+/* On the x86, the maximum storage alignment of double, long, etc. is 4,
+ but GCC's C11 ABI for x86 says that max_align_t has an alignment of 8,
+ and the C11 standard allows this. Work around this problem by
+ using __alignof__ (which returns 8 for double) rather than _Alignof
+ (which returns 4), and align each union member accordingly. */
+# ifdef __GNUC__
+# define _GL_STDDEF_ALIGNAS(type) \
+ __attribute__ ((__aligned__ (__alignof__ (type))))
+# else
+# define _GL_STDDEF_ALIGNAS(type) /* */
+# endif
+typedef union
+{
+ char *__p _GL_STDDEF_ALIGNAS (char *);
+ double __d _GL_STDDEF_ALIGNAS (double);
+ long double __ld _GL_STDDEF_ALIGNAS (long double);
+ long int __i _GL_STDDEF_ALIGNAS (long int);
+} rpl_max_align_t;
+# define max_align_t rpl_max_align_t
+# define GNULIB_defined_max_align_t 1
+# endif
+#endif
+
+# endif /* _@GUARD_PREFIX@_STDDEF_H */
+# endif /* _@GUARD_PREFIX@_STDDEF_H */
+#endif /* __need_XXX */
diff --git a/gnulib/stdint.in.h b/gnulib/stdint.in.h
new file mode 100644
index 0000000..21dd8d2
--- /dev/null
+++ b/gnulib/stdint.in.h
@@ -0,0 +1,726 @@
+/* Copyright (C) 2001-2002, 2004-2019 Free Software Foundation, Inc.
+ Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood.
+ This file is part of gnulib.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+/*
+ * ISO C 99 <stdint.h> for platforms that lack it.
+ * <http://www.opengroup.org/susv3xbd/stdint.h.html>
+ */
+
+#ifndef _@GUARD_PREFIX@_STDINT_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+/* When including a system file that in turn includes <inttypes.h>,
+ use the system <inttypes.h>, not our substitute. This avoids
+ problems with (for example) VMS, whose <sys/bitypes.h> includes
+ <inttypes.h>. */
+#define _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H
+
+/* On Android (Bionic libc), <sys/types.h> includes this file before
+ having defined 'time_t'. Therefore in this case avoid including
+ other system header files; just include the system's <stdint.h>.
+ Ideally we should test __BIONIC__ here, but it is only defined after
+ <sys/cdefs.h> has been included; hence test __ANDROID__ instead. */
+#if defined __ANDROID__ && defined _GL_INCLUDING_SYS_TYPES_H
+# @INCLUDE_NEXT@ @NEXT_STDINT_H@
+#else
+
+/* Get those types that are already defined in other system include
+ files, so that we can "#define int8_t signed char" below without
+ worrying about a later system include file containing a "typedef
+ signed char int8_t;" that will get messed up by our macro. Our
+ macros should all be consistent with the system versions, except
+ for the "fast" types and macros, which we recommend against using
+ in public interfaces due to compiler differences. */
+
+#if @HAVE_STDINT_H@
+# if defined __sgi && ! defined __c99
+ /* Bypass IRIX's <stdint.h> if in C89 mode, since it merely annoys users
+ with "This header file is to be used only for c99 mode compilations"
+ diagnostics. */
+# define __STDINT_H__
+# endif
+
+ /* Some pre-C++11 <stdint.h> implementations need this. */
+# ifdef __cplusplus
+# ifndef __STDC_CONSTANT_MACROS
+# define __STDC_CONSTANT_MACROS 1
+# endif
+# ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS 1
+# endif
+# endif
+
+ /* Other systems may have an incomplete or buggy <stdint.h>.
+ Include it before <inttypes.h>, since any "#include <stdint.h>"
+ in <inttypes.h> would reinclude us, skipping our contents because
+ _@GUARD_PREFIX@_STDINT_H is defined.
+ The include_next requires a split double-inclusion guard. */
+# @INCLUDE_NEXT@ @NEXT_STDINT_H@
+#endif
+
+#if ! defined _@GUARD_PREFIX@_STDINT_H && ! defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H
+#define _@GUARD_PREFIX@_STDINT_H
+
+/* Get SCHAR_MIN, SCHAR_MAX, UCHAR_MAX, INT_MIN, INT_MAX,
+ LONG_MIN, LONG_MAX, ULONG_MAX, _GL_INTEGER_WIDTH. */
+#include <limits.h>
+
+/* Override WINT_MIN and WINT_MAX if gnulib's <wchar.h> or <wctype.h> overrides
+ wint_t. */
+#if @GNULIB_OVERRIDES_WINT_T@
+# undef WINT_MIN
+# undef WINT_MAX
+# define WINT_MIN 0x0U
+# define WINT_MAX 0xffffffffU
+#endif
+
+#if ! @HAVE_C99_STDINT_H@
+
+/* <sys/types.h> defines some of the stdint.h types as well, on glibc,
+ IRIX 6.5, and OpenBSD 3.8 (via <machine/types.h>).
+ AIX 5.2 <sys/types.h> isn't needed and causes troubles.
+ Mac OS X 10.4.6 <sys/types.h> includes <stdint.h> (which is us), but
+ relies on the system <stdint.h> definitions, so include
+ <sys/types.h> after @NEXT_STDINT_H@. */
+# if @HAVE_SYS_TYPES_H@ && ! defined _AIX
+# include <sys/types.h>
+# endif
+
+# if @HAVE_INTTYPES_H@
+ /* In OpenBSD 3.8, <inttypes.h> includes <machine/types.h>, which defines
+ int{8,16,32,64}_t, uint{8,16,32,64}_t and __BIT_TYPES_DEFINED__.
+ <inttypes.h> also defines intptr_t and uintptr_t. */
+# include <inttypes.h>
+# elif @HAVE_SYS_INTTYPES_H@
+ /* Solaris 7 <sys/inttypes.h> has the types except the *_fast*_t types, and
+ the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX. */
+# include <sys/inttypes.h>
+# endif
+
+# if @HAVE_SYS_BITYPES_H@ && ! defined __BIT_TYPES_DEFINED__
+ /* Linux libc4 >= 4.6.7 and libc5 have a <sys/bitypes.h> that defines
+ int{8,16,32,64}_t and __BIT_TYPES_DEFINED__. In libc5 >= 5.2.2 it is
+ included by <sys/types.h>. */
+# include <sys/bitypes.h>
+# endif
+
+# undef _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H
+
+/* Minimum and maximum values for an integer type under the usual assumption.
+ Return an unspecified value if BITS == 0, adding a check to pacify
+ picky compilers. */
+
+/* These are separate macros, because if you try to merge these macros into
+ a single one, HP-UX cc rejects the resulting expression in constant
+ expressions. */
+# define _STDINT_UNSIGNED_MIN(bits, zero) \
+ (zero)
+# define _STDINT_SIGNED_MIN(bits, zero) \
+ (~ _STDINT_MAX (1, bits, zero))
+
+# define _STDINT_MAX(signed, bits, zero) \
+ (((((zero) + 1) << ((bits) ? (bits) - 1 - (signed) : 0)) - 1) * 2 + 1)
+
+#if !GNULIB_defined_stdint_types
+
+/* 7.18.1.1. Exact-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+ types have 8, 16, 32, optionally 64 bits. */
+
+# undef int8_t
+# undef uint8_t
+typedef signed char gl_int8_t;
+typedef unsigned char gl_uint8_t;
+# define int8_t gl_int8_t
+# define uint8_t gl_uint8_t
+
+# undef int16_t
+# undef uint16_t
+typedef short int gl_int16_t;
+typedef unsigned short int gl_uint16_t;
+# define int16_t gl_int16_t
+# define uint16_t gl_uint16_t
+
+# undef int32_t
+# undef uint32_t
+typedef int gl_int32_t;
+typedef unsigned int gl_uint32_t;
+# define int32_t gl_int32_t
+# define uint32_t gl_uint32_t
+
+/* If the system defines INT64_MAX, assume int64_t works. That way,
+ if the underlying platform defines int64_t to be a 64-bit long long
+ int, the code below won't mistakenly define it to be a 64-bit long
+ int, which would mess up C++ name mangling. We must use #ifdef
+ rather than #if, to avoid an error with HP-UX 10.20 cc. */
+
+# ifdef INT64_MAX
+# define GL_INT64_T
+# else
+/* Do not undefine int64_t if gnulib is not being used with 64-bit
+ types, since otherwise it breaks platforms like Tandem/NSK. */
+# if LONG_MAX >> 31 >> 31 == 1
+# undef int64_t
+typedef long int gl_int64_t;
+# define int64_t gl_int64_t
+# define GL_INT64_T
+# elif defined _MSC_VER
+# undef int64_t
+typedef __int64 gl_int64_t;
+# define int64_t gl_int64_t
+# define GL_INT64_T
+# elif @HAVE_LONG_LONG_INT@
+# undef int64_t
+typedef long long int gl_int64_t;
+# define int64_t gl_int64_t
+# define GL_INT64_T
+# endif
+# endif
+
+# ifdef UINT64_MAX
+# define GL_UINT64_T
+# else
+# if ULONG_MAX >> 31 >> 31 >> 1 == 1
+# undef uint64_t
+typedef unsigned long int gl_uint64_t;
+# define uint64_t gl_uint64_t
+# define GL_UINT64_T
+# elif defined _MSC_VER
+# undef uint64_t
+typedef unsigned __int64 gl_uint64_t;
+# define uint64_t gl_uint64_t
+# define GL_UINT64_T
+# elif @HAVE_UNSIGNED_LONG_LONG_INT@
+# undef uint64_t
+typedef unsigned long long int gl_uint64_t;
+# define uint64_t gl_uint64_t
+# define GL_UINT64_T
+# endif
+# endif
+
+/* Avoid collision with Solaris 2.5.1 <pthread.h> etc. */
+# define _UINT8_T
+# define _UINT32_T
+# define _UINT64_T
+
+
+/* 7.18.1.2. Minimum-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+ types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types
+ are the same as the corresponding N_t types. */
+
+# undef int_least8_t
+# undef uint_least8_t
+# undef int_least16_t
+# undef uint_least16_t
+# undef int_least32_t
+# undef uint_least32_t
+# undef int_least64_t
+# undef uint_least64_t
+# define int_least8_t int8_t
+# define uint_least8_t uint8_t
+# define int_least16_t int16_t
+# define uint_least16_t uint16_t
+# define int_least32_t int32_t
+# define uint_least32_t uint32_t
+# ifdef GL_INT64_T
+# define int_least64_t int64_t
+# endif
+# ifdef GL_UINT64_T
+# define uint_least64_t uint64_t
+# endif
+
+/* 7.18.1.3. Fastest minimum-width integer types */
+
+/* Note: Other <stdint.h> substitutes may define these types differently.
+ It is not recommended to use these types in public header files. */
+
+/* Here we assume a standard architecture where the hardware integer
+ types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types
+ are taken from the same list of types. The following code normally
+ uses types consistent with glibc, as that lessens the chance of
+ incompatibility with older GNU hosts. */
+
+# undef int_fast8_t
+# undef uint_fast8_t
+# undef int_fast16_t
+# undef uint_fast16_t
+# undef int_fast32_t
+# undef uint_fast32_t
+# undef int_fast64_t
+# undef uint_fast64_t
+typedef signed char gl_int_fast8_t;
+typedef unsigned char gl_uint_fast8_t;
+
+# ifdef __sun
+/* Define types compatible with SunOS 5.10, so that code compiled under
+ earlier SunOS versions works with code compiled under SunOS 5.10. */
+typedef int gl_int_fast32_t;
+typedef unsigned int gl_uint_fast32_t;
+# else
+typedef long int gl_int_fast32_t;
+typedef unsigned long int gl_uint_fast32_t;
+# endif
+typedef gl_int_fast32_t gl_int_fast16_t;
+typedef gl_uint_fast32_t gl_uint_fast16_t;
+
+# define int_fast8_t gl_int_fast8_t
+# define uint_fast8_t gl_uint_fast8_t
+# define int_fast16_t gl_int_fast16_t
+# define uint_fast16_t gl_uint_fast16_t
+# define int_fast32_t gl_int_fast32_t
+# define uint_fast32_t gl_uint_fast32_t
+# ifdef GL_INT64_T
+# define int_fast64_t int64_t
+# endif
+# ifdef GL_UINT64_T
+# define uint_fast64_t uint64_t
+# endif
+
+/* 7.18.1.4. Integer types capable of holding object pointers */
+
+/* kLIBC's stdint.h defines _INTPTR_T_DECLARED and needs its own
+ definitions of intptr_t and uintptr_t (which use int and unsigned)
+ to avoid clashes with declarations of system functions like sbrk. */
+# ifndef _INTPTR_T_DECLARED
+# undef intptr_t
+# undef uintptr_t
+typedef long int gl_intptr_t;
+typedef unsigned long int gl_uintptr_t;
+# define intptr_t gl_intptr_t
+# define uintptr_t gl_uintptr_t
+# endif
+
+/* 7.18.1.5. Greatest-width integer types */
+
+/* Note: These types are compiler dependent. It may be unwise to use them in
+ public header files. */
+
+/* If the system defines INTMAX_MAX, assume that intmax_t works, and
+ similarly for UINTMAX_MAX and uintmax_t. This avoids problems with
+ assuming one type where another is used by the system. */
+
+# ifndef INTMAX_MAX
+# undef INTMAX_C
+# undef intmax_t
+# if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1
+typedef long long int gl_intmax_t;
+# define intmax_t gl_intmax_t
+# elif defined GL_INT64_T
+# define intmax_t int64_t
+# else
+typedef long int gl_intmax_t;
+# define intmax_t gl_intmax_t
+# endif
+# endif
+
+# ifndef UINTMAX_MAX
+# undef UINTMAX_C
+# undef uintmax_t
+# if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1
+typedef unsigned long long int gl_uintmax_t;
+# define uintmax_t gl_uintmax_t
+# elif defined GL_UINT64_T
+# define uintmax_t uint64_t
+# else
+typedef unsigned long int gl_uintmax_t;
+# define uintmax_t gl_uintmax_t
+# endif
+# endif
+
+/* Verify that intmax_t and uintmax_t have the same size. Too much code
+ breaks if this is not the case. If this check fails, the reason is likely
+ to be found in the autoconf macros. */
+typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t)
+ ? 1 : -1];
+
+# define GNULIB_defined_stdint_types 1
+# endif /* !GNULIB_defined_stdint_types */
+
+/* 7.18.2. Limits of specified-width integer types */
+
+/* 7.18.2.1. Limits of exact-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+ types have 8, 16, 32, optionally 64 bits. */
+
+# undef INT8_MIN
+# undef INT8_MAX
+# undef UINT8_MAX
+# define INT8_MIN (~ INT8_MAX)
+# define INT8_MAX 127
+# define UINT8_MAX 255
+
+# undef INT16_MIN
+# undef INT16_MAX
+# undef UINT16_MAX
+# define INT16_MIN (~ INT16_MAX)
+# define INT16_MAX 32767
+# define UINT16_MAX 65535
+
+# undef INT32_MIN
+# undef INT32_MAX
+# undef UINT32_MAX
+# define INT32_MIN (~ INT32_MAX)
+# define INT32_MAX 2147483647
+# define UINT32_MAX 4294967295U
+
+# if defined GL_INT64_T && ! defined INT64_MAX
+/* Prefer (- INTMAX_C (1) << 63) over (~ INT64_MAX) because SunPRO C 5.0
+ evaluates the latter incorrectly in preprocessor expressions. */
+# define INT64_MIN (- INTMAX_C (1) << 63)
+# define INT64_MAX INTMAX_C (9223372036854775807)
+# endif
+
+# if defined GL_UINT64_T && ! defined UINT64_MAX
+# define UINT64_MAX UINTMAX_C (18446744073709551615)
+# endif
+
+/* 7.18.2.2. Limits of minimum-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+ types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types
+ are the same as the corresponding N_t types. */
+
+# undef INT_LEAST8_MIN
+# undef INT_LEAST8_MAX
+# undef UINT_LEAST8_MAX
+# define INT_LEAST8_MIN INT8_MIN
+# define INT_LEAST8_MAX INT8_MAX
+# define UINT_LEAST8_MAX UINT8_MAX
+
+# undef INT_LEAST16_MIN
+# undef INT_LEAST16_MAX
+# undef UINT_LEAST16_MAX
+# define INT_LEAST16_MIN INT16_MIN
+# define INT_LEAST16_MAX INT16_MAX
+# define UINT_LEAST16_MAX UINT16_MAX
+
+# undef INT_LEAST32_MIN
+# undef INT_LEAST32_MAX
+# undef UINT_LEAST32_MAX
+# define INT_LEAST32_MIN INT32_MIN
+# define INT_LEAST32_MAX INT32_MAX
+# define UINT_LEAST32_MAX UINT32_MAX
+
+# undef INT_LEAST64_MIN
+# undef INT_LEAST64_MAX
+# ifdef GL_INT64_T
+# define INT_LEAST64_MIN INT64_MIN
+# define INT_LEAST64_MAX INT64_MAX
+# endif
+
+# undef UINT_LEAST64_MAX
+# ifdef GL_UINT64_T
+# define UINT_LEAST64_MAX UINT64_MAX
+# endif
+
+/* 7.18.2.3. Limits of fastest minimum-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+ types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types
+ are taken from the same list of types. */
+
+# undef INT_FAST8_MIN
+# undef INT_FAST8_MAX
+# undef UINT_FAST8_MAX
+# define INT_FAST8_MIN SCHAR_MIN
+# define INT_FAST8_MAX SCHAR_MAX
+# define UINT_FAST8_MAX UCHAR_MAX
+
+# undef INT_FAST16_MIN
+# undef INT_FAST16_MAX
+# undef UINT_FAST16_MAX
+# define INT_FAST16_MIN INT_FAST32_MIN
+# define INT_FAST16_MAX INT_FAST32_MAX
+# define UINT_FAST16_MAX UINT_FAST32_MAX
+
+# undef INT_FAST32_MIN
+# undef INT_FAST32_MAX
+# undef UINT_FAST32_MAX
+# ifdef __sun
+# define INT_FAST32_MIN INT_MIN
+# define INT_FAST32_MAX INT_MAX
+# define UINT_FAST32_MAX UINT_MAX
+# else
+# define INT_FAST32_MIN LONG_MIN
+# define INT_FAST32_MAX LONG_MAX
+# define UINT_FAST32_MAX ULONG_MAX
+# endif
+
+# undef INT_FAST64_MIN
+# undef INT_FAST64_MAX
+# ifdef GL_INT64_T
+# define INT_FAST64_MIN INT64_MIN
+# define INT_FAST64_MAX INT64_MAX
+# endif
+
+# undef UINT_FAST64_MAX
+# ifdef GL_UINT64_T
+# define UINT_FAST64_MAX UINT64_MAX
+# endif
+
+/* 7.18.2.4. Limits of integer types capable of holding object pointers */
+
+# undef INTPTR_MIN
+# undef INTPTR_MAX
+# undef UINTPTR_MAX
+# define INTPTR_MIN LONG_MIN
+# define INTPTR_MAX LONG_MAX
+# define UINTPTR_MAX ULONG_MAX
+
+/* 7.18.2.5. Limits of greatest-width integer types */
+
+# ifndef INTMAX_MAX
+# undef INTMAX_MIN
+# ifdef INT64_MAX
+# define INTMAX_MIN INT64_MIN
+# define INTMAX_MAX INT64_MAX
+# else
+# define INTMAX_MIN INT32_MIN
+# define INTMAX_MAX INT32_MAX
+# endif
+# endif
+
+# ifndef UINTMAX_MAX
+# ifdef UINT64_MAX
+# define UINTMAX_MAX UINT64_MAX
+# else
+# define UINTMAX_MAX UINT32_MAX
+# endif
+# endif
+
+/* 7.18.3. Limits of other integer types */
+
+/* ptrdiff_t limits */
+# undef PTRDIFF_MIN
+# undef PTRDIFF_MAX
+# if @APPLE_UNIVERSAL_BUILD@
+# ifdef _LP64
+# define PTRDIFF_MIN _STDINT_SIGNED_MIN (64, 0l)
+# define PTRDIFF_MAX _STDINT_MAX (1, 64, 0l)
+# else
+# define PTRDIFF_MIN _STDINT_SIGNED_MIN (32, 0)
+# define PTRDIFF_MAX _STDINT_MAX (1, 32, 0)
+# endif
+# else
+# define PTRDIFF_MIN \
+ _STDINT_SIGNED_MIN (@BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@)
+# define PTRDIFF_MAX \
+ _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@)
+# endif
+
+/* sig_atomic_t limits */
+# undef SIG_ATOMIC_MIN
+# undef SIG_ATOMIC_MAX
+# if @HAVE_SIGNED_SIG_ATOMIC_T@
+# define SIG_ATOMIC_MIN \
+ _STDINT_SIGNED_MIN (@BITSIZEOF_SIG_ATOMIC_T@, 0@SIG_ATOMIC_T_SUFFIX@)
+# else
+# define SIG_ATOMIC_MIN \
+ _STDINT_UNSIGNED_MIN (@BITSIZEOF_SIG_ATOMIC_T@, 0@SIG_ATOMIC_T_SUFFIX@)
+# endif
+# define SIG_ATOMIC_MAX \
+ _STDINT_MAX (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \
+ 0@SIG_ATOMIC_T_SUFFIX@)
+
+
+/* size_t limit */
+# undef SIZE_MAX
+# if @APPLE_UNIVERSAL_BUILD@
+# ifdef _LP64
+# define SIZE_MAX _STDINT_MAX (0, 64, 0ul)
+# else
+# define SIZE_MAX _STDINT_MAX (0, 32, 0ul)
+# endif
+# else
+# define SIZE_MAX _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0@SIZE_T_SUFFIX@)
+# endif
+
+/* wchar_t limits */
+/* Get WCHAR_MIN, WCHAR_MAX.
+ This include is not on the top, above, because on OSF/1 4.0 we have a
+ sequence of nested includes
+ <wchar.h> -> <stdio.h> -> <getopt.h> -> <stdlib.h>, and the latter includes
+ <stdint.h> and assumes its types are already defined. */
+# if @HAVE_WCHAR_H@ && ! (defined WCHAR_MIN && defined WCHAR_MAX)
+ /* BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+ included before <wchar.h>. */
+# include <stddef.h>
+# include <stdio.h>
+# include <time.h>
+# define _GL_JUST_INCLUDE_SYSTEM_WCHAR_H
+# include <wchar.h>
+# undef _GL_JUST_INCLUDE_SYSTEM_WCHAR_H
+# endif
+# undef WCHAR_MIN
+# undef WCHAR_MAX
+# if @HAVE_SIGNED_WCHAR_T@
+# define WCHAR_MIN \
+ _STDINT_SIGNED_MIN (@BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@)
+# else
+# define WCHAR_MIN \
+ _STDINT_UNSIGNED_MIN (@BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@)
+# endif
+# define WCHAR_MAX \
+ _STDINT_MAX (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@)
+
+/* wint_t limits */
+# undef WINT_MIN
+# undef WINT_MAX
+# if @HAVE_SIGNED_WINT_T@
+# define WINT_MIN \
+ _STDINT_SIGNED_MIN (@BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@)
+# else
+# define WINT_MIN \
+ _STDINT_UNSIGNED_MIN (@BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@)
+# endif
+# define WINT_MAX \
+ _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@)
+
+/* 7.18.4. Macros for integer constants */
+
+/* 7.18.4.1. Macros for minimum-width integer constants */
+/* According to ISO C 99 Technical Corrigendum 1 */
+
+/* Here we assume a standard architecture where the hardware integer
+ types have 8, 16, 32, optionally 64 bits, and int is 32 bits. */
+
+# undef INT8_C
+# undef UINT8_C
+# define INT8_C(x) x
+# define UINT8_C(x) x
+
+# undef INT16_C
+# undef UINT16_C
+# define INT16_C(x) x
+# define UINT16_C(x) x
+
+# undef INT32_C
+# undef UINT32_C
+# define INT32_C(x) x
+# define UINT32_C(x) x ## U
+
+# undef INT64_C
+# undef UINT64_C
+# if LONG_MAX >> 31 >> 31 == 1
+# define INT64_C(x) x##L
+# elif defined _MSC_VER
+# define INT64_C(x) x##i64
+# elif @HAVE_LONG_LONG_INT@
+# define INT64_C(x) x##LL
+# endif
+# if ULONG_MAX >> 31 >> 31 >> 1 == 1
+# define UINT64_C(x) x##UL
+# elif defined _MSC_VER
+# define UINT64_C(x) x##ui64
+# elif @HAVE_UNSIGNED_LONG_LONG_INT@
+# define UINT64_C(x) x##ULL
+# endif
+
+/* 7.18.4.2. Macros for greatest-width integer constants */
+
+# ifndef INTMAX_C
+# if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1
+# define INTMAX_C(x) x##LL
+# elif defined GL_INT64_T
+# define INTMAX_C(x) INT64_C(x)
+# else
+# define INTMAX_C(x) x##L
+# endif
+# endif
+
+# ifndef UINTMAX_C
+# if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1
+# define UINTMAX_C(x) x##ULL
+# elif defined GL_UINT64_T
+# define UINTMAX_C(x) UINT64_C(x)
+# else
+# define UINTMAX_C(x) x##UL
+# endif
+# endif
+
+#endif /* !@HAVE_C99_STDINT_H@ */
+
+/* Macros specified by ISO/IEC TS 18661-1:2014. */
+
+#if (!defined UINTMAX_WIDTH \
+ && (defined _GNU_SOURCE || defined __STDC_WANT_IEC_60559_BFP_EXT__))
+# ifdef INT8_MAX
+# define INT8_WIDTH _GL_INTEGER_WIDTH (INT8_MIN, INT8_MAX)
+# endif
+# ifdef UINT8_MAX
+# define UINT8_WIDTH _GL_INTEGER_WIDTH (0, UINT8_MAX)
+# endif
+# ifdef INT16_MAX
+# define INT16_WIDTH _GL_INTEGER_WIDTH (INT16_MIN, INT16_MAX)
+# endif
+# ifdef UINT16_MAX
+# define UINT16_WIDTH _GL_INTEGER_WIDTH (0, UINT16_MAX)
+# endif
+# ifdef INT32_MAX
+# define INT32_WIDTH _GL_INTEGER_WIDTH (INT32_MIN, INT32_MAX)
+# endif
+# ifdef UINT32_MAX
+# define UINT32_WIDTH _GL_INTEGER_WIDTH (0, UINT32_MAX)
+# endif
+# ifdef INT64_MAX
+# define INT64_WIDTH _GL_INTEGER_WIDTH (INT64_MIN, INT64_MAX)
+# endif
+# ifdef UINT64_MAX
+# define UINT64_WIDTH _GL_INTEGER_WIDTH (0, UINT64_MAX)
+# endif
+# define INT_LEAST8_WIDTH _GL_INTEGER_WIDTH (INT_LEAST8_MIN, INT_LEAST8_MAX)
+# define UINT_LEAST8_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST8_MAX)
+# define INT_LEAST16_WIDTH _GL_INTEGER_WIDTH (INT_LEAST16_MIN, INT_LEAST16_MAX)
+# define UINT_LEAST16_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST16_MAX)
+# define INT_LEAST32_WIDTH _GL_INTEGER_WIDTH (INT_LEAST32_MIN, INT_LEAST32_MAX)
+# define UINT_LEAST32_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST32_MAX)
+# define INT_LEAST64_WIDTH _GL_INTEGER_WIDTH (INT_LEAST64_MIN, INT_LEAST64_MAX)
+# define UINT_LEAST64_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST64_MAX)
+# define INT_FAST8_WIDTH _GL_INTEGER_WIDTH (INT_FAST8_MIN, INT_FAST8_MAX)
+# define UINT_FAST8_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST8_MAX)
+# define INT_FAST16_WIDTH _GL_INTEGER_WIDTH (INT_FAST16_MIN, INT_FAST16_MAX)
+# define UINT_FAST16_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST16_MAX)
+# define INT_FAST32_WIDTH _GL_INTEGER_WIDTH (INT_FAST32_MIN, INT_FAST32_MAX)
+# define UINT_FAST32_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST32_MAX)
+# define INT_FAST64_WIDTH _GL_INTEGER_WIDTH (INT_FAST64_MIN, INT_FAST64_MAX)
+# define UINT_FAST64_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST64_MAX)
+# define INTPTR_WIDTH _GL_INTEGER_WIDTH (INTPTR_MIN, INTPTR_MAX)
+# define UINTPTR_WIDTH _GL_INTEGER_WIDTH (0, UINTPTR_MAX)
+# define INTMAX_WIDTH _GL_INTEGER_WIDTH (INTMAX_MIN, INTMAX_MAX)
+# define UINTMAX_WIDTH _GL_INTEGER_WIDTH (0, UINTMAX_MAX)
+# define PTRDIFF_WIDTH _GL_INTEGER_WIDTH (PTRDIFF_MIN, PTRDIFF_MAX)
+# define SIZE_WIDTH _GL_INTEGER_WIDTH (0, SIZE_MAX)
+# define WCHAR_WIDTH _GL_INTEGER_WIDTH (WCHAR_MIN, WCHAR_MAX)
+# ifdef WINT_MAX
+# define WINT_WIDTH _GL_INTEGER_WIDTH (WINT_MIN, WINT_MAX)
+# endif
+# ifdef SIG_ATOMIC_MAX
+# define SIG_ATOMIC_WIDTH _GL_INTEGER_WIDTH (SIG_ATOMIC_MIN, SIG_ATOMIC_MAX)
+# endif
+#endif /* !WINT_WIDTH && (_GNU_SOURCE || __STDC_WANT_IEC_60559_BFP_EXT__) */
+
+#endif /* _@GUARD_PREFIX@_STDINT_H */
+#endif /* !(defined __ANDROID__ && ...) */
+#endif /* !defined _@GUARD_PREFIX@_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */
diff --git a/gnulib/stdlib.in.h b/gnulib/stdlib.in.h
new file mode 100644
index 0000000..f829525
--- /dev/null
+++ b/gnulib/stdlib.in.h
@@ -0,0 +1,1088 @@
+/* A GNU-like <stdlib.h>.
+
+ Copyright (C) 1995, 2001-2004, 2006-2019 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+#if defined __need_system_stdlib_h || defined __need_malloc_and_calloc
+/* Special invocation conventions inside some gnulib header files,
+ and inside some glibc header files, respectively. */
+
+#@INCLUDE_NEXT@ @NEXT_STDLIB_H@
+
+#else
+/* Normal invocation convention. */
+
+#ifndef _@GUARD_PREFIX@_STDLIB_H
+
+/* The include_next requires a split double-inclusion guard. */
+#@INCLUDE_NEXT@ @NEXT_STDLIB_H@
+
+#ifndef _@GUARD_PREFIX@_STDLIB_H
+#define _@GUARD_PREFIX@_STDLIB_H
+
+/* NetBSD 5.0 mis-defines NULL. */
+#include <stddef.h>
+
+/* MirBSD 10 defines WEXITSTATUS in <sys/wait.h>, not in <stdlib.h>. */
+#if @GNULIB_SYSTEM_POSIX@ && !defined WEXITSTATUS
+# include <sys/wait.h>
+#endif
+
+/* Solaris declares getloadavg() in <sys/loadavg.h>. */
+#if (@GNULIB_GETLOADAVG@ || defined GNULIB_POSIXCHECK) && @HAVE_SYS_LOADAVG_H@
+/* OpenIndiana has a bug: <sys/time.h> must be included before
+ <sys/loadavg.h>. */
+# include <sys/time.h>
+# include <sys/loadavg.h>
+#endif
+
+/* Native Windows platforms declare mktemp() in <io.h>. */
+#if 0 && (defined _WIN32 && ! defined __CYGWIN__)
+# include <io.h>
+#endif
+
+#if @GNULIB_RANDOM_R@
+
+/* OSF/1 5.1 declares 'struct random_data' in <random.h>, which is included
+ from <stdlib.h> if _REENTRANT is defined. Include it whenever we need
+ 'struct random_data'. */
+# if @HAVE_RANDOM_H@
+# include <random.h>
+# endif
+
+# if !@HAVE_STRUCT_RANDOM_DATA@ || @REPLACE_RANDOM_R@ || !@HAVE_RANDOM_R@
+# include <stdint.h>
+# endif
+
+# if !@HAVE_STRUCT_RANDOM_DATA@
+/* Define 'struct random_data'.
+ But allow multiple gnulib generated <stdlib.h> replacements to coexist. */
+# if !GNULIB_defined_struct_random_data
+struct random_data
+{
+ int32_t *fptr; /* Front pointer. */
+ int32_t *rptr; /* Rear pointer. */
+ int32_t *state; /* Array of state values. */
+ int rand_type; /* Type of random number generator. */
+ int rand_deg; /* Degree of random number generator. */
+ int rand_sep; /* Distance between front and rear. */
+ int32_t *end_ptr; /* Pointer behind state table. */
+};
+# define GNULIB_defined_struct_random_data 1
+# endif
+# endif
+#endif
+
+#if (@GNULIB_MKSTEMP@ || @GNULIB_MKSTEMPS@ || @GNULIB_MKOSTEMP@ || @GNULIB_MKOSTEMPS@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !(defined _WIN32 && ! defined __CYGWIN__)
+/* On Mac OS X 10.3, only <unistd.h> declares mkstemp. */
+/* On Mac OS X 10.5, only <unistd.h> declares mkstemps. */
+/* On Mac OS X 10.13, only <unistd.h> declares mkostemp and mkostemps. */
+/* On Cygwin 1.7.1, only <unistd.h> declares getsubopt. */
+/* But avoid namespace pollution on glibc systems and native Windows. */
+# include <unistd.h>
+#endif
+
+/* The __attribute__ feature is available in gcc versions 2.5 and later.
+ The attribute __pure__ was added in gcc 2.96. */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
+# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
+#else
+# define _GL_ATTRIBUTE_PURE /* empty */
+#endif
+
+/* The definition of _Noreturn is copied here. */
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
+
+/* The definition of _GL_ARG_NONNULL is copied here. */
+
+/* The definition of _GL_WARN_ON_USE is copied here. */
+
+
+/* Some systems do not define EXIT_*, despite otherwise supporting C89. */
+#ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+#endif
+/* Tandem/NSK and other platforms that define EXIT_FAILURE as -1 interfere
+ with proper operation of xargs. */
+#ifndef EXIT_FAILURE
+# define EXIT_FAILURE 1
+#elif EXIT_FAILURE != 1
+# undef EXIT_FAILURE
+# define EXIT_FAILURE 1
+#endif
+
+
+#if @GNULIB__EXIT@
+/* Terminate the current process with the given return code, without running
+ the 'atexit' handlers. */
+# if !@HAVE__EXIT@
+_GL_FUNCDECL_SYS (_Exit, _Noreturn void, (int status));
+# endif
+_GL_CXXALIAS_SYS (_Exit, void, (int status));
+_GL_CXXALIASWARN (_Exit);
+#elif defined GNULIB_POSIXCHECK
+# undef _Exit
+# if HAVE_RAW_DECL__EXIT
+_GL_WARN_ON_USE (_Exit, "_Exit is unportable - "
+ "use gnulib module _Exit for portability");
+# endif
+#endif
+
+
+#if @GNULIB_ATOLL@
+/* Parse a signed decimal integer.
+ Returns the value of the integer. Errors are not detected. */
+# if !@HAVE_ATOLL@
+_GL_FUNCDECL_SYS (atoll, long long, (const char *string)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (atoll, long long, (const char *string));
+_GL_CXXALIASWARN (atoll);
+#elif defined GNULIB_POSIXCHECK
+# undef atoll
+# if HAVE_RAW_DECL_ATOLL
+_GL_WARN_ON_USE (atoll, "atoll is unportable - "
+ "use gnulib module atoll for portability");
+# endif
+#endif
+
+#if @GNULIB_CALLOC_POSIX@
+# if @REPLACE_CALLOC@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef calloc
+# define calloc rpl_calloc
+# endif
+_GL_FUNCDECL_RPL (calloc, void *, (size_t nmemb, size_t size));
+_GL_CXXALIAS_RPL (calloc, void *, (size_t nmemb, size_t size));
+# else
+_GL_CXXALIAS_SYS (calloc, void *, (size_t nmemb, size_t size));
+# endif
+_GL_CXXALIASWARN (calloc);
+#elif defined GNULIB_POSIXCHECK
+# undef calloc
+/* Assume calloc is always declared. */
+_GL_WARN_ON_USE (calloc, "calloc is not POSIX compliant everywhere - "
+ "use gnulib module calloc-posix for portability");
+#endif
+
+#if @GNULIB_CANONICALIZE_FILE_NAME@
+# if @REPLACE_CANONICALIZE_FILE_NAME@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define canonicalize_file_name rpl_canonicalize_file_name
+# endif
+_GL_FUNCDECL_RPL (canonicalize_file_name, char *, (const char *name)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (canonicalize_file_name, char *, (const char *name));
+# else
+# if !@HAVE_CANONICALIZE_FILE_NAME@
+_GL_FUNCDECL_SYS (canonicalize_file_name, char *, (const char *name)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (canonicalize_file_name, char *, (const char *name));
+# endif
+_GL_CXXALIASWARN (canonicalize_file_name);
+#elif defined GNULIB_POSIXCHECK
+# undef canonicalize_file_name
+# if HAVE_RAW_DECL_CANONICALIZE_FILE_NAME
+_GL_WARN_ON_USE (canonicalize_file_name,
+ "canonicalize_file_name is unportable - "
+ "use gnulib module canonicalize-lgpl for portability");
+# endif
+#endif
+
+#if @GNULIB_GETLOADAVG@
+/* Store max(NELEM,3) load average numbers in LOADAVG[].
+ The three numbers are the load average of the last 1 minute, the last 5
+ minutes, and the last 15 minutes, respectively.
+ LOADAVG is an array of NELEM numbers. */
+# if !@HAVE_DECL_GETLOADAVG@
+_GL_FUNCDECL_SYS (getloadavg, int, (double loadavg[], int nelem)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (getloadavg, int, (double loadavg[], int nelem));
+_GL_CXXALIASWARN (getloadavg);
+#elif defined GNULIB_POSIXCHECK
+# undef getloadavg
+# if HAVE_RAW_DECL_GETLOADAVG
+_GL_WARN_ON_USE (getloadavg, "getloadavg is not portable - "
+ "use gnulib module getloadavg for portability");
+# endif
+#endif
+
+#if @GNULIB_GETSUBOPT@
+/* Assuming *OPTIONP is a comma separated list of elements of the form
+ "token" or "token=value", getsubopt parses the first of these elements.
+ If the first element refers to a "token" that is member of the given
+ NULL-terminated array of tokens:
+ - It replaces the comma with a NUL byte, updates *OPTIONP to point past
+ the first option and the comma, sets *VALUEP to the value of the
+ element (or NULL if it doesn't contain an "=" sign),
+ - It returns the index of the "token" in the given array of tokens.
+ Otherwise it returns -1, and *OPTIONP and *VALUEP are undefined.
+ For more details see the POSIX:2001 specification.
+ http://www.opengroup.org/susv3xsh/getsubopt.html */
+# if !@HAVE_GETSUBOPT@
+_GL_FUNCDECL_SYS (getsubopt, int,
+ (char **optionp, char *const *tokens, char **valuep)
+ _GL_ARG_NONNULL ((1, 2, 3)));
+# endif
+_GL_CXXALIAS_SYS (getsubopt, int,
+ (char **optionp, char *const *tokens, char **valuep));
+_GL_CXXALIASWARN (getsubopt);
+#elif defined GNULIB_POSIXCHECK
+# undef getsubopt
+# if HAVE_RAW_DECL_GETSUBOPT
+_GL_WARN_ON_USE (getsubopt, "getsubopt is unportable - "
+ "use gnulib module getsubopt for portability");
+# endif
+#endif
+
+#if @GNULIB_GRANTPT@
+/* Change the ownership and access permission of the slave side of the
+ pseudo-terminal whose master side is specified by FD. */
+# if !@HAVE_GRANTPT@
+_GL_FUNCDECL_SYS (grantpt, int, (int fd));
+# endif
+_GL_CXXALIAS_SYS (grantpt, int, (int fd));
+_GL_CXXALIASWARN (grantpt);
+#elif defined GNULIB_POSIXCHECK
+# undef grantpt
+# if HAVE_RAW_DECL_GRANTPT
+_GL_WARN_ON_USE (grantpt, "grantpt is not portable - "
+ "use gnulib module grantpt for portability");
+# endif
+#endif
+
+/* If _GL_USE_STDLIB_ALLOC is nonzero, the including module does not
+ rely on GNU or POSIX semantics for malloc and realloc (for example,
+ by never specifying a zero size), so it does not need malloc or
+ realloc to be redefined. */
+#if @GNULIB_MALLOC_POSIX@
+# if @REPLACE_MALLOC@
+# if !((defined __cplusplus && defined GNULIB_NAMESPACE) \
+ || _GL_USE_STDLIB_ALLOC)
+# undef malloc
+# define malloc rpl_malloc
+# endif
+_GL_FUNCDECL_RPL (malloc, void *, (size_t size));
+_GL_CXXALIAS_RPL (malloc, void *, (size_t size));
+# else
+_GL_CXXALIAS_SYS (malloc, void *, (size_t size));
+# endif
+_GL_CXXALIASWARN (malloc);
+#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC
+# undef malloc
+/* Assume malloc is always declared. */
+_GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - "
+ "use gnulib module malloc-posix for portability");
+#endif
+
+/* Convert a multibyte character to a wide character. */
+#if @GNULIB_MBTOWC@
+# if @REPLACE_MBTOWC@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef mbtowc
+# define mbtowc rpl_mbtowc
+# endif
+_GL_FUNCDECL_RPL (mbtowc, int, (wchar_t *pwc, const char *s, size_t n));
+_GL_CXXALIAS_RPL (mbtowc, int, (wchar_t *pwc, const char *s, size_t n));
+# else
+# if !@HAVE_MBTOWC@
+_GL_FUNCDECL_SYS (mbtowc, int, (wchar_t *pwc, const char *s, size_t n));
+# endif
+_GL_CXXALIAS_SYS (mbtowc, int, (wchar_t *pwc, const char *s, size_t n));
+# endif
+_GL_CXXALIASWARN (mbtowc);
+#elif defined GNULIB_POSIXCHECK
+# undef mbtowc
+# if HAVE_RAW_DECL_MBTOWC
+_GL_WARN_ON_USE (mbtowc, "mbtowc is not portable - "
+ "use gnulib module mbtowc for portability");
+# endif
+#endif
+
+#if @GNULIB_MKDTEMP@
+/* Create a unique temporary directory from TEMPLATE.
+ The last six characters of TEMPLATE must be "XXXXXX";
+ they are replaced with a string that makes the directory name unique.
+ Returns TEMPLATE, or a null pointer if it cannot get a unique name.
+ The directory is created mode 700. */
+# if !@HAVE_MKDTEMP@
+_GL_FUNCDECL_SYS (mkdtemp, char *, (char * /*template*/) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (mkdtemp, char *, (char * /*template*/));
+_GL_CXXALIASWARN (mkdtemp);
+#elif defined GNULIB_POSIXCHECK
+# undef mkdtemp
+# if HAVE_RAW_DECL_MKDTEMP
+_GL_WARN_ON_USE (mkdtemp, "mkdtemp is unportable - "
+ "use gnulib module mkdtemp for portability");
+# endif
+#endif
+
+#if @GNULIB_MKOSTEMP@
+/* Create a unique temporary file from TEMPLATE.
+ The last six characters of TEMPLATE must be "XXXXXX";
+ they are replaced with a string that makes the file name unique.
+ The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
+ and O_TEXT, O_BINARY (defined in "binary-io.h").
+ The file is then created, with the specified flags, ensuring it didn't exist
+ before.
+ The file is created read-write (mask at least 0600 & ~umask), but it may be
+ world-readable and world-writable (mask 0666 & ~umask), depending on the
+ implementation.
+ Returns the open file descriptor if successful, otherwise -1 and errno
+ set. */
+# if !@HAVE_MKOSTEMP@
+_GL_FUNCDECL_SYS (mkostemp, int, (char * /*template*/, int /*flags*/)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (mkostemp, int, (char * /*template*/, int /*flags*/));
+_GL_CXXALIASWARN (mkostemp);
+#elif defined GNULIB_POSIXCHECK
+# undef mkostemp
+# if HAVE_RAW_DECL_MKOSTEMP
+_GL_WARN_ON_USE (mkostemp, "mkostemp is unportable - "
+ "use gnulib module mkostemp for portability");
+# endif
+#endif
+
+#if @GNULIB_MKOSTEMPS@
+/* Create a unique temporary file from TEMPLATE.
+ The last six characters of TEMPLATE before a suffix of length
+ SUFFIXLEN must be "XXXXXX";
+ they are replaced with a string that makes the file name unique.
+ The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
+ and O_TEXT, O_BINARY (defined in "binary-io.h").
+ The file is then created, with the specified flags, ensuring it didn't exist
+ before.
+ The file is created read-write (mask at least 0600 & ~umask), but it may be
+ world-readable and world-writable (mask 0666 & ~umask), depending on the
+ implementation.
+ Returns the open file descriptor if successful, otherwise -1 and errno
+ set. */
+# if !@HAVE_MKOSTEMPS@
+_GL_FUNCDECL_SYS (mkostemps, int,
+ (char * /*template*/, int /*suffixlen*/, int /*flags*/)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (mkostemps, int,
+ (char * /*template*/, int /*suffixlen*/, int /*flags*/));
+_GL_CXXALIASWARN (mkostemps);
+#elif defined GNULIB_POSIXCHECK
+# undef mkostemps
+# if HAVE_RAW_DECL_MKOSTEMPS
+_GL_WARN_ON_USE (mkostemps, "mkostemps is unportable - "
+ "use gnulib module mkostemps for portability");
+# endif
+#endif
+
+#if @GNULIB_MKSTEMP@
+/* Create a unique temporary file from TEMPLATE.
+ The last six characters of TEMPLATE must be "XXXXXX";
+ they are replaced with a string that makes the file name unique.
+ The file is then created, ensuring it didn't exist before.
+ The file is created read-write (mask at least 0600 & ~umask), but it may be
+ world-readable and world-writable (mask 0666 & ~umask), depending on the
+ implementation.
+ Returns the open file descriptor if successful, otherwise -1 and errno
+ set. */
+# if @REPLACE_MKSTEMP@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define mkstemp rpl_mkstemp
+# endif
+_GL_FUNCDECL_RPL (mkstemp, int, (char * /*template*/) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (mkstemp, int, (char * /*template*/));
+# else
+# if ! @HAVE_MKSTEMP@
+_GL_FUNCDECL_SYS (mkstemp, int, (char * /*template*/) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (mkstemp, int, (char * /*template*/));
+# endif
+_GL_CXXALIASWARN (mkstemp);
+#elif defined GNULIB_POSIXCHECK
+# undef mkstemp
+# if HAVE_RAW_DECL_MKSTEMP
+_GL_WARN_ON_USE (mkstemp, "mkstemp is unportable - "
+ "use gnulib module mkstemp for portability");
+# endif
+#endif
+
+#if @GNULIB_MKSTEMPS@
+/* Create a unique temporary file from TEMPLATE.
+ The last six characters of TEMPLATE prior to a suffix of length
+ SUFFIXLEN must be "XXXXXX";
+ they are replaced with a string that makes the file name unique.
+ The file is then created, ensuring it didn't exist before.
+ The file is created read-write (mask at least 0600 & ~umask), but it may be
+ world-readable and world-writable (mask 0666 & ~umask), depending on the
+ implementation.
+ Returns the open file descriptor if successful, otherwise -1 and errno
+ set. */
+# if !@HAVE_MKSTEMPS@
+_GL_FUNCDECL_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/));
+_GL_CXXALIASWARN (mkstemps);
+#elif defined GNULIB_POSIXCHECK
+# undef mkstemps
+# if HAVE_RAW_DECL_MKSTEMPS
+_GL_WARN_ON_USE (mkstemps, "mkstemps is unportable - "
+ "use gnulib module mkstemps for portability");
+# endif
+#endif
+
+#if @GNULIB_POSIX_OPENPT@
+/* Return an FD open to the master side of a pseudo-terminal. Flags should
+ include O_RDWR, and may also include O_NOCTTY. */
+# if !@HAVE_POSIX_OPENPT@
+_GL_FUNCDECL_SYS (posix_openpt, int, (int flags));
+# endif
+_GL_CXXALIAS_SYS (posix_openpt, int, (int flags));
+_GL_CXXALIASWARN (posix_openpt);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_openpt
+# if HAVE_RAW_DECL_POSIX_OPENPT
+_GL_WARN_ON_USE (posix_openpt, "posix_openpt is not portable - "
+ "use gnulib module posix_openpt for portability");
+# endif
+#endif
+
+#if @GNULIB_PTSNAME@
+/* Return the pathname of the pseudo-terminal slave associated with
+ the master FD is open on, or NULL on errors. */
+# if @REPLACE_PTSNAME@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef ptsname
+# define ptsname rpl_ptsname
+# endif
+_GL_FUNCDECL_RPL (ptsname, char *, (int fd));
+_GL_CXXALIAS_RPL (ptsname, char *, (int fd));
+# else
+# if !@HAVE_PTSNAME@
+_GL_FUNCDECL_SYS (ptsname, char *, (int fd));
+# endif
+_GL_CXXALIAS_SYS (ptsname, char *, (int fd));
+# endif
+_GL_CXXALIASWARN (ptsname);
+#elif defined GNULIB_POSIXCHECK
+# undef ptsname
+# if HAVE_RAW_DECL_PTSNAME
+_GL_WARN_ON_USE (ptsname, "ptsname is not portable - "
+ "use gnulib module ptsname for portability");
+# endif
+#endif
+
+#if @GNULIB_PTSNAME_R@
+/* Set the pathname of the pseudo-terminal slave associated with
+ the master FD is open on and return 0, or set errno and return
+ non-zero on errors. */
+# if @REPLACE_PTSNAME_R@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef ptsname_r
+# define ptsname_r rpl_ptsname_r
+# endif
+_GL_FUNCDECL_RPL (ptsname_r, int, (int fd, char *buf, size_t len));
+_GL_CXXALIAS_RPL (ptsname_r, int, (int fd, char *buf, size_t len));
+# else
+# if !@HAVE_PTSNAME_R@
+_GL_FUNCDECL_SYS (ptsname_r, int, (int fd, char *buf, size_t len));
+# endif
+_GL_CXXALIAS_SYS (ptsname_r, int, (int fd, char *buf, size_t len));
+# endif
+_GL_CXXALIASWARN (ptsname_r);
+#elif defined GNULIB_POSIXCHECK
+# undef ptsname_r
+# if HAVE_RAW_DECL_PTSNAME_R
+_GL_WARN_ON_USE (ptsname_r, "ptsname_r is not portable - "
+ "use gnulib module ptsname_r for portability");
+# endif
+#endif
+
+#if @GNULIB_PUTENV@
+# if @REPLACE_PUTENV@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef putenv
+# define putenv rpl_putenv
+# endif
+_GL_FUNCDECL_RPL (putenv, int, (char *string) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (putenv, int, (char *string));
+# else
+_GL_CXXALIAS_SYS (putenv, int, (char *string));
+# endif
+_GL_CXXALIASWARN (putenv);
+#endif
+
+#if @GNULIB_QSORT_R@
+/* Sort an array of NMEMB elements, starting at address BASE, each element
+ occupying SIZE bytes, in ascending order according to the comparison
+ function COMPARE. */
+# if @REPLACE_QSORT_R@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef qsort_r
+# define qsort_r rpl_qsort_r
+# endif
+_GL_FUNCDECL_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size,
+ int (*compare) (void const *, void const *,
+ void *),
+ void *arg) _GL_ARG_NONNULL ((1, 4)));
+_GL_CXXALIAS_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size,
+ int (*compare) (void const *, void const *,
+ void *),
+ void *arg));
+# else
+# if !@HAVE_QSORT_R@
+_GL_FUNCDECL_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size,
+ int (*compare) (void const *, void const *,
+ void *),
+ void *arg) _GL_ARG_NONNULL ((1, 4)));
+# endif
+_GL_CXXALIAS_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size,
+ int (*compare) (void const *, void const *,
+ void *),
+ void *arg));
+# endif
+_GL_CXXALIASWARN (qsort_r);
+#elif defined GNULIB_POSIXCHECK
+# undef qsort_r
+# if HAVE_RAW_DECL_QSORT_R
+_GL_WARN_ON_USE (qsort_r, "qsort_r is not portable - "
+ "use gnulib module qsort_r for portability");
+# endif
+#endif
+
+
+#if @GNULIB_RANDOM_R@
+# if !@HAVE_RANDOM_R@
+# ifndef RAND_MAX
+# define RAND_MAX 2147483647
+# endif
+# endif
+#endif
+
+
+#if @GNULIB_RANDOM@
+# if @REPLACE_RANDOM@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef random
+# define random rpl_random
+# endif
+_GL_FUNCDECL_RPL (random, long, (void));
+_GL_CXXALIAS_RPL (random, long, (void));
+# else
+# if !@HAVE_RANDOM@
+_GL_FUNCDECL_SYS (random, long, (void));
+# endif
+_GL_CXXALIAS_SYS (random, long, (void));
+# endif
+_GL_CXXALIASWARN (random);
+#elif defined GNULIB_POSIXCHECK
+# undef random
+# if HAVE_RAW_DECL_RANDOM
+_GL_WARN_ON_USE (random, "random is unportable - "
+ "use gnulib module random for portability");
+# endif
+#endif
+
+#if @GNULIB_RANDOM@
+# if @REPLACE_RANDOM@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef srandom
+# define srandom rpl_srandom
+# endif
+_GL_FUNCDECL_RPL (srandom, void, (unsigned int seed));
+_GL_CXXALIAS_RPL (srandom, void, (unsigned int seed));
+# else
+# if !@HAVE_RANDOM@
+_GL_FUNCDECL_SYS (srandom, void, (unsigned int seed));
+# endif
+_GL_CXXALIAS_SYS (srandom, void, (unsigned int seed));
+# endif
+_GL_CXXALIASWARN (srandom);
+#elif defined GNULIB_POSIXCHECK
+# undef srandom
+# if HAVE_RAW_DECL_SRANDOM
+_GL_WARN_ON_USE (srandom, "srandom is unportable - "
+ "use gnulib module random for portability");
+# endif
+#endif
+
+#if @GNULIB_RANDOM@
+# if @REPLACE_INITSTATE@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef initstate
+# define initstate rpl_initstate
+# endif
+_GL_FUNCDECL_RPL (initstate, char *,
+ (unsigned int seed, char *buf, size_t buf_size)
+ _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (initstate, char *,
+ (unsigned int seed, char *buf, size_t buf_size));
+# else
+# if !@HAVE_INITSTATE@ || !@HAVE_DECL_INITSTATE@
+_GL_FUNCDECL_SYS (initstate, char *,
+ (unsigned int seed, char *buf, size_t buf_size)
+ _GL_ARG_NONNULL ((2)));
+# endif
+_GL_CXXALIAS_SYS (initstate, char *,
+ (unsigned int seed, char *buf, size_t buf_size));
+# endif
+_GL_CXXALIASWARN (initstate);
+#elif defined GNULIB_POSIXCHECK
+# undef initstate
+# if HAVE_RAW_DECL_INITSTATE
+_GL_WARN_ON_USE (initstate, "initstate is unportable - "
+ "use gnulib module random for portability");
+# endif
+#endif
+
+#if @GNULIB_RANDOM@
+# if @REPLACE_SETSTATE@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef setstate
+# define setstate rpl_setstate
+# endif
+_GL_FUNCDECL_RPL (setstate, char *, (char *arg_state) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (setstate, char *, (char *arg_state));
+# else
+# if !@HAVE_SETSTATE@ || !@HAVE_DECL_SETSTATE@
+_GL_FUNCDECL_SYS (setstate, char *, (char *arg_state) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (setstate, char *, (char *arg_state));
+# endif
+_GL_CXXALIASWARN (setstate);
+#elif defined GNULIB_POSIXCHECK
+# undef setstate
+# if HAVE_RAW_DECL_SETSTATE
+_GL_WARN_ON_USE (setstate, "setstate is unportable - "
+ "use gnulib module random for portability");
+# endif
+#endif
+
+
+#if @GNULIB_RANDOM_R@
+# if @REPLACE_RANDOM_R@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef random_r
+# define random_r rpl_random_r
+# endif
+_GL_FUNCDECL_RPL (random_r, int, (struct random_data *buf, int32_t *result)
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (random_r, int, (struct random_data *buf, int32_t *result));
+# else
+# if !@HAVE_RANDOM_R@
+_GL_FUNCDECL_SYS (random_r, int, (struct random_data *buf, int32_t *result)
+ _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (random_r, int, (struct random_data *buf, int32_t *result));
+# endif
+_GL_CXXALIASWARN (random_r);
+#elif defined GNULIB_POSIXCHECK
+# undef random_r
+# if HAVE_RAW_DECL_RANDOM_R
+_GL_WARN_ON_USE (random_r, "random_r is unportable - "
+ "use gnulib module random_r for portability");
+# endif
+#endif
+
+#if @GNULIB_RANDOM_R@
+# if @REPLACE_RANDOM_R@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef srandom_r
+# define srandom_r rpl_srandom_r
+# endif
+_GL_FUNCDECL_RPL (srandom_r, int,
+ (unsigned int seed, struct random_data *rand_state)
+ _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (srandom_r, int,
+ (unsigned int seed, struct random_data *rand_state));
+# else
+# if !@HAVE_RANDOM_R@
+_GL_FUNCDECL_SYS (srandom_r, int,
+ (unsigned int seed, struct random_data *rand_state)
+ _GL_ARG_NONNULL ((2)));
+# endif
+_GL_CXXALIAS_SYS (srandom_r, int,
+ (unsigned int seed, struct random_data *rand_state));
+# endif
+_GL_CXXALIASWARN (srandom_r);
+#elif defined GNULIB_POSIXCHECK
+# undef srandom_r
+# if HAVE_RAW_DECL_SRANDOM_R
+_GL_WARN_ON_USE (srandom_r, "srandom_r is unportable - "
+ "use gnulib module random_r for portability");
+# endif
+#endif
+
+#if @GNULIB_RANDOM_R@
+# if @REPLACE_RANDOM_R@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef initstate_r
+# define initstate_r rpl_initstate_r
+# endif
+_GL_FUNCDECL_RPL (initstate_r, int,
+ (unsigned int seed, char *buf, size_t buf_size,
+ struct random_data *rand_state)
+ _GL_ARG_NONNULL ((2, 4)));
+_GL_CXXALIAS_RPL (initstate_r, int,
+ (unsigned int seed, char *buf, size_t buf_size,
+ struct random_data *rand_state));
+# else
+# if !@HAVE_RANDOM_R@
+_GL_FUNCDECL_SYS (initstate_r, int,
+ (unsigned int seed, char *buf, size_t buf_size,
+ struct random_data *rand_state)
+ _GL_ARG_NONNULL ((2, 4)));
+# endif
+_GL_CXXALIAS_SYS (initstate_r, int,
+ (unsigned int seed, char *buf, size_t buf_size,
+ struct random_data *rand_state));
+# endif
+_GL_CXXALIASWARN (initstate_r);
+#elif defined GNULIB_POSIXCHECK
+# undef initstate_r
+# if HAVE_RAW_DECL_INITSTATE_R
+_GL_WARN_ON_USE (initstate_r, "initstate_r is unportable - "
+ "use gnulib module random_r for portability");
+# endif
+#endif
+
+#if @GNULIB_RANDOM_R@
+# if @REPLACE_RANDOM_R@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef setstate_r
+# define setstate_r rpl_setstate_r
+# endif
+_GL_FUNCDECL_RPL (setstate_r, int,
+ (char *arg_state, struct random_data *rand_state)
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (setstate_r, int,
+ (char *arg_state, struct random_data *rand_state));
+# else
+# if !@HAVE_RANDOM_R@
+_GL_FUNCDECL_SYS (setstate_r, int,
+ (char *arg_state, struct random_data *rand_state)
+ _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (setstate_r, int,
+ (char *arg_state, struct random_data *rand_state));
+# endif
+_GL_CXXALIASWARN (setstate_r);
+#elif defined GNULIB_POSIXCHECK
+# undef setstate_r
+# if HAVE_RAW_DECL_SETSTATE_R
+_GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - "
+ "use gnulib module random_r for portability");
+# endif
+#endif
+
+
+#if @GNULIB_REALLOC_POSIX@
+# if @REPLACE_REALLOC@
+# if !((defined __cplusplus && defined GNULIB_NAMESPACE) \
+ || _GL_USE_STDLIB_ALLOC)
+# undef realloc
+# define realloc rpl_realloc
+# endif
+_GL_FUNCDECL_RPL (realloc, void *, (void *ptr, size_t size));
+_GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size));
+# else
+_GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t size));
+# endif
+_GL_CXXALIASWARN (realloc);
+#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC
+# undef realloc
+/* Assume realloc is always declared. */
+_GL_WARN_ON_USE (realloc, "realloc is not POSIX compliant everywhere - "
+ "use gnulib module realloc-posix for portability");
+#endif
+
+
+#if @GNULIB_REALLOCARRAY@
+# if ! @HAVE_REALLOCARRAY@
+_GL_FUNCDECL_SYS (reallocarray, void *,
+ (void *ptr, size_t nmemb, size_t size));
+# endif
+_GL_CXXALIAS_SYS (reallocarray, void *,
+ (void *ptr, size_t nmemb, size_t size));
+_GL_CXXALIASWARN (reallocarray);
+#elif defined GNULIB_POSIXCHECK
+# undef reallocarray
+# if HAVE_RAW_DECL_REALLOCARRAY
+_GL_WARN_ON_USE (reallocarray, "reallocarray is not portable - "
+ "use gnulib module reallocarray for portability");
+# endif
+#endif
+
+#if @GNULIB_REALPATH@
+# if @REPLACE_REALPATH@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define realpath rpl_realpath
+# endif
+_GL_FUNCDECL_RPL (realpath, char *, (const char *name, char *resolved)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (realpath, char *, (const char *name, char *resolved));
+# else
+# if !@HAVE_REALPATH@
+_GL_FUNCDECL_SYS (realpath, char *, (const char *name, char *resolved)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (realpath, char *, (const char *name, char *resolved));
+# endif
+_GL_CXXALIASWARN (realpath);
+#elif defined GNULIB_POSIXCHECK
+# undef realpath
+# if HAVE_RAW_DECL_REALPATH
+_GL_WARN_ON_USE (realpath, "realpath is unportable - use gnulib module "
+ "canonicalize or canonicalize-lgpl for portability");
+# endif
+#endif
+
+#if @GNULIB_RPMATCH@
+/* Test a user response to a question.
+ Return 1 if it is affirmative, 0 if it is negative, or -1 if not clear. */
+# if !@HAVE_RPMATCH@
+_GL_FUNCDECL_SYS (rpmatch, int, (const char *response) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (rpmatch, int, (const char *response));
+_GL_CXXALIASWARN (rpmatch);
+#elif defined GNULIB_POSIXCHECK
+# undef rpmatch
+# if HAVE_RAW_DECL_RPMATCH
+_GL_WARN_ON_USE (rpmatch, "rpmatch is unportable - "
+ "use gnulib module rpmatch for portability");
+# endif
+#endif
+
+#if @GNULIB_SECURE_GETENV@
+/* Look up NAME in the environment, returning 0 in insecure situations. */
+# if !@HAVE_SECURE_GETENV@
+_GL_FUNCDECL_SYS (secure_getenv, char *,
+ (char const *name) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (secure_getenv, char *, (char const *name));
+_GL_CXXALIASWARN (secure_getenv);
+#elif defined GNULIB_POSIXCHECK
+# undef secure_getenv
+# if HAVE_RAW_DECL_SECURE_GETENV
+_GL_WARN_ON_USE (secure_getenv, "secure_getenv is unportable - "
+ "use gnulib module secure_getenv for portability");
+# endif
+#endif
+
+#if @GNULIB_SETENV@
+/* Set NAME to VALUE in the environment.
+ If REPLACE is nonzero, overwrite an existing value. */
+# if @REPLACE_SETENV@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef setenv
+# define setenv rpl_setenv
+# endif
+_GL_FUNCDECL_RPL (setenv, int,
+ (const char *name, const char *value, int replace)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (setenv, int,
+ (const char *name, const char *value, int replace));
+# else
+# if !@HAVE_DECL_SETENV@
+_GL_FUNCDECL_SYS (setenv, int,
+ (const char *name, const char *value, int replace)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (setenv, int,
+ (const char *name, const char *value, int replace));
+# endif
+# if !(@REPLACE_SETENV@ && !@HAVE_DECL_SETENV@)
+_GL_CXXALIASWARN (setenv);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef setenv
+# if HAVE_RAW_DECL_SETENV
+_GL_WARN_ON_USE (setenv, "setenv is unportable - "
+ "use gnulib module setenv for portability");
+# endif
+#endif
+
+#if @GNULIB_STRTOD@
+ /* Parse a double from STRING, updating ENDP if appropriate. */
+# if @REPLACE_STRTOD@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define strtod rpl_strtod
+# endif
+# define GNULIB_defined_strtod_function 1
+_GL_FUNCDECL_RPL (strtod, double, (const char *str, char **endp)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtod, double, (const char *str, char **endp));
+# else
+# if !@HAVE_STRTOD@
+_GL_FUNCDECL_SYS (strtod, double, (const char *str, char **endp)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (strtod, double, (const char *str, char **endp));
+# endif
+_GL_CXXALIASWARN (strtod);
+#elif defined GNULIB_POSIXCHECK
+# undef strtod
+# if HAVE_RAW_DECL_STRTOD
+_GL_WARN_ON_USE (strtod, "strtod is unportable - "
+ "use gnulib module strtod for portability");
+# endif
+#endif
+
+#if @GNULIB_STRTOLD@
+ /* Parse a 'long double' from STRING, updating ENDP if appropriate. */
+# if @REPLACE_STRTOLD@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define strtold rpl_strtold
+# endif
+# define GNULIB_defined_strtold_function 1
+_GL_FUNCDECL_RPL (strtold, long double, (const char *str, char **endp)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtold, long double, (const char *str, char **endp));
+# else
+# if !@HAVE_STRTOLD@
+_GL_FUNCDECL_SYS (strtold, long double, (const char *str, char **endp)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (strtold, long double, (const char *str, char **endp));
+# endif
+_GL_CXXALIASWARN (strtold);
+#elif defined GNULIB_POSIXCHECK
+# undef strtold
+# if HAVE_RAW_DECL_STRTOLD
+_GL_WARN_ON_USE (strtold, "strtold is unportable - "
+ "use gnulib module strtold for portability");
+# endif
+#endif
+
+#if @GNULIB_STRTOLL@
+/* Parse a signed integer whose textual representation starts at STRING.
+ The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,
+ it may be decimal or octal (with prefix "0") or hexadecimal (with prefix
+ "0x").
+ If ENDPTR is not NULL, the address of the first byte after the integer is
+ stored in *ENDPTR.
+ Upon overflow, the return value is LLONG_MAX or LLONG_MIN, and errno is set
+ to ERANGE. */
+# if !@HAVE_STRTOLL@
+_GL_FUNCDECL_SYS (strtoll, long long,
+ (const char *string, char **endptr, int base)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (strtoll, long long,
+ (const char *string, char **endptr, int base));
+_GL_CXXALIASWARN (strtoll);
+#elif defined GNULIB_POSIXCHECK
+# undef strtoll
+# if HAVE_RAW_DECL_STRTOLL
+_GL_WARN_ON_USE (strtoll, "strtoll is unportable - "
+ "use gnulib module strtoll for portability");
+# endif
+#endif
+
+#if @GNULIB_STRTOULL@
+/* Parse an unsigned integer whose textual representation starts at STRING.
+ The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,
+ it may be decimal or octal (with prefix "0") or hexadecimal (with prefix
+ "0x").
+ If ENDPTR is not NULL, the address of the first byte after the integer is
+ stored in *ENDPTR.
+ Upon overflow, the return value is ULLONG_MAX, and errno is set to
+ ERANGE. */
+# if !@HAVE_STRTOULL@
+_GL_FUNCDECL_SYS (strtoull, unsigned long long,
+ (const char *string, char **endptr, int base)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (strtoull, unsigned long long,
+ (const char *string, char **endptr, int base));
+_GL_CXXALIASWARN (strtoull);
+#elif defined GNULIB_POSIXCHECK
+# undef strtoull
+# if HAVE_RAW_DECL_STRTOULL
+_GL_WARN_ON_USE (strtoull, "strtoull is unportable - "
+ "use gnulib module strtoull for portability");
+# endif
+#endif
+
+#if @GNULIB_UNLOCKPT@
+/* Unlock the slave side of the pseudo-terminal whose master side is specified
+ by FD, so that it can be opened. */
+# if !@HAVE_UNLOCKPT@
+_GL_FUNCDECL_SYS (unlockpt, int, (int fd));
+# endif
+_GL_CXXALIAS_SYS (unlockpt, int, (int fd));
+_GL_CXXALIASWARN (unlockpt);
+#elif defined GNULIB_POSIXCHECK
+# undef unlockpt
+# if HAVE_RAW_DECL_UNLOCKPT
+_GL_WARN_ON_USE (unlockpt, "unlockpt is not portable - "
+ "use gnulib module unlockpt for portability");
+# endif
+#endif
+
+#if @GNULIB_UNSETENV@
+/* Remove the variable NAME from the environment. */
+# if @REPLACE_UNSETENV@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef unsetenv
+# define unsetenv rpl_unsetenv
+# endif
+_GL_FUNCDECL_RPL (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (unsetenv, int, (const char *name));
+# else
+# if !@HAVE_DECL_UNSETENV@
+_GL_FUNCDECL_SYS (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (unsetenv, int, (const char *name));
+# endif
+# if !(@REPLACE_UNSETENV@ && !@HAVE_DECL_UNSETENV@)
+_GL_CXXALIASWARN (unsetenv);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef unsetenv
+# if HAVE_RAW_DECL_UNSETENV
+_GL_WARN_ON_USE (unsetenv, "unsetenv is unportable - "
+ "use gnulib module unsetenv for portability");
+# endif
+#endif
+
+/* Convert a wide character to a multibyte character. */
+#if @GNULIB_WCTOMB@
+# if @REPLACE_WCTOMB@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef wctomb
+# define wctomb rpl_wctomb
+# endif
+_GL_FUNCDECL_RPL (wctomb, int, (char *s, wchar_t wc));
+_GL_CXXALIAS_RPL (wctomb, int, (char *s, wchar_t wc));
+# else
+_GL_CXXALIAS_SYS (wctomb, int, (char *s, wchar_t wc));
+# endif
+_GL_CXXALIASWARN (wctomb);
+#endif
+
+
+#endif /* _@GUARD_PREFIX@_STDLIB_H */
+#endif /* _@GUARD_PREFIX@_STDLIB_H */
+#endif
diff --git a/gnulib/string.in.h b/gnulib/string.in.h
new file mode 100644
index 0000000..4a9292f
--- /dev/null
+++ b/gnulib/string.in.h
@@ -0,0 +1,1063 @@
+/* A GNU-like <string.h>.
+
+ Copyright (C) 1995-1996, 2001-2019 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+#if defined _GL_ALREADY_INCLUDING_STRING_H
+/* Special invocation convention:
+ - On OS X/NetBSD we have a sequence of nested includes
+ <string.h> -> <strings.h> -> "string.h"
+ In this situation system _chk variants due to -D_FORTIFY_SOURCE
+ might be used after any replacements defined here. */
+
+#@INCLUDE_NEXT@ @NEXT_STRING_H@
+
+#else
+/* Normal invocation convention. */
+
+#ifndef _@GUARD_PREFIX@_STRING_H
+
+#define _GL_ALREADY_INCLUDING_STRING_H
+
+/* The include_next requires a split double-inclusion guard. */
+#@INCLUDE_NEXT@ @NEXT_STRING_H@
+
+#undef _GL_ALREADY_INCLUDING_STRING_H
+
+#ifndef _@GUARD_PREFIX@_STRING_H
+#define _@GUARD_PREFIX@_STRING_H
+
+/* NetBSD 5.0 mis-defines NULL. */
+#include <stddef.h>
+
+/* MirBSD defines mbslen as a macro. */
+#if @GNULIB_MBSLEN@ && defined __MirBSD__
+# include <wchar.h>
+#endif
+
+/* The __attribute__ feature is available in gcc versions 2.5 and later.
+ The attribute __pure__ was added in gcc 2.96. */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
+# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
+#else
+# define _GL_ATTRIBUTE_PURE /* empty */
+#endif
+
+/* NetBSD 5.0 declares strsignal in <unistd.h>, not in <string.h>. */
+/* But in any case avoid namespace pollution on glibc systems. */
+#if (@GNULIB_STRSIGNAL@ || defined GNULIB_POSIXCHECK) && defined __NetBSD__ \
+ && ! defined __GLIBC__
+# include <unistd.h>
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
+
+/* The definition of _GL_ARG_NONNULL is copied here. */
+
+/* The definition of _GL_WARN_ON_USE is copied here. */
+
+
+/* Clear a block of memory. The compiler will not delete a call to
+ this function, even if the block is dead after the call. */
+#if @GNULIB_EXPLICIT_BZERO@
+# if ! @HAVE_EXPLICIT_BZERO@
+_GL_FUNCDECL_SYS (explicit_bzero, void,
+ (void *__dest, size_t __n) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (explicit_bzero, void, (void *__dest, size_t __n));
+_GL_CXXALIASWARN (explicit_bzero);
+#elif defined GNULIB_POSIXCHECK
+# undef explicit_bzero
+# if HAVE_RAW_DECL_EXPLICIT_BZERO
+_GL_WARN_ON_USE (explicit_bzero, "explicit_bzero is unportable - "
+ "use gnulib module explicit_bzero for portability");
+# endif
+#endif
+
+/* Find the index of the least-significant set bit. */
+#if @GNULIB_FFSL@
+# if !@HAVE_FFSL@
+_GL_FUNCDECL_SYS (ffsl, int, (long int i));
+# endif
+_GL_CXXALIAS_SYS (ffsl, int, (long int i));
+_GL_CXXALIASWARN (ffsl);
+#elif defined GNULIB_POSIXCHECK
+# undef ffsl
+# if HAVE_RAW_DECL_FFSL
+_GL_WARN_ON_USE (ffsl, "ffsl is not portable - use the ffsl module");
+# endif
+#endif
+
+
+/* Find the index of the least-significant set bit. */
+#if @GNULIB_FFSLL@
+# if !@HAVE_FFSLL@
+_GL_FUNCDECL_SYS (ffsll, int, (long long int i));
+# endif
+_GL_CXXALIAS_SYS (ffsll, int, (long long int i));
+_GL_CXXALIASWARN (ffsll);
+#elif defined GNULIB_POSIXCHECK
+# undef ffsll
+# if HAVE_RAW_DECL_FFSLL
+_GL_WARN_ON_USE (ffsll, "ffsll is not portable - use the ffsll module");
+# endif
+#endif
+
+
+/* Return the first instance of C within N bytes of S, or NULL. */
+#if @GNULIB_MEMCHR@
+# if @REPLACE_MEMCHR@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define memchr rpl_memchr
+# endif
+_GL_FUNCDECL_RPL (memchr, void *, (void const *__s, int __c, size_t __n)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (memchr, void *, (void const *__s, int __c, size_t __n));
+# else
+# if ! @HAVE_MEMCHR@
+_GL_FUNCDECL_SYS (memchr, void *, (void const *__s, int __c, size_t __n)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+# endif
+ /* On some systems, this function is defined as an overloaded function:
+ extern "C" { const void * std::memchr (const void *, int, size_t); }
+ extern "C++" { void * std::memchr (void *, int, size_t); } */
+_GL_CXXALIAS_SYS_CAST2 (memchr,
+ void *, (void const *__s, int __c, size_t __n),
+ void const *, (void const *__s, int __c, size_t __n));
+# endif
+# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
+ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
+_GL_CXXALIASWARN1 (memchr, void *, (void *__s, int __c, size_t __n));
+_GL_CXXALIASWARN1 (memchr, void const *,
+ (void const *__s, int __c, size_t __n));
+# else
+_GL_CXXALIASWARN (memchr);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef memchr
+/* Assume memchr is always declared. */
+_GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - "
+ "use gnulib module memchr for portability" );
+#endif
+
+/* Return the first occurrence of NEEDLE in HAYSTACK. */
+#if @GNULIB_MEMMEM@
+# if @REPLACE_MEMMEM@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define memmem rpl_memmem
+# endif
+_GL_FUNCDECL_RPL (memmem, void *,
+ (void const *__haystack, size_t __haystack_len,
+ void const *__needle, size_t __needle_len)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 3)));
+_GL_CXXALIAS_RPL (memmem, void *,
+ (void const *__haystack, size_t __haystack_len,
+ void const *__needle, size_t __needle_len));
+# else
+# if ! @HAVE_DECL_MEMMEM@
+_GL_FUNCDECL_SYS (memmem, void *,
+ (void const *__haystack, size_t __haystack_len,
+ void const *__needle, size_t __needle_len)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 3)));
+# endif
+_GL_CXXALIAS_SYS (memmem, void *,
+ (void const *__haystack, size_t __haystack_len,
+ void const *__needle, size_t __needle_len));
+# endif
+_GL_CXXALIASWARN (memmem);
+#elif defined GNULIB_POSIXCHECK
+# undef memmem
+# if HAVE_RAW_DECL_MEMMEM
+_GL_WARN_ON_USE (memmem, "memmem is unportable and often quadratic - "
+ "use gnulib module memmem-simple for portability, "
+ "and module memmem for speed" );
+# endif
+#endif
+
+/* Copy N bytes of SRC to DEST, return pointer to bytes after the
+ last written byte. */
+#if @GNULIB_MEMPCPY@
+# if ! @HAVE_MEMPCPY@
+_GL_FUNCDECL_SYS (mempcpy, void *,
+ (void *restrict __dest, void const *restrict __src,
+ size_t __n)
+ _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (mempcpy, void *,
+ (void *restrict __dest, void const *restrict __src,
+ size_t __n));
+_GL_CXXALIASWARN (mempcpy);
+#elif defined GNULIB_POSIXCHECK
+# undef mempcpy
+# if HAVE_RAW_DECL_MEMPCPY
+_GL_WARN_ON_USE (mempcpy, "mempcpy is unportable - "
+ "use gnulib module mempcpy for portability");
+# endif
+#endif
+
+/* Search backwards through a block for a byte (specified as an int). */
+#if @GNULIB_MEMRCHR@
+# if ! @HAVE_DECL_MEMRCHR@
+_GL_FUNCDECL_SYS (memrchr, void *, (void const *, int, size_t)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+# endif
+ /* On some systems, this function is defined as an overloaded function:
+ extern "C++" { const void * std::memrchr (const void *, int, size_t); }
+ extern "C++" { void * std::memrchr (void *, int, size_t); } */
+_GL_CXXALIAS_SYS_CAST2 (memrchr,
+ void *, (void const *, int, size_t),
+ void const *, (void const *, int, size_t));
+# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
+ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
+_GL_CXXALIASWARN1 (memrchr, void *, (void *, int, size_t));
+_GL_CXXALIASWARN1 (memrchr, void const *, (void const *, int, size_t));
+# else
+_GL_CXXALIASWARN (memrchr);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef memrchr
+# if HAVE_RAW_DECL_MEMRCHR
+_GL_WARN_ON_USE (memrchr, "memrchr is unportable - "
+ "use gnulib module memrchr for portability");
+# endif
+#endif
+
+/* Find the first occurrence of C in S. More efficient than
+ memchr(S,C,N), at the expense of undefined behavior if C does not
+ occur within N bytes. */
+#if @GNULIB_RAWMEMCHR@
+# if ! @HAVE_RAWMEMCHR@
+_GL_FUNCDECL_SYS (rawmemchr, void *, (void const *__s, int __c_in)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+# endif
+ /* On some systems, this function is defined as an overloaded function:
+ extern "C++" { const void * std::rawmemchr (const void *, int); }
+ extern "C++" { void * std::rawmemchr (void *, int); } */
+_GL_CXXALIAS_SYS_CAST2 (rawmemchr,
+ void *, (void const *__s, int __c_in),
+ void const *, (void const *__s, int __c_in));
+# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
+ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
+_GL_CXXALIASWARN1 (rawmemchr, void *, (void *__s, int __c_in));
+_GL_CXXALIASWARN1 (rawmemchr, void const *, (void const *__s, int __c_in));
+# else
+_GL_CXXALIASWARN (rawmemchr);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef rawmemchr
+# if HAVE_RAW_DECL_RAWMEMCHR
+_GL_WARN_ON_USE (rawmemchr, "rawmemchr is unportable - "
+ "use gnulib module rawmemchr for portability");
+# endif
+#endif
+
+/* Copy SRC to DST, returning the address of the terminating '\0' in DST. */
+#if @GNULIB_STPCPY@
+# if ! @HAVE_STPCPY@
+_GL_FUNCDECL_SYS (stpcpy, char *,
+ (char *restrict __dst, char const *restrict __src)
+ _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (stpcpy, char *,
+ (char *restrict __dst, char const *restrict __src));
+_GL_CXXALIASWARN (stpcpy);
+#elif defined GNULIB_POSIXCHECK
+# undef stpcpy
+# if HAVE_RAW_DECL_STPCPY
+_GL_WARN_ON_USE (stpcpy, "stpcpy is unportable - "
+ "use gnulib module stpcpy for portability");
+# endif
+#endif
+
+/* Copy no more than N bytes of SRC to DST, returning a pointer past the
+ last non-NUL byte written into DST. */
+#if @GNULIB_STPNCPY@
+# if @REPLACE_STPNCPY@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef stpncpy
+# define stpncpy rpl_stpncpy
+# endif
+_GL_FUNCDECL_RPL (stpncpy, char *,
+ (char *restrict __dst, char const *restrict __src,
+ size_t __n)
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (stpncpy, char *,
+ (char *restrict __dst, char const *restrict __src,
+ size_t __n));
+# else
+# if ! @HAVE_STPNCPY@
+_GL_FUNCDECL_SYS (stpncpy, char *,
+ (char *restrict __dst, char const *restrict __src,
+ size_t __n)
+ _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (stpncpy, char *,
+ (char *restrict __dst, char const *restrict __src,
+ size_t __n));
+# endif
+_GL_CXXALIASWARN (stpncpy);
+#elif defined GNULIB_POSIXCHECK
+# undef stpncpy
+# if HAVE_RAW_DECL_STPNCPY
+_GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - "
+ "use gnulib module stpncpy for portability");
+# endif
+#endif
+
+#if defined GNULIB_POSIXCHECK
+/* strchr() does not work with multibyte strings if the locale encoding is
+ GB18030 and the character to be searched is a digit. */
+# undef strchr
+/* Assume strchr is always declared. */
+_GL_WARN_ON_USE (strchr, "strchr cannot work correctly on character strings "
+ "in some multibyte locales - "
+ "use mbschr if you care about internationalization");
+#endif
+
+/* Find the first occurrence of C in S or the final NUL byte. */
+#if @GNULIB_STRCHRNUL@
+# if @REPLACE_STRCHRNUL@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define strchrnul rpl_strchrnul
+# endif
+_GL_FUNCDECL_RPL (strchrnul, char *, (const char *__s, int __c_in)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strchrnul, char *,
+ (const char *str, int ch));
+# else
+# if ! @HAVE_STRCHRNUL@
+_GL_FUNCDECL_SYS (strchrnul, char *, (char const *__s, int __c_in)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+# endif
+ /* On some systems, this function is defined as an overloaded function:
+ extern "C++" { const char * std::strchrnul (const char *, int); }
+ extern "C++" { char * std::strchrnul (char *, int); } */
+_GL_CXXALIAS_SYS_CAST2 (strchrnul,
+ char *, (char const *__s, int __c_in),
+ char const *, (char const *__s, int __c_in));
+# endif
+# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
+ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
+_GL_CXXALIASWARN1 (strchrnul, char *, (char *__s, int __c_in));
+_GL_CXXALIASWARN1 (strchrnul, char const *, (char const *__s, int __c_in));
+# else
+_GL_CXXALIASWARN (strchrnul);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef strchrnul
+# if HAVE_RAW_DECL_STRCHRNUL
+_GL_WARN_ON_USE (strchrnul, "strchrnul is unportable - "
+ "use gnulib module strchrnul for portability");
+# endif
+#endif
+
+/* Duplicate S, returning an identical malloc'd string. */
+#if @GNULIB_STRDUP@
+# if @REPLACE_STRDUP@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef strdup
+# define strdup rpl_strdup
+# endif
+_GL_FUNCDECL_RPL (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strdup, char *, (char const *__s));
+# else
+# if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup
+ /* strdup exists as a function and as a macro. Get rid of the macro. */
+# undef strdup
+# endif
+# if !(@HAVE_DECL_STRDUP@ || defined strdup)
+_GL_FUNCDECL_SYS (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (strdup, char *, (char const *__s));
+# endif
+_GL_CXXALIASWARN (strdup);
+#elif defined GNULIB_POSIXCHECK
+# undef strdup
+# if HAVE_RAW_DECL_STRDUP
+_GL_WARN_ON_USE (strdup, "strdup is unportable - "
+ "use gnulib module strdup for portability");
+# endif
+#endif
+
+/* Append no more than N characters from SRC onto DEST. */
+#if @GNULIB_STRNCAT@
+# if @REPLACE_STRNCAT@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef strncat
+# define strncat rpl_strncat
+# endif
+_GL_FUNCDECL_RPL (strncat, char *, (char *dest, const char *src, size_t n)
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (strncat, char *, (char *dest, const char *src, size_t n));
+# else
+_GL_CXXALIAS_SYS (strncat, char *, (char *dest, const char *src, size_t n));
+# endif
+_GL_CXXALIASWARN (strncat);
+#elif defined GNULIB_POSIXCHECK
+# undef strncat
+# if HAVE_RAW_DECL_STRNCAT
+_GL_WARN_ON_USE (strncat, "strncat is unportable - "
+ "use gnulib module strncat for portability");
+# endif
+#endif
+
+/* Return a newly allocated copy of at most N bytes of STRING. */
+#if @GNULIB_STRNDUP@
+# if @REPLACE_STRNDUP@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef strndup
+# define strndup rpl_strndup
+# endif
+_GL_FUNCDECL_RPL (strndup, char *, (char const *__s, size_t __n)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strndup, char *, (char const *__s, size_t __n));
+# else
+# if ! @HAVE_DECL_STRNDUP@
+_GL_FUNCDECL_SYS (strndup, char *, (char const *__s, size_t __n)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (strndup, char *, (char const *__s, size_t __n));
+# endif
+_GL_CXXALIASWARN (strndup);
+#elif defined GNULIB_POSIXCHECK
+# undef strndup
+# if HAVE_RAW_DECL_STRNDUP
+_GL_WARN_ON_USE (strndup, "strndup is unportable - "
+ "use gnulib module strndup for portability");
+# endif
+#endif
+
+/* Find the length (number of bytes) of STRING, but scan at most
+ MAXLEN bytes. If no '\0' terminator is found in that many bytes,
+ return MAXLEN. */
+#if @GNULIB_STRNLEN@
+# if @REPLACE_STRNLEN@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef strnlen
+# define strnlen rpl_strnlen
+# endif
+_GL_FUNCDECL_RPL (strnlen, size_t, (char const *__s, size_t __maxlen)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strnlen, size_t, (char const *__s, size_t __maxlen));
+# else
+# if ! @HAVE_DECL_STRNLEN@
+_GL_FUNCDECL_SYS (strnlen, size_t, (char const *__s, size_t __maxlen)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (strnlen, size_t, (char const *__s, size_t __maxlen));
+# endif
+_GL_CXXALIASWARN (strnlen);
+#elif defined GNULIB_POSIXCHECK
+# undef strnlen
+# if HAVE_RAW_DECL_STRNLEN
+_GL_WARN_ON_USE (strnlen, "strnlen is unportable - "
+ "use gnulib module strnlen for portability");
+# endif
+#endif
+
+#if defined GNULIB_POSIXCHECK
+/* strcspn() assumes the second argument is a list of single-byte characters.
+ Even in this simple case, it does not work with multibyte strings if the
+ locale encoding is GB18030 and one of the characters to be searched is a
+ digit. */
+# undef strcspn
+/* Assume strcspn is always declared. */
+_GL_WARN_ON_USE (strcspn, "strcspn cannot work correctly on character strings "
+ "in multibyte locales - "
+ "use mbscspn if you care about internationalization");
+#endif
+
+/* Find the first occurrence in S of any character in ACCEPT. */
+#if @GNULIB_STRPBRK@
+# if ! @HAVE_STRPBRK@
+_GL_FUNCDECL_SYS (strpbrk, char *, (char const *__s, char const *__accept)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2)));
+# endif
+ /* On some systems, this function is defined as an overloaded function:
+ extern "C" { const char * strpbrk (const char *, const char *); }
+ extern "C++" { char * strpbrk (char *, const char *); } */
+_GL_CXXALIAS_SYS_CAST2 (strpbrk,
+ char *, (char const *__s, char const *__accept),
+ const char *, (char const *__s, char const *__accept));
+# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
+ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
+_GL_CXXALIASWARN1 (strpbrk, char *, (char *__s, char const *__accept));
+_GL_CXXALIASWARN1 (strpbrk, char const *,
+ (char const *__s, char const *__accept));
+# else
+_GL_CXXALIASWARN (strpbrk);
+# endif
+# if defined GNULIB_POSIXCHECK
+/* strpbrk() assumes the second argument is a list of single-byte characters.
+ Even in this simple case, it does not work with multibyte strings if the
+ locale encoding is GB18030 and one of the characters to be searched is a
+ digit. */
+# undef strpbrk
+_GL_WARN_ON_USE (strpbrk, "strpbrk cannot work correctly on character strings "
+ "in multibyte locales - "
+ "use mbspbrk if you care about internationalization");
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef strpbrk
+# if HAVE_RAW_DECL_STRPBRK
+_GL_WARN_ON_USE (strpbrk, "strpbrk is unportable - "
+ "use gnulib module strpbrk for portability");
+# endif
+#endif
+
+#if defined GNULIB_POSIXCHECK
+/* strspn() assumes the second argument is a list of single-byte characters.
+ Even in this simple case, it cannot work with multibyte strings. */
+# undef strspn
+/* Assume strspn is always declared. */
+_GL_WARN_ON_USE (strspn, "strspn cannot work correctly on character strings "
+ "in multibyte locales - "
+ "use mbsspn if you care about internationalization");
+#endif
+
+#if defined GNULIB_POSIXCHECK
+/* strrchr() does not work with multibyte strings if the locale encoding is
+ GB18030 and the character to be searched is a digit. */
+# undef strrchr
+/* Assume strrchr is always declared. */
+_GL_WARN_ON_USE (strrchr, "strrchr cannot work correctly on character strings "
+ "in some multibyte locales - "
+ "use mbsrchr if you care about internationalization");
+#endif
+
+/* Search the next delimiter (char listed in DELIM) starting at *STRINGP.
+ If one is found, overwrite it with a NUL, and advance *STRINGP
+ to point to the next char after it. Otherwise, set *STRINGP to NULL.
+ If *STRINGP was already NULL, nothing happens.
+ Return the old value of *STRINGP.
+
+ This is a variant of strtok() that is multithread-safe and supports
+ empty fields.
+
+ Caveat: It modifies the original string.
+ Caveat: These functions cannot be used on constant strings.
+ Caveat: The identity of the delimiting character is lost.
+ Caveat: It doesn't work with multibyte strings unless all of the delimiter
+ characters are ASCII characters < 0x30.
+
+ See also strtok_r(). */
+#if @GNULIB_STRSEP@
+# if ! @HAVE_STRSEP@
+_GL_FUNCDECL_SYS (strsep, char *,
+ (char **restrict __stringp, char const *restrict __delim)
+ _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (strsep, char *,
+ (char **restrict __stringp, char const *restrict __delim));
+_GL_CXXALIASWARN (strsep);
+# if defined GNULIB_POSIXCHECK
+# undef strsep
+_GL_WARN_ON_USE (strsep, "strsep cannot work correctly on character strings "
+ "in multibyte locales - "
+ "use mbssep if you care about internationalization");
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef strsep
+# if HAVE_RAW_DECL_STRSEP
+_GL_WARN_ON_USE (strsep, "strsep is unportable - "
+ "use gnulib module strsep for portability");
+# endif
+#endif
+
+#if @GNULIB_STRSTR@
+# if @REPLACE_STRSTR@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define strstr rpl_strstr
+# endif
+_GL_FUNCDECL_RPL (strstr, char *, (const char *haystack, const char *needle)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (strstr, char *, (const char *haystack, const char *needle));
+# else
+ /* On some systems, this function is defined as an overloaded function:
+ extern "C++" { const char * strstr (const char *, const char *); }
+ extern "C++" { char * strstr (char *, const char *); } */
+_GL_CXXALIAS_SYS_CAST2 (strstr,
+ char *, (const char *haystack, const char *needle),
+ const char *, (const char *haystack, const char *needle));
+# endif
+# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
+ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
+_GL_CXXALIASWARN1 (strstr, char *, (char *haystack, const char *needle));
+_GL_CXXALIASWARN1 (strstr, const char *,
+ (const char *haystack, const char *needle));
+# else
+_GL_CXXALIASWARN (strstr);
+# endif
+#elif defined GNULIB_POSIXCHECK
+/* strstr() does not work with multibyte strings if the locale encoding is
+ different from UTF-8:
+ POSIX says that it operates on "strings", and "string" in POSIX is defined
+ as a sequence of bytes, not of characters. */
+# undef strstr
+/* Assume strstr is always declared. */
+_GL_WARN_ON_USE (strstr, "strstr is quadratic on many systems, and cannot "
+ "work correctly on character strings in most "
+ "multibyte locales - "
+ "use mbsstr if you care about internationalization, "
+ "or use strstr if you care about speed");
+#endif
+
+/* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive
+ comparison. */
+#if @GNULIB_STRCASESTR@
+# if @REPLACE_STRCASESTR@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define strcasestr rpl_strcasestr
+# endif
+_GL_FUNCDECL_RPL (strcasestr, char *,
+ (const char *haystack, const char *needle)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (strcasestr, char *,
+ (const char *haystack, const char *needle));
+# else
+# if ! @HAVE_STRCASESTR@
+_GL_FUNCDECL_SYS (strcasestr, char *,
+ (const char *haystack, const char *needle)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2)));
+# endif
+ /* On some systems, this function is defined as an overloaded function:
+ extern "C++" { const char * strcasestr (const char *, const char *); }
+ extern "C++" { char * strcasestr (char *, const char *); } */
+_GL_CXXALIAS_SYS_CAST2 (strcasestr,
+ char *, (const char *haystack, const char *needle),
+ const char *, (const char *haystack, const char *needle));
+# endif
+# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
+ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
+_GL_CXXALIASWARN1 (strcasestr, char *, (char *haystack, const char *needle));
+_GL_CXXALIASWARN1 (strcasestr, const char *,
+ (const char *haystack, const char *needle));
+# else
+_GL_CXXALIASWARN (strcasestr);
+# endif
+#elif defined GNULIB_POSIXCHECK
+/* strcasestr() does not work with multibyte strings:
+ It is a glibc extension, and glibc implements it only for unibyte
+ locales. */
+# undef strcasestr
+# if HAVE_RAW_DECL_STRCASESTR
+_GL_WARN_ON_USE (strcasestr, "strcasestr does work correctly on character "
+ "strings in multibyte locales - "
+ "use mbscasestr if you care about "
+ "internationalization, or use c-strcasestr if you want "
+ "a locale independent function");
+# endif
+#endif
+
+/* Parse S into tokens separated by characters in DELIM.
+ If S is NULL, the saved pointer in SAVE_PTR is used as
+ the next starting point. For example:
+ char s[] = "-abc-=-def";
+ char *sp;
+ x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def"
+ x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL
+ x = strtok_r(NULL, "=", &sp); // x = NULL
+ // s = "abc\0-def\0"
+
+ This is a variant of strtok() that is multithread-safe.
+
+ For the POSIX documentation for this function, see:
+ http://www.opengroup.org/susv3xsh/strtok.html
+
+ Caveat: It modifies the original string.
+ Caveat: These functions cannot be used on constant strings.
+ Caveat: The identity of the delimiting character is lost.
+ Caveat: It doesn't work with multibyte strings unless all of the delimiter
+ characters are ASCII characters < 0x30.
+
+ See also strsep(). */
+#if @GNULIB_STRTOK_R@
+# if @REPLACE_STRTOK_R@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef strtok_r
+# define strtok_r rpl_strtok_r
+# endif
+_GL_FUNCDECL_RPL (strtok_r, char *,
+ (char *restrict s, char const *restrict delim,
+ char **restrict save_ptr)
+ _GL_ARG_NONNULL ((2, 3)));
+_GL_CXXALIAS_RPL (strtok_r, char *,
+ (char *restrict s, char const *restrict delim,
+ char **restrict save_ptr));
+# else
+# if @UNDEFINE_STRTOK_R@ || defined GNULIB_POSIXCHECK
+# undef strtok_r
+# endif
+# if ! @HAVE_DECL_STRTOK_R@
+_GL_FUNCDECL_SYS (strtok_r, char *,
+ (char *restrict s, char const *restrict delim,
+ char **restrict save_ptr)
+ _GL_ARG_NONNULL ((2, 3)));
+# endif
+_GL_CXXALIAS_SYS (strtok_r, char *,
+ (char *restrict s, char const *restrict delim,
+ char **restrict save_ptr));
+# endif
+_GL_CXXALIASWARN (strtok_r);
+# if defined GNULIB_POSIXCHECK
+_GL_WARN_ON_USE (strtok_r, "strtok_r cannot work correctly on character "
+ "strings in multibyte locales - "
+ "use mbstok_r if you care about internationalization");
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef strtok_r
+# if HAVE_RAW_DECL_STRTOK_R
+_GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - "
+ "use gnulib module strtok_r for portability");
+# endif
+#endif
+
+
+/* The following functions are not specified by POSIX. They are gnulib
+ extensions. */
+
+#if @GNULIB_MBSLEN@
+/* Return the number of multibyte characters in the character string STRING.
+ This considers multibyte characters, unlike strlen, which counts bytes. */
+# ifdef __MirBSD__ /* MirBSD defines mbslen as a macro. Override it. */
+# undef mbslen
+# endif
+# if @HAVE_MBSLEN@ /* AIX, OSF/1, MirBSD define mbslen already in libc. */
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define mbslen rpl_mbslen
+# endif
+_GL_FUNCDECL_RPL (mbslen, size_t, (const char *string)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (mbslen, size_t, (const char *string));
+# else
+_GL_FUNCDECL_SYS (mbslen, size_t, (const char *string)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_SYS (mbslen, size_t, (const char *string));
+# endif
+_GL_CXXALIASWARN (mbslen);
+#endif
+
+#if @GNULIB_MBSNLEN@
+/* Return the number of multibyte characters in the character string starting
+ at STRING and ending at STRING + LEN. */
+_GL_EXTERN_C size_t mbsnlen (const char *string, size_t len)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1));
+#endif
+
+#if @GNULIB_MBSCHR@
+/* Locate the first single-byte character C in the character string STRING,
+ and return a pointer to it. Return NULL if C is not found in STRING.
+ Unlike strchr(), this function works correctly in multibyte locales with
+ encodings such as GB18030. */
+# if defined __hpux
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define mbschr rpl_mbschr /* avoid collision with HP-UX function */
+# endif
+_GL_FUNCDECL_RPL (mbschr, char *, (const char *string, int c)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (mbschr, char *, (const char *string, int c));
+# else
+_GL_FUNCDECL_SYS (mbschr, char *, (const char *string, int c)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_SYS (mbschr, char *, (const char *string, int c));
+# endif
+_GL_CXXALIASWARN (mbschr);
+#endif
+
+#if @GNULIB_MBSRCHR@
+/* Locate the last single-byte character C in the character string STRING,
+ and return a pointer to it. Return NULL if C is not found in STRING.
+ Unlike strrchr(), this function works correctly in multibyte locales with
+ encodings such as GB18030. */
+# if defined __hpux || defined __INTERIX
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define mbsrchr rpl_mbsrchr /* avoid collision with system function */
+# endif
+_GL_FUNCDECL_RPL (mbsrchr, char *, (const char *string, int c)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (mbsrchr, char *, (const char *string, int c));
+# else
+_GL_FUNCDECL_SYS (mbsrchr, char *, (const char *string, int c)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_SYS (mbsrchr, char *, (const char *string, int c));
+# endif
+_GL_CXXALIASWARN (mbsrchr);
+#endif
+
+#if @GNULIB_MBSSTR@
+/* Find the first occurrence of the character string NEEDLE in the character
+ string HAYSTACK. Return NULL if NEEDLE is not found in HAYSTACK.
+ Unlike strstr(), this function works correctly in multibyte locales with
+ encodings different from UTF-8. */
+_GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2));
+#endif
+
+#if @GNULIB_MBSCASECMP@
+/* Compare the character strings S1 and S2, ignoring case, returning less than,
+ equal to or greater than zero if S1 is lexicographically less than, equal to
+ or greater than S2.
+ Note: This function may, in multibyte locales, return 0 for strings of
+ different lengths!
+ Unlike strcasecmp(), this function works correctly in multibyte locales. */
+_GL_EXTERN_C int mbscasecmp (const char *s1, const char *s2)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2));
+#endif
+
+#if @GNULIB_MBSNCASECMP@
+/* Compare the initial segment of the character string S1 consisting of at most
+ N characters with the initial segment of the character string S2 consisting
+ of at most N characters, ignoring case, returning less than, equal to or
+ greater than zero if the initial segment of S1 is lexicographically less
+ than, equal to or greater than the initial segment of S2.
+ Note: This function may, in multibyte locales, return 0 for initial segments
+ of different lengths!
+ Unlike strncasecmp(), this function works correctly in multibyte locales.
+ But beware that N is not a byte count but a character count! */
+_GL_EXTERN_C int mbsncasecmp (const char *s1, const char *s2, size_t n)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2));
+#endif
+
+#if @GNULIB_MBSPCASECMP@
+/* Compare the initial segment of the character string STRING consisting of
+ at most mbslen (PREFIX) characters with the character string PREFIX,
+ ignoring case. If the two match, return a pointer to the first byte
+ after this prefix in STRING. Otherwise, return NULL.
+ Note: This function may, in multibyte locales, return non-NULL if STRING
+ is of smaller length than PREFIX!
+ Unlike strncasecmp(), this function works correctly in multibyte
+ locales. */
+_GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2));
+#endif
+
+#if @GNULIB_MBSCASESTR@
+/* Find the first occurrence of the character string NEEDLE in the character
+ string HAYSTACK, using case-insensitive comparison.
+ Note: This function may, in multibyte locales, return success even if
+ strlen (haystack) < strlen (needle) !
+ Unlike strcasestr(), this function works correctly in multibyte locales. */
+_GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2));
+#endif
+
+#if @GNULIB_MBSCSPN@
+/* Find the first occurrence in the character string STRING of any character
+ in the character string ACCEPT. Return the number of bytes from the
+ beginning of the string to this occurrence, or to the end of the string
+ if none exists.
+ Unlike strcspn(), this function works correctly in multibyte locales. */
+_GL_EXTERN_C size_t mbscspn (const char *string, const char *accept)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2));
+#endif
+
+#if @GNULIB_MBSPBRK@
+/* Find the first occurrence in the character string STRING of any character
+ in the character string ACCEPT. Return the pointer to it, or NULL if none
+ exists.
+ Unlike strpbrk(), this function works correctly in multibyte locales. */
+# if defined __hpux
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define mbspbrk rpl_mbspbrk /* avoid collision with HP-UX function */
+# endif
+_GL_FUNCDECL_RPL (mbspbrk, char *, (const char *string, const char *accept)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (mbspbrk, char *, (const char *string, const char *accept));
+# else
+_GL_FUNCDECL_SYS (mbspbrk, char *, (const char *string, const char *accept)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_SYS (mbspbrk, char *, (const char *string, const char *accept));
+# endif
+_GL_CXXALIASWARN (mbspbrk);
+#endif
+
+#if @GNULIB_MBSSPN@
+/* Find the first occurrence in the character string STRING of any character
+ not in the character string REJECT. Return the number of bytes from the
+ beginning of the string to this occurrence, or to the end of the string
+ if none exists.
+ Unlike strspn(), this function works correctly in multibyte locales. */
+_GL_EXTERN_C size_t mbsspn (const char *string, const char *reject)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2));
+#endif
+
+#if @GNULIB_MBSSEP@
+/* Search the next delimiter (multibyte character listed in the character
+ string DELIM) starting at the character string *STRINGP.
+ If one is found, overwrite it with a NUL, and advance *STRINGP to point
+ to the next multibyte character after it. Otherwise, set *STRINGP to NULL.
+ If *STRINGP was already NULL, nothing happens.
+ Return the old value of *STRINGP.
+
+ This is a variant of mbstok_r() that supports empty fields.
+
+ Caveat: It modifies the original string.
+ Caveat: These functions cannot be used on constant strings.
+ Caveat: The identity of the delimiting character is lost.
+
+ See also mbstok_r(). */
+_GL_EXTERN_C char * mbssep (char **stringp, const char *delim)
+ _GL_ARG_NONNULL ((1, 2));
+#endif
+
+#if @GNULIB_MBSTOK_R@
+/* Parse the character string STRING into tokens separated by characters in
+ the character string DELIM.
+ If STRING is NULL, the saved pointer in SAVE_PTR is used as
+ the next starting point. For example:
+ char s[] = "-abc-=-def";
+ char *sp;
+ x = mbstok_r(s, "-", &sp); // x = "abc", sp = "=-def"
+ x = mbstok_r(NULL, "-=", &sp); // x = "def", sp = NULL
+ x = mbstok_r(NULL, "=", &sp); // x = NULL
+ // s = "abc\0-def\0"
+
+ Caveat: It modifies the original string.
+ Caveat: These functions cannot be used on constant strings.
+ Caveat: The identity of the delimiting character is lost.
+
+ See also mbssep(). */
+_GL_EXTERN_C char * mbstok_r (char *string, const char *delim, char **save_ptr)
+ _GL_ARG_NONNULL ((2, 3));
+#endif
+
+/* Map any int, typically from errno, into an error message. */
+#if @GNULIB_STRERROR@
+# if @REPLACE_STRERROR@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef strerror
+# define strerror rpl_strerror
+# endif
+_GL_FUNCDECL_RPL (strerror, char *, (int));
+_GL_CXXALIAS_RPL (strerror, char *, (int));
+# else
+_GL_CXXALIAS_SYS (strerror, char *, (int));
+# endif
+_GL_CXXALIASWARN (strerror);
+#elif defined GNULIB_POSIXCHECK
+# undef strerror
+/* Assume strerror is always declared. */
+_GL_WARN_ON_USE (strerror, "strerror is unportable - "
+ "use gnulib module strerror to guarantee non-NULL result");
+#endif
+
+/* Map any int, typically from errno, into an error message. Multithread-safe.
+ Uses the POSIX declaration, not the glibc declaration. */
+#if @GNULIB_STRERROR_R@
+# if @REPLACE_STRERROR_R@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef strerror_r
+# define strerror_r rpl_strerror_r
+# endif
+_GL_FUNCDECL_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen)
+ _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen));
+# else
+# if !@HAVE_DECL_STRERROR_R@
+_GL_FUNCDECL_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen)
+ _GL_ARG_NONNULL ((2)));
+# endif
+_GL_CXXALIAS_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen));
+# endif
+# if @HAVE_DECL_STRERROR_R@
+_GL_CXXALIASWARN (strerror_r);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef strerror_r
+# if HAVE_RAW_DECL_STRERROR_R
+_GL_WARN_ON_USE (strerror_r, "strerror_r is unportable - "
+ "use gnulib module strerror_r-posix for portability");
+# endif
+#endif
+
+#if @GNULIB_STRSIGNAL@
+# if @REPLACE_STRSIGNAL@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define strsignal rpl_strsignal
+# endif
+_GL_FUNCDECL_RPL (strsignal, char *, (int __sig));
+_GL_CXXALIAS_RPL (strsignal, char *, (int __sig));
+# else
+# if ! @HAVE_DECL_STRSIGNAL@
+_GL_FUNCDECL_SYS (strsignal, char *, (int __sig));
+# endif
+/* Need to cast, because on Cygwin 1.5.x systems, the return type is
+ 'const char *'. */
+_GL_CXXALIAS_SYS_CAST (strsignal, char *, (int __sig));
+# endif
+_GL_CXXALIASWARN (strsignal);
+#elif defined GNULIB_POSIXCHECK
+# undef strsignal
+# if HAVE_RAW_DECL_STRSIGNAL
+_GL_WARN_ON_USE (strsignal, "strsignal is unportable - "
+ "use gnulib module strsignal for portability");
+# endif
+#endif
+
+#if @GNULIB_STRVERSCMP@
+# if !@HAVE_STRVERSCMP@
+_GL_FUNCDECL_SYS (strverscmp, int, (const char *, const char *)
+ _GL_ATTRIBUTE_PURE
+ _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (strverscmp, int, (const char *, const char *));
+_GL_CXXALIASWARN (strverscmp);
+#elif defined GNULIB_POSIXCHECK
+# undef strverscmp
+# if HAVE_RAW_DECL_STRVERSCMP
+_GL_WARN_ON_USE (strverscmp, "strverscmp is unportable - "
+ "use gnulib module strverscmp for portability");
+# endif
+#endif
+
+
+#endif /* _@GUARD_PREFIX@_STRING_H */
+#endif /* _@GUARD_PREFIX@_STRING_H */
+#endif
diff --git a/gnulib/strndup.c b/gnulib/strndup.c
new file mode 100644
index 0000000..5b74828
--- /dev/null
+++ b/gnulib/strndup.c
@@ -0,0 +1,36 @@
+/* A replacement function, for systems that lack strndup.
+
+ Copyright (C) 1996-1998, 2001-2003, 2005-2007, 2009-2019 Free Software
+ Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <stdlib.h>
+
+char *
+strndup (char const *s, size_t n)
+{
+ size_t len = strnlen (s, n);
+ char *new = malloc (len + 1);
+
+ if (new == NULL)
+ return NULL;
+
+ new[len] = '\0';
+ return memcpy (new, s, len);
+}
diff --git a/gnulib/strnlen.c b/gnulib/strnlen.c
new file mode 100644
index 0000000..9fb6635
--- /dev/null
+++ b/gnulib/strnlen.c
@@ -0,0 +1,30 @@
+/* Find the length of STRING, but scan at most MAXLEN characters.
+ Copyright (C) 2005-2007, 2009-2019 Free Software Foundation, Inc.
+ Written by Simon Josefsson.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <string.h>
+
+/* Find the length of STRING, but scan at most MAXLEN characters.
+ If no '\0' terminator is found in that many characters, return MAXLEN. */
+
+size_t
+strnlen (const char *string, size_t maxlen)
+{
+ const char *end = memchr (string, '\0', maxlen);
+ return end ? (size_t) (end - string) : maxlen;
+}
diff --git a/gnulib/sys_types.in.h b/gnulib/sys_types.in.h
new file mode 100644
index 0000000..237e206
--- /dev/null
+++ b/gnulib/sys_types.in.h
@@ -0,0 +1,106 @@
+/* Provide a more complete sys/types.h.
+
+ Copyright (C) 2011-2019 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+#if defined _WIN32 && !defined __CYGWIN__ \
+ && (defined __need_off_t || defined __need___off64_t \
+ || defined __need_ssize_t || defined __need_time_t)
+
+/* Special invocation convention inside mingw header files. */
+
+#@INCLUDE_NEXT@ @NEXT_SYS_TYPES_H@
+
+#else
+/* Normal invocation convention. */
+
+#ifndef _@GUARD_PREFIX@_SYS_TYPES_H
+
+/* The include_next requires a split double-inclusion guard. */
+# define _GL_INCLUDING_SYS_TYPES_H
+#@INCLUDE_NEXT@ @NEXT_SYS_TYPES_H@
+# undef _GL_INCLUDING_SYS_TYPES_H
+
+#ifndef _@GUARD_PREFIX@_SYS_TYPES_H
+#define _@GUARD_PREFIX@_SYS_TYPES_H
+
+/* Override off_t if Large File Support is requested on native Windows. */
+#if @WINDOWS_64_BIT_OFF_T@
+/* Same as int64_t in <stdint.h>. */
+# if defined _MSC_VER
+# define off_t __int64
+# else
+# define off_t long long int
+# endif
+/* Indicator, for gnulib internal purposes. */
+# define _GL_WINDOWS_64_BIT_OFF_T 1
+#endif
+
+/* Override dev_t and ino_t if distinguishable inodes support is requested
+ on native Windows. */
+#if @WINDOWS_STAT_INODES@
+
+# if @WINDOWS_STAT_INODES@ == 2
+/* Experimental, not useful in Windows 10. */
+
+/* Define dev_t to a 64-bit type. */
+# if !defined GNULIB_defined_dev_t
+typedef unsigned long long int rpl_dev_t;
+# undef dev_t
+# define dev_t rpl_dev_t
+# define GNULIB_defined_dev_t 1
+# endif
+
+/* Define ino_t to a 128-bit type. */
+# if !defined GNULIB_defined_ino_t
+/* MSVC does not have a 128-bit integer type.
+ GCC has a 128-bit integer type __int128, but only on 64-bit targets. */
+typedef struct { unsigned long long int _gl_ino[2]; } rpl_ino_t;
+# undef ino_t
+# define ino_t rpl_ino_t
+# define GNULIB_defined_ino_t 1
+# endif
+
+# else /* @WINDOWS_STAT_INODES@ == 1 */
+
+/* Define ino_t to a 64-bit type. */
+# if !defined GNULIB_defined_ino_t
+typedef unsigned long long int rpl_ino_t;
+# undef ino_t
+# define ino_t rpl_ino_t
+# define GNULIB_defined_ino_t 1
+# endif
+
+# endif
+
+/* Indicator, for gnulib internal purposes. */
+# define _GL_WINDOWS_STAT_INODES @WINDOWS_STAT_INODES@
+
+#endif
+
+/* MSVC 9 defines size_t in <stddef.h>, not in <sys/types.h>. */
+/* But avoid namespace pollution on glibc systems. */
+#if (defined _WIN32 && ! defined __CYGWIN__) && ! defined __GLIBC__
+# include <stddef.h>
+#endif
+
+#endif /* _@GUARD_PREFIX@_SYS_TYPES_H */
+#endif /* _@GUARD_PREFIX@_SYS_TYPES_H */
+#endif /* __need_XXX */
diff --git a/gnulib/unistd.c b/gnulib/unistd.c
new file mode 100644
index 0000000..72bad1c
--- /dev/null
+++ b/gnulib/unistd.c
@@ -0,0 +1,4 @@
+#include <config.h>
+#define _GL_UNISTD_INLINE _GL_EXTERN_INLINE
+#include "unistd.h"
+typedef int dummy;
diff --git a/gnulib/unistd.in.h b/gnulib/unistd.in.h
new file mode 100644
index 0000000..59ee39e
--- /dev/null
+++ b/gnulib/unistd.in.h
@@ -0,0 +1,1692 @@
+/* Substitute for and wrapper around <unistd.h>.
+ Copyright (C) 2003-2019 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _@GUARD_PREFIX@_UNISTD_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+#ifdef _GL_INCLUDING_UNISTD_H
+/* Special invocation convention:
+ - On Mac OS X 10.3.9 we have a sequence of nested includes
+ <unistd.h> -> <signal.h> -> <pthread.h> -> <unistd.h>
+ In this situation, the functions are not yet declared, therefore we cannot
+ provide the C++ aliases. */
+
+#@INCLUDE_NEXT@ @NEXT_UNISTD_H@
+
+#else
+/* Normal invocation convention. */
+
+/* The include_next requires a split double-inclusion guard. */
+#if @HAVE_UNISTD_H@
+# define _GL_INCLUDING_UNISTD_H
+# @INCLUDE_NEXT@ @NEXT_UNISTD_H@
+# undef _GL_INCLUDING_UNISTD_H
+#endif
+
+/* Get all possible declarations of gethostname(). */
+#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ \
+ && !defined _GL_INCLUDING_WINSOCK2_H
+# define _GL_INCLUDING_WINSOCK2_H
+# include <winsock2.h>
+# undef _GL_INCLUDING_WINSOCK2_H
+#endif
+
+#if !defined _@GUARD_PREFIX@_UNISTD_H && !defined _GL_INCLUDING_WINSOCK2_H
+#define _@GUARD_PREFIX@_UNISTD_H
+
+/* NetBSD 5.0 mis-defines NULL. Also get size_t. */
+/* But avoid namespace pollution on glibc systems. */
+#ifndef __GLIBC__
+# include <stddef.h>
+#endif
+
+/* mingw doesn't define the SEEK_* or *_FILENO macros in <unistd.h>. */
+/* MSVC declares 'unlink' in <stdio.h>, not in <unistd.h>. We must include
+ it before we #define unlink rpl_unlink. */
+/* Cygwin 1.7.1 declares symlinkat in <stdio.h>, not in <unistd.h>. */
+/* But avoid namespace pollution on glibc systems. */
+#if (!(defined SEEK_CUR && defined SEEK_END && defined SEEK_SET) \
+ || ((@GNULIB_UNLINK@ || defined GNULIB_POSIXCHECK) \
+ && (defined _WIN32 && ! defined __CYGWIN__)) \
+ || ((@GNULIB_SYMLINKAT@ || defined GNULIB_POSIXCHECK) \
+ && defined __CYGWIN__)) \
+ && ! defined __GLIBC__
+# include <stdio.h>
+#endif
+
+/* Cygwin 1.7.1 and Android 4.3 declare unlinkat in <fcntl.h>, not in
+ <unistd.h>. */
+/* But avoid namespace pollution on glibc systems. */
+#if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) \
+ && (defined __CYGWIN__ || defined __ANDROID__) \
+ && ! defined __GLIBC__
+# include <fcntl.h>
+#endif
+
+/* mingw fails to declare _exit in <unistd.h>. */
+/* mingw, MSVC, BeOS, Haiku declare environ in <stdlib.h>, not in
+ <unistd.h>. */
+/* Solaris declares getcwd not only in <unistd.h> but also in <stdlib.h>. */
+/* OSF Tru64 Unix cannot see gnulib rpl_strtod when system <stdlib.h> is
+ included here. */
+/* But avoid namespace pollution on glibc systems. */
+#if !defined __GLIBC__ && !defined __osf__
+# define __need_system_stdlib_h
+# include <stdlib.h>
+# undef __need_system_stdlib_h
+#endif
+
+/* Native Windows platforms declare chdir, getcwd, rmdir in
+ <io.h> and/or <direct.h>, not in <unistd.h>.
+ They also declare access(), chmod(), close(), dup(), dup2(), isatty(),
+ lseek(), read(), unlink(), write() in <io.h>. */
+#if ((@GNULIB_CHDIR@ || @GNULIB_GETCWD@ || @GNULIB_RMDIR@ \
+ || defined GNULIB_POSIXCHECK) \
+ && (defined _WIN32 && ! defined __CYGWIN__))
+# include <io.h> /* mingw32, mingw64 */
+# include <direct.h> /* mingw64, MSVC 9 */
+#elif (@GNULIB_CLOSE@ || @GNULIB_DUP@ || @GNULIB_DUP2@ || @GNULIB_ISATTY@ \
+ || @GNULIB_LSEEK@ || @GNULIB_READ@ || @GNULIB_UNLINK@ || @GNULIB_WRITE@ \
+ || defined GNULIB_POSIXCHECK) \
+ && (defined _WIN32 && ! defined __CYGWIN__)
+# include <io.h>
+#endif
+
+/* AIX and OSF/1 5.1 declare getdomainname in <netdb.h>, not in <unistd.h>.
+ NonStop Kernel declares gethostname in <netdb.h>, not in <unistd.h>. */
+/* But avoid namespace pollution on glibc systems. */
+#if ((@GNULIB_GETDOMAINNAME@ && (defined _AIX || defined __osf__)) \
+ || (@GNULIB_GETHOSTNAME@ && defined __TANDEM)) \
+ && !defined __GLIBC__
+# include <netdb.h>
+#endif
+
+/* Android 4.3 declares fchownat in <sys/stat.h>, not in <unistd.h>. */
+/* But avoid namespace pollution on glibc systems. */
+#if (@GNULIB_FCHOWNAT@ || defined GNULIB_POSIXCHECK) && defined __ANDROID__ \
+ && !defined __GLIBC__
+# include <sys/stat.h>
+#endif
+
+/* MSVC defines off_t in <sys/types.h>.
+ May also define off_t to a 64-bit type on native Windows. */
+/* But avoid namespace pollution on glibc systems. */
+#ifndef __GLIBC__
+/* Get off_t, ssize_t. */
+# include <sys/types.h>
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
+
+/* The definition of _GL_ARG_NONNULL is copied here. */
+
+/* The definition of _GL_WARN_ON_USE is copied here. */
+
+
+/* Get getopt(), optarg, optind, opterr, optopt. */
+#if @GNULIB_UNISTD_H_GETOPT@ && !defined _GL_SYSTEM_GETOPT
+# include <getopt-cdefs.h>
+# include <getopt-pfx-core.h>
+#endif
+
+#ifndef _GL_INLINE_HEADER_BEGIN
+ #error "Please include config.h first."
+#endif
+_GL_INLINE_HEADER_BEGIN
+#ifndef _GL_UNISTD_INLINE
+# define _GL_UNISTD_INLINE _GL_INLINE
+#endif
+
+/* Hide some function declarations from <winsock2.h>. */
+
+#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@
+# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef socket
+# define socket socket_used_without_including_sys_socket_h
+# undef connect
+# define connect connect_used_without_including_sys_socket_h
+# undef accept
+# define accept accept_used_without_including_sys_socket_h
+# undef bind
+# define bind bind_used_without_including_sys_socket_h
+# undef getpeername
+# define getpeername getpeername_used_without_including_sys_socket_h
+# undef getsockname
+# define getsockname getsockname_used_without_including_sys_socket_h
+# undef getsockopt
+# define getsockopt getsockopt_used_without_including_sys_socket_h
+# undef listen
+# define listen listen_used_without_including_sys_socket_h
+# undef recv
+# define recv recv_used_without_including_sys_socket_h
+# undef send
+# define send send_used_without_including_sys_socket_h
+# undef recvfrom
+# define recvfrom recvfrom_used_without_including_sys_socket_h
+# undef sendto
+# define sendto sendto_used_without_including_sys_socket_h
+# undef setsockopt
+# define setsockopt setsockopt_used_without_including_sys_socket_h
+# undef shutdown
+# define shutdown shutdown_used_without_including_sys_socket_h
+# else
+ _GL_WARN_ON_USE (socket,
+ "socket() used without including <sys/socket.h>");
+ _GL_WARN_ON_USE (connect,
+ "connect() used without including <sys/socket.h>");
+ _GL_WARN_ON_USE (accept,
+ "accept() used without including <sys/socket.h>");
+ _GL_WARN_ON_USE (bind,
+ "bind() used without including <sys/socket.h>");
+ _GL_WARN_ON_USE (getpeername,
+ "getpeername() used without including <sys/socket.h>");
+ _GL_WARN_ON_USE (getsockname,
+ "getsockname() used without including <sys/socket.h>");
+ _GL_WARN_ON_USE (getsockopt,
+ "getsockopt() used without including <sys/socket.h>");
+ _GL_WARN_ON_USE (listen,
+ "listen() used without including <sys/socket.h>");
+ _GL_WARN_ON_USE (recv,
+ "recv() used without including <sys/socket.h>");
+ _GL_WARN_ON_USE (send,
+ "send() used without including <sys/socket.h>");
+ _GL_WARN_ON_USE (recvfrom,
+ "recvfrom() used without including <sys/socket.h>");
+ _GL_WARN_ON_USE (sendto,
+ "sendto() used without including <sys/socket.h>");
+ _GL_WARN_ON_USE (setsockopt,
+ "setsockopt() used without including <sys/socket.h>");
+ _GL_WARN_ON_USE (shutdown,
+ "shutdown() used without including <sys/socket.h>");
+# endif
+# endif
+# if !defined _@GUARD_PREFIX@_SYS_SELECT_H
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef select
+# define select select_used_without_including_sys_select_h
+# else
+ _GL_WARN_ON_USE (select,
+ "select() used without including <sys/select.h>");
+# endif
+# endif
+#endif
+
+
+/* OS/2 EMX lacks these macros. */
+#ifndef STDIN_FILENO
+# define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+# define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+
+/* Ensure *_OK macros exist. */
+#ifndef F_OK
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+
+
+/* Declare overridden functions. */
+
+
+#if defined GNULIB_POSIXCHECK
+/* The access() function is a security risk. */
+_GL_WARN_ON_USE (access, "the access function is a security risk - "
+ "use the gnulib module faccessat instead");
+#endif
+
+
+#if @GNULIB_CHDIR@
+_GL_CXXALIAS_SYS (chdir, int, (const char *file) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIASWARN (chdir);
+#elif defined GNULIB_POSIXCHECK
+# undef chdir
+# if HAVE_RAW_DECL_CHDIR
+_GL_WARN_ON_USE (chown, "chdir is not always in <unistd.h> - "
+ "use gnulib module chdir for portability");
+# endif
+#endif
+
+
+#if @GNULIB_CHOWN@
+/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE
+ to GID (if GID is not -1). Follow symbolic links.
+ Return 0 if successful, otherwise -1 and errno set.
+ See the POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/chown.html. */
+# if @REPLACE_CHOWN@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef chown
+# define chown rpl_chown
+# endif
+_GL_FUNCDECL_RPL (chown, int, (const char *file, uid_t uid, gid_t gid)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (chown, int, (const char *file, uid_t uid, gid_t gid));
+# else
+# if !@HAVE_CHOWN@
+_GL_FUNCDECL_SYS (chown, int, (const char *file, uid_t uid, gid_t gid)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (chown, int, (const char *file, uid_t uid, gid_t gid));
+# endif
+_GL_CXXALIASWARN (chown);
+#elif defined GNULIB_POSIXCHECK
+# undef chown
+# if HAVE_RAW_DECL_CHOWN
+_GL_WARN_ON_USE (chown, "chown fails to follow symlinks on some systems and "
+ "doesn't treat a uid or gid of -1 on some systems - "
+ "use gnulib module chown for portability");
+# endif
+#endif
+
+
+#if @GNULIB_CLOSE@
+# if @REPLACE_CLOSE@
+/* Automatically included by modules that need a replacement for close. */
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef close
+# define close rpl_close
+# endif
+_GL_FUNCDECL_RPL (close, int, (int fd));
+_GL_CXXALIAS_RPL (close, int, (int fd));
+# else
+_GL_CXXALIAS_SYS (close, int, (int fd));
+# endif
+_GL_CXXALIASWARN (close);
+#elif @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+# undef close
+# define close close_used_without_requesting_gnulib_module_close
+#elif defined GNULIB_POSIXCHECK
+# undef close
+/* Assume close is always declared. */
+_GL_WARN_ON_USE (close, "close does not portably work on sockets - "
+ "use gnulib module close for portability");
+#endif
+
+
+#if @GNULIB_COPY_FILE_RANGE@
+# if !@HAVE_COPY_FILE_RANGE@
+_GL_FUNCDECL_SYS (copy_file_range, ssize_t, (int ifd, off_t *ipos,
+ int ofd, off_t *opos,
+ size_t len, unsigned flags));
+_GL_CXXALIAS_SYS (copy_file_range, ssize_t, (int ifd, off_t *ipos,
+ int ofd, off_t *opos,
+ size_t len, unsigned flags));
+# endif
+_GL_CXXALIASWARN (copy_file_range);
+#elif defined GNULIB_POSIXCHECK
+/* Assume copy_file_range is always declared. */
+_GL_WARN_ON_USE (copy_file_range,
+ "copy_file_range is unportable - "
+ "use gnulib module copy_file_range for portability");
+#endif
+
+
+#if @GNULIB_DUP@
+# if @REPLACE_DUP@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define dup rpl_dup
+# endif
+_GL_FUNCDECL_RPL (dup, int, (int oldfd));
+_GL_CXXALIAS_RPL (dup, int, (int oldfd));
+# else
+_GL_CXXALIAS_SYS (dup, int, (int oldfd));
+# endif
+_GL_CXXALIASWARN (dup);
+#elif defined GNULIB_POSIXCHECK
+# undef dup
+# if HAVE_RAW_DECL_DUP
+_GL_WARN_ON_USE (dup, "dup is unportable - "
+ "use gnulib module dup for portability");
+# endif
+#endif
+
+
+#if @GNULIB_DUP2@
+/* Copy the file descriptor OLDFD into file descriptor NEWFD. Do nothing if
+ NEWFD = OLDFD, otherwise close NEWFD first if it is open.
+ Return newfd if successful, otherwise -1 and errno set.
+ See the POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/dup2.html>. */
+# if @REPLACE_DUP2@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define dup2 rpl_dup2
+# endif
+_GL_FUNCDECL_RPL (dup2, int, (int oldfd, int newfd));
+_GL_CXXALIAS_RPL (dup2, int, (int oldfd, int newfd));
+# else
+# if !@HAVE_DUP2@
+_GL_FUNCDECL_SYS (dup2, int, (int oldfd, int newfd));
+# endif
+_GL_CXXALIAS_SYS (dup2, int, (int oldfd, int newfd));
+# endif
+_GL_CXXALIASWARN (dup2);
+#elif defined GNULIB_POSIXCHECK
+# undef dup2
+# if HAVE_RAW_DECL_DUP2
+_GL_WARN_ON_USE (dup2, "dup2 is unportable - "
+ "use gnulib module dup2 for portability");
+# endif
+#endif
+
+
+#if @GNULIB_DUP3@
+/* Copy the file descriptor OLDFD into file descriptor NEWFD, with the
+ specified flags.
+ The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
+ and O_TEXT, O_BINARY (defined in "binary-io.h").
+ Close NEWFD first if it is open.
+ Return newfd if successful, otherwise -1 and errno set.
+ See the Linux man page at
+ <https://www.kernel.org/doc/man-pages/online/pages/man2/dup3.2.html>. */
+# if @HAVE_DUP3@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define dup3 rpl_dup3
+# endif
+_GL_FUNCDECL_RPL (dup3, int, (int oldfd, int newfd, int flags));
+_GL_CXXALIAS_RPL (dup3, int, (int oldfd, int newfd, int flags));
+# else
+_GL_FUNCDECL_SYS (dup3, int, (int oldfd, int newfd, int flags));
+_GL_CXXALIAS_SYS (dup3, int, (int oldfd, int newfd, int flags));
+# endif
+_GL_CXXALIASWARN (dup3);
+#elif defined GNULIB_POSIXCHECK
+# undef dup3
+# if HAVE_RAW_DECL_DUP3
+_GL_WARN_ON_USE (dup3, "dup3 is unportable - "
+ "use gnulib module dup3 for portability");
+# endif
+#endif
+
+
+#if @GNULIB_ENVIRON@
+# if defined __CYGWIN__ && !defined __i386__
+/* The 'environ' variable is defined in a DLL. Therefore its declaration needs
+ the '__declspec(dllimport)' attribute, but the system's <unistd.h> lacks it.
+ This leads to a link error on 64-bit Cygwin when the option
+ -Wl,--disable-auto-import is in use. */
+_GL_EXTERN_C __declspec(dllimport) char **environ;
+# endif
+# if !@HAVE_DECL_ENVIRON@
+/* Set of environment variables and values. An array of strings of the form
+ "VARIABLE=VALUE", terminated with a NULL. */
+# if defined __APPLE__ && defined __MACH__
+# include <TargetConditionals.h>
+# if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
+# define _GL_USE_CRT_EXTERNS
+# endif
+# endif
+# ifdef _GL_USE_CRT_EXTERNS
+# include <crt_externs.h>
+# define environ (*_NSGetEnviron ())
+# else
+# ifdef __cplusplus
+extern "C" {
+# endif
+extern char **environ;
+# ifdef __cplusplus
+}
+# endif
+# endif
+# endif
+#elif defined GNULIB_POSIXCHECK
+# if HAVE_RAW_DECL_ENVIRON
+_GL_UNISTD_INLINE char ***
+_GL_WARN_ON_USE_ATTRIBUTE ("environ is unportable - "
+ "use gnulib module environ for portability")
+rpl_environ (void)
+{
+ return &environ;
+}
+# undef environ
+# define environ (*rpl_environ ())
+# endif
+#endif
+
+
+#if @GNULIB_EUIDACCESS@
+/* Like access(), except that it uses the effective user id and group id of
+ the current process. */
+# if !@HAVE_EUIDACCESS@
+_GL_FUNCDECL_SYS (euidaccess, int, (const char *filename, int mode)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (euidaccess, int, (const char *filename, int mode));
+_GL_CXXALIASWARN (euidaccess);
+# if defined GNULIB_POSIXCHECK
+/* Like access(), this function is a security risk. */
+_GL_WARN_ON_USE (euidaccess, "the euidaccess function is a security risk - "
+ "use the gnulib module faccessat instead");
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef euidaccess
+# if HAVE_RAW_DECL_EUIDACCESS
+_GL_WARN_ON_USE (euidaccess, "euidaccess is unportable - "
+ "use gnulib module euidaccess for portability");
+# endif
+#endif
+
+
+#if @GNULIB_FACCESSAT@
+# if @REPLACE_FACCESSAT@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef faccessat
+# define faccessat rpl_faccessat
+# endif
+_GL_FUNCDECL_RPL (faccessat, int,
+ (int fd, char const *name, int mode, int flag)
+ _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (faccessat, int,
+ (int fd, char const *name, int mode, int flag));
+# else
+# if !@HAVE_FACCESSAT@
+_GL_FUNCDECL_SYS (faccessat, int,
+ (int fd, char const *file, int mode, int flag)
+ _GL_ARG_NONNULL ((2)));
+# endif
+_GL_CXXALIAS_SYS (faccessat, int,
+ (int fd, char const *file, int mode, int flag));
+# endif
+_GL_CXXALIASWARN (faccessat);
+#elif defined GNULIB_POSIXCHECK
+# undef faccessat
+# if HAVE_RAW_DECL_FACCESSAT
+_GL_WARN_ON_USE (faccessat, "faccessat is not portable - "
+ "use gnulib module faccessat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_FCHDIR@
+/* Change the process' current working directory to the directory on which
+ the given file descriptor is open.
+ Return 0 if successful, otherwise -1 and errno set.
+ See the POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html>. */
+# if ! @HAVE_FCHDIR@
+_GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/));
+
+/* Gnulib internal hooks needed to maintain the fchdir metadata. */
+_GL_EXTERN_C int _gl_register_fd (int fd, const char *filename)
+ _GL_ARG_NONNULL ((2));
+_GL_EXTERN_C void _gl_unregister_fd (int fd);
+_GL_EXTERN_C int _gl_register_dup (int oldfd, int newfd);
+_GL_EXTERN_C const char *_gl_directory_name (int fd);
+
+# else
+# if !@HAVE_DECL_FCHDIR@
+_GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/));
+# endif
+# endif
+_GL_CXXALIAS_SYS (fchdir, int, (int /*fd*/));
+_GL_CXXALIASWARN (fchdir);
+#elif defined GNULIB_POSIXCHECK
+# undef fchdir
+# if HAVE_RAW_DECL_FCHDIR
+_GL_WARN_ON_USE (fchdir, "fchdir is unportable - "
+ "use gnulib module fchdir for portability");
+# endif
+#endif
+
+
+#if @GNULIB_FCHOWNAT@
+# if @REPLACE_FCHOWNAT@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef fchownat
+# define fchownat rpl_fchownat
+# endif
+_GL_FUNCDECL_RPL (fchownat, int, (int fd, char const *file,
+ uid_t owner, gid_t group, int flag)
+ _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (fchownat, int, (int fd, char const *file,
+ uid_t owner, gid_t group, int flag));
+# else
+# if !@HAVE_FCHOWNAT@
+_GL_FUNCDECL_SYS (fchownat, int, (int fd, char const *file,
+ uid_t owner, gid_t group, int flag)
+ _GL_ARG_NONNULL ((2)));
+# endif
+_GL_CXXALIAS_SYS (fchownat, int, (int fd, char const *file,
+ uid_t owner, gid_t group, int flag));
+# endif
+_GL_CXXALIASWARN (fchownat);
+#elif defined GNULIB_POSIXCHECK
+# undef fchownat
+# if HAVE_RAW_DECL_FCHOWNAT
+_GL_WARN_ON_USE (fchownat, "fchownat is not portable - "
+ "use gnulib module openat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_FDATASYNC@
+/* Synchronize changes to a file.
+ Return 0 if successful, otherwise -1 and errno set.
+ See POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html>. */
+# if !@HAVE_FDATASYNC@ || !@HAVE_DECL_FDATASYNC@
+_GL_FUNCDECL_SYS (fdatasync, int, (int fd));
+# endif
+_GL_CXXALIAS_SYS (fdatasync, int, (int fd));
+_GL_CXXALIASWARN (fdatasync);
+#elif defined GNULIB_POSIXCHECK
+# undef fdatasync
+# if HAVE_RAW_DECL_FDATASYNC
+_GL_WARN_ON_USE (fdatasync, "fdatasync is unportable - "
+ "use gnulib module fdatasync for portability");
+# endif
+#endif
+
+
+#if @GNULIB_FSYNC@
+/* Synchronize changes, including metadata, to a file.
+ Return 0 if successful, otherwise -1 and errno set.
+ See POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html>. */
+# if !@HAVE_FSYNC@
+_GL_FUNCDECL_SYS (fsync, int, (int fd));
+# endif
+_GL_CXXALIAS_SYS (fsync, int, (int fd));
+_GL_CXXALIASWARN (fsync);
+#elif defined GNULIB_POSIXCHECK
+# undef fsync
+# if HAVE_RAW_DECL_FSYNC
+_GL_WARN_ON_USE (fsync, "fsync is unportable - "
+ "use gnulib module fsync for portability");
+# endif
+#endif
+
+
+#if @GNULIB_FTRUNCATE@
+/* Change the size of the file to which FD is opened to become equal to LENGTH.
+ Return 0 if successful, otherwise -1 and errno set.
+ See the POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html>. */
+# if @REPLACE_FTRUNCATE@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef ftruncate
+# define ftruncate rpl_ftruncate
+# endif
+_GL_FUNCDECL_RPL (ftruncate, int, (int fd, off_t length));
+_GL_CXXALIAS_RPL (ftruncate, int, (int fd, off_t length));
+# else
+# if !@HAVE_FTRUNCATE@
+_GL_FUNCDECL_SYS (ftruncate, int, (int fd, off_t length));
+# endif
+_GL_CXXALIAS_SYS (ftruncate, int, (int fd, off_t length));
+# endif
+_GL_CXXALIASWARN (ftruncate);
+#elif defined GNULIB_POSIXCHECK
+# undef ftruncate
+# if HAVE_RAW_DECL_FTRUNCATE
+_GL_WARN_ON_USE (ftruncate, "ftruncate is unportable - "
+ "use gnulib module ftruncate for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETCWD@
+/* Get the name of the current working directory, and put it in SIZE bytes
+ of BUF.
+ Return BUF if successful, or NULL if the directory couldn't be determined
+ or SIZE was too small.
+ See the POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html>.
+ Additionally, the gnulib module 'getcwd' guarantees the following GNU
+ extension: If BUF is NULL, an array is allocated with 'malloc'; the array
+ is SIZE bytes long, unless SIZE == 0, in which case it is as big as
+ necessary. */
+# if @REPLACE_GETCWD@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define getcwd rpl_getcwd
+# endif
+_GL_FUNCDECL_RPL (getcwd, char *, (char *buf, size_t size));
+_GL_CXXALIAS_RPL (getcwd, char *, (char *buf, size_t size));
+# else
+/* Need to cast, because on mingw, the second parameter is
+ int size. */
+_GL_CXXALIAS_SYS_CAST (getcwd, char *, (char *buf, size_t size));
+# endif
+_GL_CXXALIASWARN (getcwd);
+#elif defined GNULIB_POSIXCHECK
+# undef getcwd
+# if HAVE_RAW_DECL_GETCWD
+_GL_WARN_ON_USE (getcwd, "getcwd is unportable - "
+ "use gnulib module getcwd for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETDOMAINNAME@
+/* Return the NIS domain name of the machine.
+ WARNING! The NIS domain name is unrelated to the fully qualified host name
+ of the machine. It is also unrelated to email addresses.
+ WARNING! The NIS domain name is usually the empty string or "(none)" when
+ not using NIS.
+
+ Put up to LEN bytes of the NIS domain name into NAME.
+ Null terminate it if the name is shorter than LEN.
+ If the NIS domain name is longer than LEN, set errno = EINVAL and return -1.
+ Return 0 if successful, otherwise set errno and return -1. */
+# if @REPLACE_GETDOMAINNAME@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef getdomainname
+# define getdomainname rpl_getdomainname
+# endif
+_GL_FUNCDECL_RPL (getdomainname, int, (char *name, size_t len)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (getdomainname, int, (char *name, size_t len));
+# else
+# if !@HAVE_DECL_GETDOMAINNAME@
+_GL_FUNCDECL_SYS (getdomainname, int, (char *name, size_t len)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (getdomainname, int, (char *name, size_t len));
+# endif
+_GL_CXXALIASWARN (getdomainname);
+#elif defined GNULIB_POSIXCHECK
+# undef getdomainname
+# if HAVE_RAW_DECL_GETDOMAINNAME
+_GL_WARN_ON_USE (getdomainname, "getdomainname is unportable - "
+ "use gnulib module getdomainname for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETDTABLESIZE@
+/* Return the maximum number of file descriptors in the current process.
+ In POSIX, this is same as sysconf (_SC_OPEN_MAX). */
+# if @REPLACE_GETDTABLESIZE@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef getdtablesize
+# define getdtablesize rpl_getdtablesize
+# endif
+_GL_FUNCDECL_RPL (getdtablesize, int, (void));
+_GL_CXXALIAS_RPL (getdtablesize, int, (void));
+# else
+# if !@HAVE_GETDTABLESIZE@
+_GL_FUNCDECL_SYS (getdtablesize, int, (void));
+# endif
+_GL_CXXALIAS_SYS (getdtablesize, int, (void));
+# endif
+_GL_CXXALIASWARN (getdtablesize);
+#elif defined GNULIB_POSIXCHECK
+# undef getdtablesize
+# if HAVE_RAW_DECL_GETDTABLESIZE
+_GL_WARN_ON_USE (getdtablesize, "getdtablesize is unportable - "
+ "use gnulib module getdtablesize for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETGROUPS@
+/* Return the supplemental groups that the current process belongs to.
+ It is unspecified whether the effective group id is in the list.
+ If N is 0, return the group count; otherwise, N describes how many
+ entries are available in GROUPS. Return -1 and set errno if N is
+ not 0 and not large enough. Fails with ENOSYS on some systems. */
+# if @REPLACE_GETGROUPS@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef getgroups
+# define getgroups rpl_getgroups
+# endif
+_GL_FUNCDECL_RPL (getgroups, int, (int n, gid_t *groups));
+_GL_CXXALIAS_RPL (getgroups, int, (int n, gid_t *groups));
+# else
+# if !@HAVE_GETGROUPS@
+_GL_FUNCDECL_SYS (getgroups, int, (int n, gid_t *groups));
+# endif
+_GL_CXXALIAS_SYS (getgroups, int, (int n, gid_t *groups));
+# endif
+_GL_CXXALIASWARN (getgroups);
+#elif defined GNULIB_POSIXCHECK
+# undef getgroups
+# if HAVE_RAW_DECL_GETGROUPS
+_GL_WARN_ON_USE (getgroups, "getgroups is unportable - "
+ "use gnulib module getgroups for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETHOSTNAME@
+/* Return the standard host name of the machine.
+ WARNING! The host name may or may not be fully qualified.
+
+ Put up to LEN bytes of the host name into NAME.
+ Null terminate it if the name is shorter than LEN.
+ If the host name is longer than LEN, set errno = EINVAL and return -1.
+ Return 0 if successful, otherwise set errno and return -1. */
+# if @UNISTD_H_HAVE_WINSOCK2_H@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef gethostname
+# define gethostname rpl_gethostname
+# endif
+_GL_FUNCDECL_RPL (gethostname, int, (char *name, size_t len)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (gethostname, int, (char *name, size_t len));
+# else
+# if !@HAVE_GETHOSTNAME@
+_GL_FUNCDECL_SYS (gethostname, int, (char *name, size_t len)
+ _GL_ARG_NONNULL ((1)));
+# endif
+/* Need to cast, because on Solaris 10 and OSF/1 5.1 systems, the second
+ parameter is
+ int len. */
+_GL_CXXALIAS_SYS_CAST (gethostname, int, (char *name, size_t len));
+# endif
+_GL_CXXALIASWARN (gethostname);
+#elif @UNISTD_H_HAVE_WINSOCK2_H@
+# undef gethostname
+# define gethostname gethostname_used_without_requesting_gnulib_module_gethostname
+#elif defined GNULIB_POSIXCHECK
+# undef gethostname
+# if HAVE_RAW_DECL_GETHOSTNAME
+_GL_WARN_ON_USE (gethostname, "gethostname is unportable - "
+ "use gnulib module gethostname for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETLOGIN@
+/* Returns the user's login name, or NULL if it cannot be found. Upon error,
+ returns NULL with errno set.
+
+ See <http://www.opengroup.org/susv3xsh/getlogin.html>.
+
+ Most programs don't need to use this function, because the information is
+ available through environment variables:
+ ${LOGNAME-$USER} on Unix platforms,
+ $USERNAME on native Windows platforms.
+ */
+# if !@HAVE_DECL_GETLOGIN@
+_GL_FUNCDECL_SYS (getlogin, char *, (void));
+# endif
+_GL_CXXALIAS_SYS (getlogin, char *, (void));
+_GL_CXXALIASWARN (getlogin);
+#elif defined GNULIB_POSIXCHECK
+# undef getlogin
+# if HAVE_RAW_DECL_GETLOGIN
+_GL_WARN_ON_USE (getlogin, "getlogin is unportable - "
+ "use gnulib module getlogin for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETLOGIN_R@
+/* Copies the user's login name to NAME.
+ The array pointed to by NAME has room for SIZE bytes.
+
+ Returns 0 if successful. Upon error, an error number is returned, or -1 in
+ the case that the login name cannot be found but no specific error is
+ provided (this case is hopefully rare but is left open by the POSIX spec).
+
+ See <http://www.opengroup.org/susv3xsh/getlogin.html>.
+
+ Most programs don't need to use this function, because the information is
+ available through environment variables:
+ ${LOGNAME-$USER} on Unix platforms,
+ $USERNAME on native Windows platforms.
+ */
+# if @REPLACE_GETLOGIN_R@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define getlogin_r rpl_getlogin_r
+# endif
+_GL_FUNCDECL_RPL (getlogin_r, int, (char *name, size_t size)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (getlogin_r, int, (char *name, size_t size));
+# else
+# if !@HAVE_DECL_GETLOGIN_R@
+_GL_FUNCDECL_SYS (getlogin_r, int, (char *name, size_t size)
+ _GL_ARG_NONNULL ((1)));
+# endif
+/* Need to cast, because on Solaris 10 systems, the second argument is
+ int size. */
+_GL_CXXALIAS_SYS_CAST (getlogin_r, int, (char *name, size_t size));
+# endif
+_GL_CXXALIASWARN (getlogin_r);
+#elif defined GNULIB_POSIXCHECK
+# undef getlogin_r
+# if HAVE_RAW_DECL_GETLOGIN_R
+_GL_WARN_ON_USE (getlogin_r, "getlogin_r is unportable - "
+ "use gnulib module getlogin_r for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETPAGESIZE@
+# if @REPLACE_GETPAGESIZE@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define getpagesize rpl_getpagesize
+# endif
+_GL_FUNCDECL_RPL (getpagesize, int, (void));
+_GL_CXXALIAS_RPL (getpagesize, int, (void));
+# else
+# if !@HAVE_GETPAGESIZE@
+# if !defined getpagesize
+/* This is for POSIX systems. */
+# if !defined _gl_getpagesize && defined _SC_PAGESIZE
+# if ! (defined __VMS && __VMS_VER < 70000000)
+# define _gl_getpagesize() sysconf (_SC_PAGESIZE)
+# endif
+# endif
+/* This is for older VMS. */
+# if !defined _gl_getpagesize && defined __VMS
+# ifdef __ALPHA
+# define _gl_getpagesize() 8192
+# else
+# define _gl_getpagesize() 512
+# endif
+# endif
+/* This is for BeOS. */
+# if !defined _gl_getpagesize && @HAVE_OS_H@
+# include <OS.h>
+# if defined B_PAGE_SIZE
+# define _gl_getpagesize() B_PAGE_SIZE
+# endif
+# endif
+/* This is for AmigaOS4.0. */
+# if !defined _gl_getpagesize && defined __amigaos4__
+# define _gl_getpagesize() 2048
+# endif
+/* This is for older Unix systems. */
+# if !defined _gl_getpagesize && @HAVE_SYS_PARAM_H@
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define _gl_getpagesize() EXEC_PAGESIZE
+# else
+# ifdef NBPG
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif
+# define _gl_getpagesize() (NBPG * CLSIZE)
+# else
+# ifdef NBPC
+# define _gl_getpagesize() NBPC
+# endif
+# endif
+# endif
+# endif
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define getpagesize() _gl_getpagesize ()
+# else
+# if !GNULIB_defined_getpagesize_function
+_GL_UNISTD_INLINE int
+getpagesize ()
+{
+ return _gl_getpagesize ();
+}
+# define GNULIB_defined_getpagesize_function 1
+# endif
+# endif
+# endif
+# endif
+/* Need to cast, because on Cygwin 1.5.x systems, the return type is size_t. */
+_GL_CXXALIAS_SYS_CAST (getpagesize, int, (void));
+# endif
+# if @HAVE_DECL_GETPAGESIZE@
+_GL_CXXALIASWARN (getpagesize);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef getpagesize
+# if HAVE_RAW_DECL_GETPAGESIZE
+_GL_WARN_ON_USE (getpagesize, "getpagesize is unportable - "
+ "use gnulib module getpagesize for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETPASS@
+/* Function getpass() from module 'getpass':
+ Read a password from /dev/tty or stdin.
+ Function getpass() from module 'getpass-gnu':
+ Read a password of arbitrary length from /dev/tty or stdin. */
+# if @REPLACE_GETPASS@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef getpass
+# define getpass rpl_getpass
+# endif
+_GL_FUNCDECL_RPL (getpass, char *, (const char *prompt)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (getpass, char *, (const char *prompt));
+# else
+# if !@HAVE_GETPASS@
+_GL_FUNCDECL_SYS (getpass, char *, (const char *prompt)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (getpass, char *, (const char *prompt));
+# endif
+_GL_CXXALIASWARN (getpass);
+#elif defined GNULIB_POSIXCHECK
+# undef getpass
+# if HAVE_RAW_DECL_GETPASS
+_GL_WARN_ON_USE (getpass, "getpass is unportable - "
+ "use gnulib module getpass or getpass-gnu for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETUSERSHELL@
+/* Return the next valid login shell on the system, or NULL when the end of
+ the list has been reached. */
+# if !@HAVE_DECL_GETUSERSHELL@
+_GL_FUNCDECL_SYS (getusershell, char *, (void));
+# endif
+_GL_CXXALIAS_SYS (getusershell, char *, (void));
+_GL_CXXALIASWARN (getusershell);
+#elif defined GNULIB_POSIXCHECK
+# undef getusershell
+# if HAVE_RAW_DECL_GETUSERSHELL
+_GL_WARN_ON_USE (getusershell, "getusershell is unportable - "
+ "use gnulib module getusershell for portability");
+# endif
+#endif
+
+#if @GNULIB_GETUSERSHELL@
+/* Rewind to pointer that is advanced at each getusershell() call. */
+# if !@HAVE_DECL_GETUSERSHELL@
+_GL_FUNCDECL_SYS (setusershell, void, (void));
+# endif
+_GL_CXXALIAS_SYS (setusershell, void, (void));
+_GL_CXXALIASWARN (setusershell);
+#elif defined GNULIB_POSIXCHECK
+# undef setusershell
+# if HAVE_RAW_DECL_SETUSERSHELL
+_GL_WARN_ON_USE (setusershell, "setusershell is unportable - "
+ "use gnulib module getusershell for portability");
+# endif
+#endif
+
+#if @GNULIB_GETUSERSHELL@
+/* Free the pointer that is advanced at each getusershell() call and
+ associated resources. */
+# if !@HAVE_DECL_GETUSERSHELL@
+_GL_FUNCDECL_SYS (endusershell, void, (void));
+# endif
+_GL_CXXALIAS_SYS (endusershell, void, (void));
+_GL_CXXALIASWARN (endusershell);
+#elif defined GNULIB_POSIXCHECK
+# undef endusershell
+# if HAVE_RAW_DECL_ENDUSERSHELL
+_GL_WARN_ON_USE (endusershell, "endusershell is unportable - "
+ "use gnulib module getusershell for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GROUP_MEMBER@
+/* Determine whether group id is in calling user's group list. */
+# if !@HAVE_GROUP_MEMBER@
+_GL_FUNCDECL_SYS (group_member, int, (gid_t gid));
+# endif
+_GL_CXXALIAS_SYS (group_member, int, (gid_t gid));
+_GL_CXXALIASWARN (group_member);
+#elif defined GNULIB_POSIXCHECK
+# undef group_member
+# if HAVE_RAW_DECL_GROUP_MEMBER
+_GL_WARN_ON_USE (group_member, "group_member is unportable - "
+ "use gnulib module group-member for portability");
+# endif
+#endif
+
+
+#if @GNULIB_ISATTY@
+# if @REPLACE_ISATTY@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef isatty
+# define isatty rpl_isatty
+# endif
+_GL_FUNCDECL_RPL (isatty, int, (int fd));
+_GL_CXXALIAS_RPL (isatty, int, (int fd));
+# else
+_GL_CXXALIAS_SYS (isatty, int, (int fd));
+# endif
+_GL_CXXALIASWARN (isatty);
+#elif defined GNULIB_POSIXCHECK
+# undef isatty
+# if HAVE_RAW_DECL_ISATTY
+_GL_WARN_ON_USE (isatty, "isatty has portability problems on native Windows - "
+ "use gnulib module isatty for portability");
+# endif
+#endif
+
+
+#if @GNULIB_LCHOWN@
+/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE
+ to GID (if GID is not -1). Do not follow symbolic links.
+ Return 0 if successful, otherwise -1 and errno set.
+ See the POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/lchown.html>. */
+# if @REPLACE_LCHOWN@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef lchown
+# define lchown rpl_lchown
+# endif
+_GL_FUNCDECL_RPL (lchown, int, (char const *file, uid_t owner, gid_t group)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (lchown, int, (char const *file, uid_t owner, gid_t group));
+# else
+# if !@HAVE_LCHOWN@
+_GL_FUNCDECL_SYS (lchown, int, (char const *file, uid_t owner, gid_t group)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (lchown, int, (char const *file, uid_t owner, gid_t group));
+# endif
+_GL_CXXALIASWARN (lchown);
+#elif defined GNULIB_POSIXCHECK
+# undef lchown
+# if HAVE_RAW_DECL_LCHOWN
+_GL_WARN_ON_USE (lchown, "lchown is unportable to pre-POSIX.1-2001 systems - "
+ "use gnulib module lchown for portability");
+# endif
+#endif
+
+
+#if @GNULIB_LINK@
+/* Create a new hard link for an existing file.
+ Return 0 if successful, otherwise -1 and errno set.
+ See POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html>. */
+# if @REPLACE_LINK@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define link rpl_link
+# endif
+_GL_FUNCDECL_RPL (link, int, (const char *path1, const char *path2)
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (link, int, (const char *path1, const char *path2));
+# else
+# if !@HAVE_LINK@
+_GL_FUNCDECL_SYS (link, int, (const char *path1, const char *path2)
+ _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (link, int, (const char *path1, const char *path2));
+# endif
+_GL_CXXALIASWARN (link);
+#elif defined GNULIB_POSIXCHECK
+# undef link
+# if HAVE_RAW_DECL_LINK
+_GL_WARN_ON_USE (link, "link is unportable - "
+ "use gnulib module link for portability");
+# endif
+#endif
+
+
+#if @GNULIB_LINKAT@
+/* Create a new hard link for an existing file, relative to two
+ directories. FLAG controls whether symlinks are followed.
+ Return 0 if successful, otherwise -1 and errno set. */
+# if @REPLACE_LINKAT@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef linkat
+# define linkat rpl_linkat
+# endif
+_GL_FUNCDECL_RPL (linkat, int,
+ (int fd1, const char *path1, int fd2, const char *path2,
+ int flag)
+ _GL_ARG_NONNULL ((2, 4)));
+_GL_CXXALIAS_RPL (linkat, int,
+ (int fd1, const char *path1, int fd2, const char *path2,
+ int flag));
+# else
+# if !@HAVE_LINKAT@
+_GL_FUNCDECL_SYS (linkat, int,
+ (int fd1, const char *path1, int fd2, const char *path2,
+ int flag)
+ _GL_ARG_NONNULL ((2, 4)));
+# endif
+_GL_CXXALIAS_SYS (linkat, int,
+ (int fd1, const char *path1, int fd2, const char *path2,
+ int flag));
+# endif
+_GL_CXXALIASWARN (linkat);
+#elif defined GNULIB_POSIXCHECK
+# undef linkat
+# if HAVE_RAW_DECL_LINKAT
+_GL_WARN_ON_USE (linkat, "linkat is unportable - "
+ "use gnulib module linkat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_LSEEK@
+/* Set the offset of FD relative to SEEK_SET, SEEK_CUR, or SEEK_END.
+ Return the new offset if successful, otherwise -1 and errno set.
+ See the POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html>. */
+# if @REPLACE_LSEEK@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define lseek rpl_lseek
+# endif
+_GL_FUNCDECL_RPL (lseek, off_t, (int fd, off_t offset, int whence));
+_GL_CXXALIAS_RPL (lseek, off_t, (int fd, off_t offset, int whence));
+# else
+_GL_CXXALIAS_SYS (lseek, off_t, (int fd, off_t offset, int whence));
+# endif
+_GL_CXXALIASWARN (lseek);
+#elif defined GNULIB_POSIXCHECK
+# undef lseek
+# if HAVE_RAW_DECL_LSEEK
+_GL_WARN_ON_USE (lseek, "lseek does not fail with ESPIPE on pipes on some "
+ "systems - use gnulib module lseek for portability");
+# endif
+#endif
+
+
+#if @GNULIB_PIPE@
+/* Create a pipe, defaulting to O_BINARY mode.
+ Store the read-end as fd[0] and the write-end as fd[1].
+ Return 0 upon success, or -1 with errno set upon failure. */
+# if !@HAVE_PIPE@
+_GL_FUNCDECL_SYS (pipe, int, (int fd[2]) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (pipe, int, (int fd[2]));
+_GL_CXXALIASWARN (pipe);
+#elif defined GNULIB_POSIXCHECK
+# undef pipe
+# if HAVE_RAW_DECL_PIPE
+_GL_WARN_ON_USE (pipe, "pipe is unportable - "
+ "use gnulib module pipe-posix for portability");
+# endif
+#endif
+
+
+#if @GNULIB_PIPE2@
+/* Create a pipe, applying the given flags when opening the read-end of the
+ pipe and the write-end of the pipe.
+ The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
+ and O_TEXT, O_BINARY (defined in "binary-io.h").
+ Store the read-end as fd[0] and the write-end as fd[1].
+ Return 0 upon success, or -1 with errno set upon failure.
+ See also the Linux man page at
+ <https://www.kernel.org/doc/man-pages/online/pages/man2/pipe2.2.html>. */
+# if @HAVE_PIPE2@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define pipe2 rpl_pipe2
+# endif
+_GL_FUNCDECL_RPL (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (pipe2, int, (int fd[2], int flags));
+# else
+_GL_FUNCDECL_SYS (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_SYS (pipe2, int, (int fd[2], int flags));
+# endif
+_GL_CXXALIASWARN (pipe2);
+#elif defined GNULIB_POSIXCHECK
+# undef pipe2
+# if HAVE_RAW_DECL_PIPE2
+_GL_WARN_ON_USE (pipe2, "pipe2 is unportable - "
+ "use gnulib module pipe2 for portability");
+# endif
+#endif
+
+
+#if @GNULIB_PREAD@
+/* Read at most BUFSIZE bytes from FD into BUF, starting at OFFSET.
+ Return the number of bytes placed into BUF if successful, otherwise
+ set errno and return -1. 0 indicates EOF.
+ See the POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html>. */
+# if @REPLACE_PREAD@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef pread
+# define pread rpl_pread
+# endif
+_GL_FUNCDECL_RPL (pread, ssize_t,
+ (int fd, void *buf, size_t bufsize, off_t offset)
+ _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (pread, ssize_t,
+ (int fd, void *buf, size_t bufsize, off_t offset));
+# else
+# if !@HAVE_PREAD@
+_GL_FUNCDECL_SYS (pread, ssize_t,
+ (int fd, void *buf, size_t bufsize, off_t offset)
+ _GL_ARG_NONNULL ((2)));
+# endif
+_GL_CXXALIAS_SYS (pread, ssize_t,
+ (int fd, void *buf, size_t bufsize, off_t offset));
+# endif
+_GL_CXXALIASWARN (pread);
+#elif defined GNULIB_POSIXCHECK
+# undef pread
+# if HAVE_RAW_DECL_PREAD
+_GL_WARN_ON_USE (pread, "pread is unportable - "
+ "use gnulib module pread for portability");
+# endif
+#endif
+
+
+#if @GNULIB_PWRITE@
+/* Write at most BUFSIZE bytes from BUF into FD, starting at OFFSET.
+ Return the number of bytes written if successful, otherwise
+ set errno and return -1. 0 indicates nothing written. See the
+ POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html>. */
+# if @REPLACE_PWRITE@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef pwrite
+# define pwrite rpl_pwrite
+# endif
+_GL_FUNCDECL_RPL (pwrite, ssize_t,
+ (int fd, const void *buf, size_t bufsize, off_t offset)
+ _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (pwrite, ssize_t,
+ (int fd, const void *buf, size_t bufsize, off_t offset));
+# else
+# if !@HAVE_PWRITE@
+_GL_FUNCDECL_SYS (pwrite, ssize_t,
+ (int fd, const void *buf, size_t bufsize, off_t offset)
+ _GL_ARG_NONNULL ((2)));
+# endif
+_GL_CXXALIAS_SYS (pwrite, ssize_t,
+ (int fd, const void *buf, size_t bufsize, off_t offset));
+# endif
+_GL_CXXALIASWARN (pwrite);
+#elif defined GNULIB_POSIXCHECK
+# undef pwrite
+# if HAVE_RAW_DECL_PWRITE
+_GL_WARN_ON_USE (pwrite, "pwrite is unportable - "
+ "use gnulib module pwrite for portability");
+# endif
+#endif
+
+
+#if @GNULIB_READ@
+/* Read up to COUNT bytes from file descriptor FD into the buffer starting
+ at BUF. See the POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html>. */
+# if @REPLACE_READ@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef read
+# define read rpl_read
+# endif
+_GL_FUNCDECL_RPL (read, ssize_t, (int fd, void *buf, size_t count)
+ _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (read, ssize_t, (int fd, void *buf, size_t count));
+# else
+/* Need to cast, because on mingw, the third parameter is
+ unsigned int count
+ and the return type is 'int'. */
+_GL_CXXALIAS_SYS_CAST (read, ssize_t, (int fd, void *buf, size_t count));
+# endif
+_GL_CXXALIASWARN (read);
+#endif
+
+
+#if @GNULIB_READLINK@
+/* Read the contents of the symbolic link FILE and place the first BUFSIZE
+ bytes of it into BUF. Return the number of bytes placed into BUF if
+ successful, otherwise -1 and errno set.
+ See the POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html>. */
+# if @REPLACE_READLINK@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define readlink rpl_readlink
+# endif
+_GL_FUNCDECL_RPL (readlink, ssize_t,
+ (const char *file, char *buf, size_t bufsize)
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (readlink, ssize_t,
+ (const char *file, char *buf, size_t bufsize));
+# else
+# if !@HAVE_READLINK@
+_GL_FUNCDECL_SYS (readlink, ssize_t,
+ (const char *file, char *buf, size_t bufsize)
+ _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (readlink, ssize_t,
+ (const char *file, char *buf, size_t bufsize));
+# endif
+_GL_CXXALIASWARN (readlink);
+#elif defined GNULIB_POSIXCHECK
+# undef readlink
+# if HAVE_RAW_DECL_READLINK
+_GL_WARN_ON_USE (readlink, "readlink is unportable - "
+ "use gnulib module readlink for portability");
+# endif
+#endif
+
+
+#if @GNULIB_READLINKAT@
+# if @REPLACE_READLINKAT@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define readlinkat rpl_readlinkat
+# endif
+_GL_FUNCDECL_RPL (readlinkat, ssize_t,
+ (int fd, char const *file, char *buf, size_t len)
+ _GL_ARG_NONNULL ((2, 3)));
+_GL_CXXALIAS_RPL (readlinkat, ssize_t,
+ (int fd, char const *file, char *buf, size_t len));
+# else
+# if !@HAVE_READLINKAT@
+_GL_FUNCDECL_SYS (readlinkat, ssize_t,
+ (int fd, char const *file, char *buf, size_t len)
+ _GL_ARG_NONNULL ((2, 3)));
+# endif
+_GL_CXXALIAS_SYS (readlinkat, ssize_t,
+ (int fd, char const *file, char *buf, size_t len));
+# endif
+_GL_CXXALIASWARN (readlinkat);
+#elif defined GNULIB_POSIXCHECK
+# undef readlinkat
+# if HAVE_RAW_DECL_READLINKAT
+_GL_WARN_ON_USE (readlinkat, "readlinkat is not portable - "
+ "use gnulib module readlinkat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_RMDIR@
+/* Remove the directory DIR. */
+# if @REPLACE_RMDIR@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define rmdir rpl_rmdir
+# endif
+_GL_FUNCDECL_RPL (rmdir, int, (char const *name) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (rmdir, int, (char const *name));
+# else
+_GL_CXXALIAS_SYS (rmdir, int, (char const *name));
+# endif
+_GL_CXXALIASWARN (rmdir);
+#elif defined GNULIB_POSIXCHECK
+# undef rmdir
+# if HAVE_RAW_DECL_RMDIR
+_GL_WARN_ON_USE (rmdir, "rmdir is unportable - "
+ "use gnulib module rmdir for portability");
+# endif
+#endif
+
+
+#if @GNULIB_SETHOSTNAME@
+/* Set the host name of the machine.
+ The host name may or may not be fully qualified.
+
+ Put LEN bytes of NAME into the host name.
+ Return 0 if successful, otherwise, set errno and return -1.
+
+ Platforms with no ability to set the hostname return -1 and set
+ errno = ENOSYS. */
+# if !@HAVE_SETHOSTNAME@ || !@HAVE_DECL_SETHOSTNAME@
+_GL_FUNCDECL_SYS (sethostname, int, (const char *name, size_t len)
+ _GL_ARG_NONNULL ((1)));
+# endif
+/* Need to cast, because on Solaris 11 2011-10, Mac OS X 10.5, IRIX 6.5
+ and FreeBSD 6.4 the second parameter is int. On Solaris 11
+ 2011-10, the first parameter is not const. */
+_GL_CXXALIAS_SYS_CAST (sethostname, int, (const char *name, size_t len));
+_GL_CXXALIASWARN (sethostname);
+#elif defined GNULIB_POSIXCHECK
+# undef sethostname
+# if HAVE_RAW_DECL_SETHOSTNAME
+_GL_WARN_ON_USE (sethostname, "sethostname is unportable - "
+ "use gnulib module sethostname for portability");
+# endif
+#endif
+
+
+#if @GNULIB_SLEEP@
+/* Pause the execution of the current thread for N seconds.
+ Returns the number of seconds left to sleep.
+ See the POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/sleep.html>. */
+# if @REPLACE_SLEEP@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef sleep
+# define sleep rpl_sleep
+# endif
+_GL_FUNCDECL_RPL (sleep, unsigned int, (unsigned int n));
+_GL_CXXALIAS_RPL (sleep, unsigned int, (unsigned int n));
+# else
+# if !@HAVE_SLEEP@
+_GL_FUNCDECL_SYS (sleep, unsigned int, (unsigned int n));
+# endif
+_GL_CXXALIAS_SYS (sleep, unsigned int, (unsigned int n));
+# endif
+_GL_CXXALIASWARN (sleep);
+#elif defined GNULIB_POSIXCHECK
+# undef sleep
+# if HAVE_RAW_DECL_SLEEP
+_GL_WARN_ON_USE (sleep, "sleep is unportable - "
+ "use gnulib module sleep for portability");
+# endif
+#endif
+
+
+#if @GNULIB_SYMLINK@
+# if @REPLACE_SYMLINK@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef symlink
+# define symlink rpl_symlink
+# endif
+_GL_FUNCDECL_RPL (symlink, int, (char const *contents, char const *file)
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (symlink, int, (char const *contents, char const *file));
+# else
+# if !@HAVE_SYMLINK@
+_GL_FUNCDECL_SYS (symlink, int, (char const *contents, char const *file)
+ _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (symlink, int, (char const *contents, char const *file));
+# endif
+_GL_CXXALIASWARN (symlink);
+#elif defined GNULIB_POSIXCHECK
+# undef symlink
+# if HAVE_RAW_DECL_SYMLINK
+_GL_WARN_ON_USE (symlink, "symlink is not portable - "
+ "use gnulib module symlink for portability");
+# endif
+#endif
+
+
+#if @GNULIB_SYMLINKAT@
+# if @REPLACE_SYMLINKAT@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef symlinkat
+# define symlinkat rpl_symlinkat
+# endif
+_GL_FUNCDECL_RPL (symlinkat, int,
+ (char const *contents, int fd, char const *file)
+ _GL_ARG_NONNULL ((1, 3)));
+_GL_CXXALIAS_RPL (symlinkat, int,
+ (char const *contents, int fd, char const *file));
+# else
+# if !@HAVE_SYMLINKAT@
+_GL_FUNCDECL_SYS (symlinkat, int,
+ (char const *contents, int fd, char const *file)
+ _GL_ARG_NONNULL ((1, 3)));
+# endif
+_GL_CXXALIAS_SYS (symlinkat, int,
+ (char const *contents, int fd, char const *file));
+# endif
+_GL_CXXALIASWARN (symlinkat);
+#elif defined GNULIB_POSIXCHECK
+# undef symlinkat
+# if HAVE_RAW_DECL_SYMLINKAT
+_GL_WARN_ON_USE (symlinkat, "symlinkat is not portable - "
+ "use gnulib module symlinkat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_TRUNCATE@
+/* Change the size of the file designated by FILENAME to become equal to LENGTH.
+ Return 0 if successful, otherwise -1 and errno set.
+ See the POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html>. */
+# if @REPLACE_TRUNCATE@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef truncate
+# define truncate rpl_truncate
+# endif
+_GL_FUNCDECL_RPL (truncate, int, (const char *filename, off_t length)
+ _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (truncate, int, (const char *filename, off_t length));
+# else
+# if !@HAVE_DECL_TRUNCATE@
+_GL_FUNCDECL_SYS (truncate, int, (const char *filename, off_t length)
+ _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (truncate, int, (const char *filename, off_t length));
+# endif
+_GL_CXXALIASWARN (truncate);
+#elif defined GNULIB_POSIXCHECK
+# undef truncate
+# if HAVE_RAW_DECL_TRUNCATE
+_GL_WARN_ON_USE (truncate, "truncate is unportable - "
+ "use gnulib module truncate for portability");
+# endif
+#endif
+
+
+#if @GNULIB_TTYNAME_R@
+/* Store at most BUFLEN characters of the pathname of the terminal FD is
+ open on in BUF. Return 0 on success, otherwise an error number. */
+# if @REPLACE_TTYNAME_R@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef ttyname_r
+# define ttyname_r rpl_ttyname_r
+# endif
+_GL_FUNCDECL_RPL (ttyname_r, int,
+ (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (ttyname_r, int,
+ (int fd, char *buf, size_t buflen));
+# else
+# if !@HAVE_DECL_TTYNAME_R@
+_GL_FUNCDECL_SYS (ttyname_r, int,
+ (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2)));
+# endif
+_GL_CXXALIAS_SYS (ttyname_r, int,
+ (int fd, char *buf, size_t buflen));
+# endif
+_GL_CXXALIASWARN (ttyname_r);
+#elif defined GNULIB_POSIXCHECK
+# undef ttyname_r
+# if HAVE_RAW_DECL_TTYNAME_R
+_GL_WARN_ON_USE (ttyname_r, "ttyname_r is not portable - "
+ "use gnulib module ttyname_r for portability");
+# endif
+#endif
+
+
+#if @GNULIB_UNLINK@
+# if @REPLACE_UNLINK@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef unlink
+# define unlink rpl_unlink
+# endif
+_GL_FUNCDECL_RPL (unlink, int, (char const *file) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (unlink, int, (char const *file));
+# else
+_GL_CXXALIAS_SYS (unlink, int, (char const *file));
+# endif
+_GL_CXXALIASWARN (unlink);
+#elif defined GNULIB_POSIXCHECK
+# undef unlink
+# if HAVE_RAW_DECL_UNLINK
+_GL_WARN_ON_USE (unlink, "unlink is not portable - "
+ "use gnulib module unlink for portability");
+# endif
+#endif
+
+
+#if @GNULIB_UNLINKAT@
+# if @REPLACE_UNLINKAT@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef unlinkat
+# define unlinkat rpl_unlinkat
+# endif
+_GL_FUNCDECL_RPL (unlinkat, int, (int fd, char const *file, int flag)
+ _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (unlinkat, int, (int fd, char const *file, int flag));
+# else
+# if !@HAVE_UNLINKAT@
+_GL_FUNCDECL_SYS (unlinkat, int, (int fd, char const *file, int flag)
+ _GL_ARG_NONNULL ((2)));
+# endif
+_GL_CXXALIAS_SYS (unlinkat, int, (int fd, char const *file, int flag));
+# endif
+_GL_CXXALIASWARN (unlinkat);
+#elif defined GNULIB_POSIXCHECK
+# undef unlinkat
+# if HAVE_RAW_DECL_UNLINKAT
+_GL_WARN_ON_USE (unlinkat, "unlinkat is not portable - "
+ "use gnulib module openat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_USLEEP@
+/* Pause the execution of the current thread for N microseconds.
+ Returns 0 on completion, or -1 on range error.
+ See the POSIX:2001 specification
+ <http://www.opengroup.org/susv3xsh/usleep.html>. */
+# if @REPLACE_USLEEP@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef usleep
+# define usleep rpl_usleep
+# endif
+_GL_FUNCDECL_RPL (usleep, int, (useconds_t n));
+_GL_CXXALIAS_RPL (usleep, int, (useconds_t n));
+# else
+# if !@HAVE_USLEEP@
+_GL_FUNCDECL_SYS (usleep, int, (useconds_t n));
+# endif
+_GL_CXXALIAS_SYS (usleep, int, (useconds_t n));
+# endif
+_GL_CXXALIASWARN (usleep);
+#elif defined GNULIB_POSIXCHECK
+# undef usleep
+# if HAVE_RAW_DECL_USLEEP
+_GL_WARN_ON_USE (usleep, "usleep is unportable - "
+ "use gnulib module usleep for portability");
+# endif
+#endif
+
+
+#if @GNULIB_WRITE@
+/* Write up to COUNT bytes starting at BUF to file descriptor FD.
+ See the POSIX:2008 specification
+ <http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html>. */
+# if @REPLACE_WRITE@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef write
+# define write rpl_write
+# endif
+_GL_FUNCDECL_RPL (write, ssize_t, (int fd, const void *buf, size_t count)
+ _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (write, ssize_t, (int fd, const void *buf, size_t count));
+# else
+/* Need to cast, because on mingw, the third parameter is
+ unsigned int count
+ and the return type is 'int'. */
+_GL_CXXALIAS_SYS_CAST (write, ssize_t, (int fd, const void *buf, size_t count));
+# endif
+_GL_CXXALIASWARN (write);
+#endif
+
+_GL_INLINE_HEADER_END
+
+#endif /* _@GUARD_PREFIX@_UNISTD_H */
+#endif /* _GL_INCLUDING_UNISTD_H */
+#endif /* _@GUARD_PREFIX@_UNISTD_H */
diff --git a/gnulib/verify.h b/gnulib/verify.h
new file mode 100644
index 0000000..9b8e1ed
--- /dev/null
+++ b/gnulib/verify.h
@@ -0,0 +1,287 @@
+/* Compile-time assert-like macros.
+
+ Copyright (C) 2005-2006, 2009-2019 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */
+
+#ifndef _GL_VERIFY_H
+#define _GL_VERIFY_H
+
+
+/* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert (R, DIAGNOSTIC)
+ works as per C11. This is supported by GCC 4.6.0 and later, in C
+ mode.
+
+ Define _GL_HAVE__STATIC_ASSERT1 to 1 if _Static_assert (R) works as
+ per C2X, and define _GL_HAVE_STATIC_ASSERT1 if static_assert (R)
+ works as per C++17. This is supported by GCC 9.1 and later.
+
+ Support compilers claiming conformance to the relevant standard,
+ and also support GCC when not pedantic. If we were willing to slow
+ 'configure' down we could also use it with other compilers, but
+ since this affects only the quality of diagnostics, why bother? */
+#ifndef __cplusplus
+# if (201112L <= __STDC_VERSION__ \
+ || (!defined __STRICT_ANSI__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)))
+# define _GL_HAVE__STATIC_ASSERT 1
+# endif
+# if (202000L <= __STDC_VERSION__ \
+ || (!defined __STRICT_ANSI__ && 9 <= __GNUC__))
+# define _GL_HAVE__STATIC_ASSERT1 1
+# endif
+#else
+# if 201703L <= __cplusplus || 9 <= __GNUC__
+# define _GL_HAVE_STATIC_ASSERT1 1
+# endif
+#endif
+
+/* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other
+ system headers, defines a conflicting _Static_assert that is no
+ better than ours; override it. */
+#ifndef _GL_HAVE__STATIC_ASSERT
+# include <stddef.h>
+# undef _Static_assert
+#endif
+
+/* Each of these macros verifies that its argument R is nonzero. To
+ be portable, R should be an integer constant expression. Unlike
+ assert (R), there is no run-time overhead.
+
+ If _Static_assert works, verify (R) uses it directly. Similarly,
+ _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct
+ that is an operand of sizeof.
+
+ The code below uses several ideas for C++ compilers, and for C
+ compilers that do not support _Static_assert:
+
+ * The first step is ((R) ? 1 : -1). Given an expression R, of
+ integral or boolean or floating-point type, this yields an
+ expression of integral type, whose value is later verified to be
+ constant and nonnegative.
+
+ * Next this expression W is wrapped in a type
+ struct _gl_verify_type {
+ unsigned int _gl_verify_error_if_negative: W;
+ }.
+ If W is negative, this yields a compile-time error. No compiler can
+ deal with a bit-field of negative size.
+
+ One might think that an array size check would have the same
+ effect, that is, that the type struct { unsigned int dummy[W]; }
+ would work as well. However, inside a function, some compilers
+ (such as C++ compilers and GNU C) allow local parameters and
+ variables inside array size expressions. With these compilers,
+ an array size check would not properly diagnose this misuse of
+ the verify macro:
+
+ void function (int n) { verify (n < 0); }
+
+ * For the verify macro, the struct _gl_verify_type will need to
+ somehow be embedded into a declaration. To be portable, this
+ declaration must declare an object, a constant, a function, or a
+ typedef name. If the declared entity uses the type directly,
+ such as in
+
+ struct dummy {...};
+ typedef struct {...} dummy;
+ extern struct {...} *dummy;
+ extern void dummy (struct {...} *);
+ extern struct {...} *dummy (void);
+
+ two uses of the verify macro would yield colliding declarations
+ if the entity names are not disambiguated. A workaround is to
+ attach the current line number to the entity name:
+
+ #define _GL_CONCAT0(x, y) x##y
+ #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
+ extern struct {...} * _GL_CONCAT (dummy, __LINE__);
+
+ But this has the problem that two invocations of verify from
+ within the same macro would collide, since the __LINE__ value
+ would be the same for both invocations. (The GCC __COUNTER__
+ macro solves this problem, but is not portable.)
+
+ A solution is to use the sizeof operator. It yields a number,
+ getting rid of the identity of the type. Declarations like
+
+ extern int dummy [sizeof (struct {...})];
+ extern void dummy (int [sizeof (struct {...})]);
+ extern int (*dummy (void)) [sizeof (struct {...})];
+
+ can be repeated.
+
+ * Should the implementation use a named struct or an unnamed struct?
+ Which of the following alternatives can be used?
+
+ extern int dummy [sizeof (struct {...})];
+ extern int dummy [sizeof (struct _gl_verify_type {...})];
+ extern void dummy (int [sizeof (struct {...})]);
+ extern void dummy (int [sizeof (struct _gl_verify_type {...})]);
+ extern int (*dummy (void)) [sizeof (struct {...})];
+ extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})];
+
+ In the second and sixth case, the struct type is exported to the
+ outer scope; two such declarations therefore collide. GCC warns
+ about the first, third, and fourth cases. So the only remaining
+ possibility is the fifth case:
+
+ extern int (*dummy (void)) [sizeof (struct {...})];
+
+ * GCC warns about duplicate declarations of the dummy function if
+ -Wredundant-decls is used. GCC 4.3 and later have a builtin
+ __COUNTER__ macro that can let us generate unique identifiers for
+ each dummy function, to suppress this warning.
+
+ * This implementation exploits the fact that older versions of GCC,
+ which do not support _Static_assert, also do not warn about the
+ last declaration mentioned above.
+
+ * GCC warns if -Wnested-externs is enabled and 'verify' is used
+ within a function body; but inside a function, you can always
+ arrange to use verify_expr instead.
+
+ * In C++, any struct definition inside sizeof is invalid.
+ Use a template type to work around the problem. */
+
+/* Concatenate two preprocessor tokens. */
+#define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
+#define _GL_CONCAT0(x, y) x##y
+
+/* _GL_COUNTER is an integer, preferably one that changes each time we
+ use it. Use __COUNTER__ if it works, falling back on __LINE__
+ otherwise. __LINE__ isn't perfect, but it's better than a
+ constant. */
+#if defined __COUNTER__ && __COUNTER__ != __COUNTER__
+# define _GL_COUNTER __COUNTER__
+#else
+# define _GL_COUNTER __LINE__
+#endif
+
+/* Generate a symbol with the given prefix, making it unique if
+ possible. */
+#define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)
+
+/* Verify requirement R at compile-time, as an integer constant expression
+ that returns 1. If R is false, fail at compile-time. */
+
+#define _GL_VERIFY_TRUE(R) (!!sizeof (_GL_VERIFY_TYPE (R)))
+
+#ifdef __cplusplus
+# if !GNULIB_defined_struct__gl_verify_type
+template <int w>
+ struct _gl_verify_type {
+ unsigned int _gl_verify_error_if_negative: w;
+ };
+# define GNULIB_defined_struct__gl_verify_type 1
+# endif
+# define _GL_VERIFY_TYPE(R) _gl_verify_type<(R) ? 1 : -1>
+#elif defined _GL_HAVE__STATIC_ASSERT1
+# define _GL_VERIFY_TYPE(R) \
+ struct { \
+ _Static_assert (R); \
+ int _gl_dummy; \
+ }
+#else
+# define _GL_VERIFY_TYPE(R) \
+ struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; }
+#endif
+
+/* Verify requirement R at compile-time, as a declaration without a
+ trailing ';'. If R is false, fail at compile-time.
+
+ This macro requires three or more arguments but uses at most the first
+ two, so that the _Static_assert macro optionally defined below supports
+ both the C11 two-argument syntax and the C2X one-argument syntax.
+
+ Unfortunately, unlike C11, this implementation must appear as an
+ ordinary declaration, and cannot appear inside struct { ... }. */
+
+#if defined _GL_HAVE__STATIC_ASSERT
+# define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC)
+#else
+# define _GL_VERIFY(R, DIAGNOSTIC, ...) \
+ extern int (*_GL_GENSYM (_gl_verify_function) (void)) \
+ [_GL_VERIFY_TRUE (R)]
+#endif
+
+/* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */
+#ifdef _GL_STATIC_ASSERT_H
+# if !defined _GL_HAVE__STATIC_ASSERT1 && !defined _Static_assert
+# define _Static_assert(...) \
+ _GL_VERIFY (__VA_ARGS__, "static assertion failed", -)
+# endif
+# if !defined _GL_HAVE_STATIC_ASSERT1 && !defined static_assert
+# define static_assert _Static_assert /* C11 requires this #define. */
+# endif
+#endif
+
+/* @assert.h omit start@ */
+
+/* Each of these macros verifies that its argument R is nonzero. To
+ be portable, R should be an integer constant expression. Unlike
+ assert (R), there is no run-time overhead.
+
+ There are two macros, since no single macro can be used in all
+ contexts in C. verify_expr (R, E) is for scalar contexts, including
+ integer constant expression contexts. verify (R) is for declaration
+ contexts, e.g., the top level. */
+
+/* Verify requirement R at compile-time. Return the value of the
+ expression E. */
+
+#define verify_expr(R, E) (_GL_VERIFY_TRUE (R) ? (E) : (E))
+
+/* Verify requirement R at compile-time, as a declaration without a
+ trailing ';'. verify (R) acts like static_assert (R) except that
+ it is portable to C11/C++14 and earlier, and its name is shorter
+ and may be more convenient. */
+
+#ifdef _GL_HAVE__STATIC_ASSERT1
+# define verify(R) _Static_assert (R)
+#else
+# define verify(R) _GL_VERIFY (R, "verify (...)", -)
+#endif
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+/* Assume that R always holds. Behavior is undefined if R is false,
+ fails to evaluate, or has side effects. Although assuming R can
+ help a compiler generate better code or diagnostics, performance
+ can suffer if R uses hard-to-optimize features such as function
+ calls not inlined by the compiler. */
+
+#if (__has_builtin (__builtin_unreachable) \
+ || 4 < __GNUC__ + (5 <= __GNUC_MINOR__))
+# define assume(R) ((R) ? (void) 0 : __builtin_unreachable ())
+#elif 1200 <= _MSC_VER
+# define assume(R) __assume (R)
+#elif ((defined GCC_LINT || defined lint) \
+ && (__has_builtin (__builtin_trap) \
+ || 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__))))
+ /* Doing it this way helps various packages when configured with
+ --enable-gcc-warnings, which compiles with -Dlint. It's nicer
+ when 'assume' silences warnings even with older GCCs. */
+# define assume(R) ((R) ? (void) 0 : __builtin_trap ())
+#else
+ /* Some tools grok NOTREACHED, e.g., Oracle Studio 12.6. */
+# define assume(R) ((R) ? (void) 0 : /*NOTREACHED*/ (void) 0)
+#endif
+
+/* @assert.h omit end@ */
+
+#endif
diff --git a/gnulib/warn-on-use.h b/gnulib/warn-on-use.h
new file mode 100644
index 0000000..7d11a15
--- /dev/null
+++ b/gnulib/warn-on-use.h
@@ -0,0 +1,131 @@
+/* A C macro for emitting warnings if a function is used.
+ Copyright (C) 2010-2019 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* _GL_WARN_ON_USE (function, "literal string") issues a declaration
+ for FUNCTION which will then trigger a compiler warning containing
+ the text of "literal string" anywhere that function is called, if
+ supported by the compiler. If the compiler does not support this
+ feature, the macro expands to an unused extern declaration.
+
+ _GL_WARN_ON_USE_ATTRIBUTE ("literal string") expands to the
+ attribute used in _GL_WARN_ON_USE. If the compiler does not support
+ this feature, it expands to empty.
+
+ These macros are useful for marking a function as a potential
+ portability trap, with the intent that "literal string" include
+ instructions on the replacement function that should be used
+ instead.
+ _GL_WARN_ON_USE is for functions with 'extern' linkage.
+ _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline'
+ linkage.
+
+ However, one of the reasons that a function is a portability trap is
+ if it has the wrong signature. Declaring FUNCTION with a different
+ signature in C is a compilation error, so this macro must use the
+ same type as any existing declaration so that programs that avoid
+ the problematic FUNCTION do not fail to compile merely because they
+ included a header that poisoned the function. But this implies that
+ _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already
+ have a declaration. Use of this macro implies that there must not
+ be any other macro hiding the declaration of FUNCTION; but
+ undefining FUNCTION first is part of the poisoning process anyway
+ (although for symbols that are provided only via a macro, the result
+ is a compilation error rather than a warning containing
+ "literal string"). Also note that in C++, it is only safe to use if
+ FUNCTION has no overloads.
+
+ For an example, it is possible to poison 'getline' by:
+ - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],
+ [getline]) in configure.ac, which potentially defines
+ HAVE_RAW_DECL_GETLINE
+ - adding this code to a header that wraps the system <stdio.h>:
+ #undef getline
+ #if HAVE_RAW_DECL_GETLINE
+ _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but"
+ "not universally present; use the gnulib module getline");
+ #endif
+
+ It is not possible to directly poison global variables. But it is
+ possible to write a wrapper accessor function, and poison that
+ (less common usage, like &environ, will cause a compilation error
+ rather than issue the nice warning, but the end result of informing
+ the developer about their portability problem is still achieved):
+ #if HAVE_RAW_DECL_ENVIRON
+ static char ***
+ rpl_environ (void) { return &environ; }
+ _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared");
+ # undef environ
+ # define environ (*rpl_environ ())
+ #endif
+ or better (avoiding contradictory use of 'static' and 'extern'):
+ #if HAVE_RAW_DECL_ENVIRON
+ static char ***
+ _GL_WARN_ON_USE_ATTRIBUTE ("environ is not always properly declared")
+ rpl_environ (void) { return &environ; }
+ # undef environ
+ # define environ (*rpl_environ ())
+ #endif
+ */
+#ifndef _GL_WARN_ON_USE
+
+# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
+/* A compiler attribute is available in gcc versions 4.3.0 and later. */
+# define _GL_WARN_ON_USE(function, message) \
+extern __typeof__ (function) function __attribute__ ((__warning__ (message)))
+# define _GL_WARN_ON_USE_ATTRIBUTE(message) \
+ __attribute__ ((__warning__ (message)))
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+/* Verify the existence of the function. */
+# define _GL_WARN_ON_USE(function, message) \
+extern __typeof__ (function) function
+# define _GL_WARN_ON_USE_ATTRIBUTE(message)
+# else /* Unsupported. */
+# define _GL_WARN_ON_USE(function, message) \
+_GL_WARN_EXTERN_C int _gl_warn_on_use
+# define _GL_WARN_ON_USE_ATTRIBUTE(message)
+# endif
+#endif
+
+/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string")
+ is like _GL_WARN_ON_USE (function, "string"), except that the function is
+ declared with the given prototype, consisting of return type, parameters,
+ and attributes.
+ This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does
+ not work in this case. */
+#ifndef _GL_WARN_ON_USE_CXX
+# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
+# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
+extern rettype function parameters_and_attributes \
+ __attribute__ ((__warning__ (msg)))
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+/* Verify the existence of the function. */
+# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
+extern rettype function parameters_and_attributes
+# else /* Unsupported. */
+# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
+_GL_WARN_EXTERN_C int _gl_warn_on_use
+# endif
+#endif
+
+/* _GL_WARN_EXTERN_C declaration;
+ performs the declaration with C linkage. */
+#ifndef _GL_WARN_EXTERN_C
+# if defined __cplusplus
+# define _GL_WARN_EXTERN_C extern "C"
+# else
+# define _GL_WARN_EXTERN_C extern
+# endif
+#endif
diff --git a/gnulib/xalloc-oversized.h b/gnulib/xalloc-oversized.h
new file mode 100644
index 0000000..e3068c8
--- /dev/null
+++ b/gnulib/xalloc-oversized.h
@@ -0,0 +1,60 @@
+/* xalloc-oversized.h -- memory allocation size checking
+
+ Copyright (C) 1990-2000, 2003-2004, 2006-2019 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef XALLOC_OVERSIZED_H_
+#define XALLOC_OVERSIZED_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* True if N * S would overflow in a size_t calculation,
+ or would generate a value larger than PTRDIFF_MAX.
+ This expands to a constant expression if N and S are both constants.
+ By gnulib convention, SIZE_MAX represents overflow in size
+ calculations, so the conservative size_t-based dividend to use here
+ is SIZE_MAX - 1. */
+#define __xalloc_oversized(n, s) \
+ ((size_t) (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX - 1) / (s) < (n))
+
+#if PTRDIFF_MAX < SIZE_MAX
+typedef ptrdiff_t __xalloc_count_type;
+#else
+typedef size_t __xalloc_count_type;
+#endif
+
+/* Return 1 if an array of N objects, each of size S, cannot exist
+ reliably due to size or ptrdiff_t arithmetic overflow. S must be
+ positive and N must be nonnegative. This is a macro, not a
+ function, so that it works correctly even when SIZE_MAX < N. */
+
+#if 7 <= __GNUC__
+# define xalloc_oversized(n, s) \
+ __builtin_mul_overflow_p (n, s, (__xalloc_count_type) 1)
+#elif 5 <= __GNUC__ && !defined __ICC && !__STRICT_ANSI__
+# define xalloc_oversized(n, s) \
+ (__builtin_constant_p (n) && __builtin_constant_p (s) \
+ ? __xalloc_oversized (n, s) \
+ : ({ __xalloc_count_type __xalloc_count; \
+ __builtin_mul_overflow (n, s, &__xalloc_count); }))
+
+/* Other compilers use integer division; this may be slower but is
+ more portable. */
+#else
+# define xalloc_oversized(n, s) __xalloc_oversized (n, s)
+#endif
+
+#endif /* !XALLOC_OVERSIZED_H_ */
diff --git a/liblouis.pc.in b/liblouis.pc.in
new file mode 100644
index 0000000..65881b9
--- /dev/null
+++ b/liblouis.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+tablesdir=${prefix}/share/liblouis/tables
+
+Name: liblouis
+Description: a braille translator and back-translator
+Version: @VERSION@
+Requires:
+Libs: -L${libdir} -llouis
+Cflags: -I${includedir}/liblouis
diff --git a/liblouis/Makefile.am b/liblouis/Makefile.am
new file mode 100644
index 0000000..98ee660
--- /dev/null
+++ b/liblouis/Makefile.am
@@ -0,0 +1,52 @@
+liblouisincludedir = $(includedir)/liblouis
+
+# Don't include liblouis.h in dist, this will break subdir builds
+# when dist is configured with a different ucs-option than the build,
+# i.e. ucs2 dist and ucs4 build and vice versa.
+nodist_liblouisinclude_HEADERS = \
+ liblouis.h
+
+lib_LTLIBRARIES = liblouis.la
+
+AM_CPPFLAGS = \
+ $(WARN_CFLAGS) \
+ -DTABLESDIR=\""$(datadir)"/liblouis/tables\" \
+ -I$(top_srcdir)/gnulib \
+ -I$(top_builddir)/gnulib
+
+liblouis_la_LIBADD = $(top_builddir)/gnulib/libgnu.la
+
+liblouis_la_LDFLAGS = \
+ -version-info $(LIBLOUIS_CURRENT):$(LIBLOUIS_REVISION):$(LIBLOUIS_AGE) -no-undefined \
+ $(LTLIBINTL)
+
+if HAVE_LD_OUTPUT_DEF
+liblouis_la_LDFLAGS += -Wl,--output-def,liblouis-$(DLL_VERSION).def
+defexecdir = $(bindir)
+defexec_DATA = liblouis-$(DLL_VERSION).def
+DISTCLEANFILES = $(defexec_DATA)
+endif
+
+liblouis_la_SOURCES = \
+ internal.h \
+ compileTranslationTable.c \
+ lou_translateString.c \
+ lou_backTranslateString.c \
+ commonTranslationFunctions.c \
+ metadata.c \
+ pattern.c \
+ logging.c \
+ utils.c \
+ maketable.c
+
+# Don't include liblouis.h in dist, this will break subdir builds
+# when dist is configured with a different ucs-option than the build,
+# i.e. ucs2 dist and ucs4 build and vice versa.
+nodist_liblouis_la_SOURCES = \
+ liblouis.h
+
+if HAVE_SOURCE_FORMATTER
+format-sources-local:
+ for file in $(SOURCES); do $(SOURCE_FORMATTER) -i $$file; done
+ $(SOURCE_FORMATTER) -i liblouis.h.in
+endif
diff --git a/liblouis/commonTranslationFunctions.c b/liblouis/commonTranslationFunctions.c
new file mode 100644
index 0000000..b73e286
--- /dev/null
+++ b/liblouis/commonTranslationFunctions.c
@@ -0,0 +1,93 @@
+/* liblouis Braille Translation and Back-Translation Library
+
+ Based on the Linux screenreader BRLTTY, copyright (C) 1999-2006 by The
+ BRLTTY Team
+
+ Copyright (C) 2004, 2005, 2006 ViewPlus Technologies, Inc. www.viewplus.com
+ Copyright (C) 2004, 2005, 2006 JJB Software, Inc. www.jjb-software.com
+ Copyright (C) 2016 Mike Gray, American Printing House for the Blind
+ Copyright (C) 2016 Davy Kager, Dedicon
+
+ This file is part of liblouis.
+
+ liblouis is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 2.1 of the License, or
+ (at your option) any later version.
+
+ liblouis is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+#include "internal.h"
+
+static int passVariables[NUMVAR];
+
+void EXPORT_CALL
+_lou_resetPassVariables(void) {
+ memset(passVariables, 0, sizeof(passVariables[0]) * NUMVAR);
+}
+
+int EXPORT_CALL
+_lou_handlePassVariableTest(const widechar *instructions, int *IC, int *itsTrue) {
+ switch (instructions[*IC]) {
+ case pass_eq:
+ if (passVariables[instructions[*IC + 1]] != instructions[*IC + 2]) *itsTrue = 0;
+ *IC += 3;
+ return 1;
+
+ case pass_lt:
+ if (passVariables[instructions[*IC + 1]] >= instructions[*IC + 2]) *itsTrue = 0;
+ *IC += 3;
+ return 1;
+
+ case pass_gt:
+ if (passVariables[instructions[*IC + 1]] <= instructions[*IC + 2]) *itsTrue = 0;
+ *IC += 3;
+ return 1;
+
+ case pass_lteq:
+ if (passVariables[instructions[*IC + 1]] > instructions[*IC + 2]) *itsTrue = 0;
+ *IC += 3;
+ return 1;
+
+ case pass_gteq:
+ if (passVariables[instructions[*IC + 1]] < instructions[*IC + 2]) *itsTrue = 0;
+ *IC += 3;
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+int EXPORT_CALL
+_lou_handlePassVariableAction(const widechar *instructions, int *IC) {
+ switch (instructions[*IC]) {
+ case pass_eq:
+ passVariables[instructions[*IC + 1]] = instructions[*IC + 2];
+ *IC += 3;
+ return 1;
+
+ case pass_hyphen:
+ passVariables[instructions[*IC + 1]] -= 1;
+ if (passVariables[instructions[*IC + 1]] < 0)
+ passVariables[instructions[*IC + 1]] = 0;
+ *IC += 2;
+ return 1;
+
+ case pass_plus:
+ passVariables[instructions[*IC + 1]] += 1;
+ *IC += 2;
+ return 1;
+
+ default:
+ return 0;
+ }
+}
diff --git a/liblouis/compileTranslationTable.c b/liblouis/compileTranslationTable.c
new file mode 100644
index 0000000..9c9092c
--- /dev/null
+++ b/liblouis/compileTranslationTable.c
@@ -0,0 +1,4634 @@
+/* liblouis Braille Translation and Back-Translation Library
+
+ Based on the Linux screenreader BRLTTY, copyright (C) 1999-2006 by The
+ BRLTTY Team
+
+ Copyright (C) 2004, 2005, 2006 ViewPlus Technologies, Inc. www.viewplus.com
+ Copyright (C) 2004, 2005, 2006 JJB Software, Inc. www.jjb-software.com
+ Copyright (C) 2016 Mike Gray, American Printing House for the Blind
+ Copyright (C) 2016 Davy Kager, Dedicon
+
+ This file is part of liblouis.
+
+ liblouis is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 2.1 of the License, or
+ (at your option) any later version.
+
+ liblouis is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file
+ * @brief Read and compile translation tables
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/stat.h>
+
+#include "internal.h"
+#include "config.h"
+
+#define QUOTESUB 28 /* Stand-in for double quotes in strings */
+
+/* needed to make debuggin easier */
+#ifdef DEBUG
+wchar_t wchar;
+#endif
+
+/* The following variables and functions make it possible to specify the
+ * path on which all tables for liblouis and all files for liblouisutdml,
+ * in their proper directories, will be found.
+ */
+
+static char *dataPathPtr;
+
+char *EXPORT_CALL
+lou_setDataPath(const char *path) {
+ static char dataPath[MAXSTRING];
+ dataPathPtr = NULL;
+ if (path == NULL) return NULL;
+ strcpy(dataPath, path);
+ dataPathPtr = dataPath;
+ return dataPathPtr;
+}
+
+char *EXPORT_CALL
+lou_getDataPath(void) {
+ return dataPathPtr;
+}
+
+/* End of dataPath code. */
+
+static int
+eqasc2uni(const unsigned char *a, const widechar *b, const int len) {
+ int k;
+ for (k = 0; k < len; k++)
+ if ((widechar)a[k] != b[k]) return 0;
+ return 1;
+}
+
+typedef struct CharsString {
+ widechar length;
+ widechar chars[MAXSTRING];
+} CharsString;
+
+static int errorCount;
+static int warningCount;
+
+typedef struct TranslationTableChainEntry {
+ struct TranslationTableChainEntry *next;
+ TranslationTableHeader *table;
+ int tableListLength;
+ char tableList[1];
+} TranslationTableChainEntry;
+
+static TranslationTableChainEntry *translationTableChain = NULL;
+
+typedef struct DisplayTableChainEntry {
+ struct DisplayTableChainEntry *next;
+ DisplayTableHeader *table;
+ int tableListLength;
+ char tableList[1];
+} DisplayTableChainEntry;
+
+static DisplayTableChainEntry *displayTableChain = NULL;
+
+/* predifined character classes */
+static const char *characterClassNames[] = {
+ "space",
+ "letter",
+ "digit",
+ "punctuation",
+ "uppercase",
+ "lowercase",
+ "math",
+ "sign",
+ "litdigit",
+ NULL,
+};
+
+static const char *opcodeNames[CTO_None] = {
+ "include",
+ "locale",
+ "undefined",
+ "capsletter",
+ "begcapsword",
+ "endcapsword",
+ "begcaps",
+ "endcaps",
+ "begcapsphrase",
+ "endcapsphrase",
+ "lencapsphrase",
+ "letsign",
+ "noletsignbefore",
+ "noletsign",
+ "noletsignafter",
+ "numsign",
+ "numericmodechars",
+ "midendnumericmodechars",
+ "numericnocontchars",
+ "seqdelimiter",
+ "seqbeforechars",
+ "seqafterchars",
+ "seqafterpattern",
+ "seqafterexpression",
+ "emphclass",
+ "emphletter",
+ "begemphword",
+ "endemphword",
+ "begemph",
+ "endemph",
+ "begemphphrase",
+ "endemphphrase",
+ "lenemphphrase",
+ "capsmodechars",
+ "emphmodechars",
+ "begcomp",
+ "compbegemph1",
+ "compendemph1",
+ "compbegemph2",
+ "compendemph2",
+ "compbegemph3",
+ "compendemph3",
+ "compcapsign",
+ "compbegcaps",
+ "compendcaps",
+ "endcomp",
+ "nocontractsign",
+ "multind",
+ "compdots",
+ "comp6",
+ "class",
+ "after",
+ "before",
+ "noback",
+ "nofor",
+ "empmatchbefore",
+ "empmatchafter",
+ "swapcc",
+ "swapcd",
+ "swapdd",
+ "space",
+ "digit",
+ "punctuation",
+ "math",
+ "sign",
+ "letter",
+ "uppercase",
+ "lowercase",
+ "grouping",
+ "uplow",
+ "litdigit",
+ "display",
+ "replace",
+ "context",
+ "correct",
+ "pass2",
+ "pass3",
+ "pass4",
+ "repeated",
+ "repword",
+ "capsnocont",
+ "always",
+ "exactdots",
+ "nocross",
+ "syllable",
+ "nocont",
+ "compbrl",
+ "literal",
+ "largesign",
+ "word",
+ "partword",
+ "joinnum",
+ "joinword",
+ "lowword",
+ "contraction",
+ "sufword",
+ "prfword",
+ "begword",
+ "begmidword",
+ "midword",
+ "midendword",
+ "endword",
+ "prepunc",
+ "postpunc",
+ "begnum",
+ "midnum",
+ "endnum",
+ "decpoint",
+ "hyphen",
+ // "apostrophe",
+ // "initial",
+ "nobreak",
+ "match",
+ "backmatch",
+ "attribute",
+};
+
+static short opcodeLengths[CTO_None] = { 0 };
+
+static void
+compileError(FileInfo *nested, const char *format, ...);
+
+static void
+free_tablefiles(char **tables);
+
+static int
+getAChar(FileInfo *nested) {
+ /* Read a big endian, little endian or ASCII 8 file and convert it to
+ * 16- or 32-bit unsigned integers */
+ int ch1 = 0, ch2 = 0;
+ widechar character;
+ if (nested->encoding == ascii8)
+ if (nested->status == 2) {
+ nested->status++;
+ return nested->checkencoding[1];
+ }
+ while ((ch1 = fgetc(nested->in)) != EOF) {
+ if (nested->status < 2) nested->checkencoding[nested->status] = ch1;
+ nested->status++;
+ if (nested->status == 2) {
+ if (nested->checkencoding[0] == 0xfe && nested->checkencoding[1] == 0xff)
+ nested->encoding = bigEndian;
+ else if (nested->checkencoding[0] == 0xff && nested->checkencoding[1] == 0xfe)
+ nested->encoding = littleEndian;
+ else if (nested->checkencoding[0] < 128 && nested->checkencoding[1] < 128) {
+ nested->encoding = ascii8;
+ return nested->checkencoding[0];
+ } else {
+ compileError(nested,
+ "encoding is neither big-endian, little-endian nor ASCII 8.");
+ ch1 = EOF;
+ break;
+ ;
+ }
+ continue;
+ }
+ switch (nested->encoding) {
+ case noEncoding:
+ break;
+ case ascii8:
+ return ch1;
+ break;
+ case bigEndian:
+ ch2 = fgetc(nested->in);
+ if (ch2 == EOF) break;
+ character = (widechar)(ch1 << 8) | ch2;
+ return (int)character;
+ break;
+ case littleEndian:
+ ch2 = fgetc(nested->in);
+ if (ch2 == EOF) break;
+ character = (widechar)(ch2 << 8) | ch1;
+ return (int)character;
+ break;
+ }
+ if (ch1 == EOF || ch2 == EOF) break;
+ }
+ return EOF;
+}
+
+int EXPORT_CALL
+_lou_getALine(FileInfo *nested) {
+ /* Read a line of widechar's from an input file */
+ int ch;
+ int pch = 0;
+ nested->linelen = 0;
+ while ((ch = getAChar(nested)) != EOF) {
+ if (ch == 13) continue;
+ if (pch == '\\' && ch == 10) {
+ nested->linelen--;
+ pch = ch;
+ continue;
+ }
+ if (ch == 10 || nested->linelen >= MAXSTRING - 1) break;
+ nested->line[nested->linelen++] = (widechar)ch;
+ pch = ch;
+ }
+ nested->line[nested->linelen] = 0;
+ nested->linepos = 0;
+ if (ch == EOF) return 0;
+ nested->lineNumber++;
+ return 1;
+}
+
+static inline int
+atEndOfLine(FileInfo *nested) {
+ return nested->linepos >= nested->linelen;
+}
+
+static inline int
+atTokenDelimiter(FileInfo *nested) {
+ return nested->line[nested->linepos] <= 32;
+}
+
+static int
+getToken(FileInfo *nested, CharsString *result, const char *description, int *lastToken) {
+ /* Find the next string of contiguous non-whitespace characters. If this
+ * is the last token on the line, return 2 instead of 1. */
+ while (!atEndOfLine(nested) && atTokenDelimiter(nested)) nested->linepos++;
+ result->length = 0;
+ while (!atEndOfLine(nested) && !atTokenDelimiter(nested)) {
+ int maxlen = MAXSTRING;
+ if (result->length >= maxlen) {
+ compileError(nested, "more than %d characters (bytes)", maxlen);
+ return 0;
+ } else
+ result->chars[result->length++] = nested->line[nested->linepos++];
+ }
+ if (!result->length) {
+ /* Not enough tokens */
+ if (description) compileError(nested, "%s not specified.", description);
+ return 0;
+ }
+ result->chars[result->length] = 0;
+ while (!atEndOfLine(nested) && atTokenDelimiter(nested)) nested->linepos++;
+ return (*lastToken = atEndOfLine(nested)) ? 2 : 1;
+}
+
+static void
+compileError(FileInfo *nested, const char *format, ...) {
+#ifndef __SYMBIAN32__
+ char buffer[MAXSTRING];
+ va_list arguments;
+ va_start(arguments, format);
+ vsnprintf(buffer, sizeof(buffer), format, arguments);
+ va_end(arguments);
+ if (nested)
+ _lou_logMessage(LOU_LOG_ERROR, "%s:%d: error: %s", nested->fileName,
+ nested->lineNumber, buffer);
+ else
+ _lou_logMessage(LOU_LOG_ERROR, "error: %s", buffer);
+ errorCount++;
+#endif
+}
+
+static void
+compileWarning(FileInfo *nested, const char *format, ...) {
+#ifndef __SYMBIAN32__
+ char buffer[MAXSTRING];
+ va_list arguments;
+ va_start(arguments, format);
+ vsnprintf(buffer, sizeof(buffer), format, arguments);
+ va_end(arguments);
+ if (nested)
+ _lou_logMessage(LOU_LOG_WARN, "%s:%d: warning: %s", nested->fileName,
+ nested->lineNumber, buffer);
+ else
+ _lou_logMessage(LOU_LOG_WARN, "warning: %s", buffer);
+ warningCount++;
+#endif
+}
+
+static int
+allocateSpaceInTranslationTable(FileInfo *nested, TranslationTableOffset *offset,
+ int count, TranslationTableHeader **table) {
+ /* allocate memory for table and expand previously allocated memory if necessary */
+ int spaceNeeded = ((count + OFFSETSIZE - 1) / OFFSETSIZE) * OFFSETSIZE;
+ TranslationTableOffset newSize = (*table)->bytesUsed + spaceNeeded;
+ TranslationTableOffset size = (*table)->tableSize;
+ if (newSize > size) {
+ TranslationTableHeader *newTable;
+ newSize += (newSize / OFFSETSIZE);
+ newTable = realloc(*table, newSize);
+ if (!newTable) {
+ compileError(nested, "Not enough memory for translation table.");
+ _lou_outOfMemory();
+ }
+ memset(((unsigned char *)newTable) + size, 0, newSize - size);
+ /* update references to the old table */
+ {
+ TranslationTableChainEntry *entry;
+ for (entry = translationTableChain; entry != NULL; entry = entry->next)
+ if (entry->table == *table)
+ entry->table = (TranslationTableHeader *)newTable;
+ }
+ *table = (TranslationTableHeader *)newTable;
+ (*table)->tableSize = newSize;
+ }
+ if (offset != NULL) {
+ *offset = ((*table)->bytesUsed - sizeof(**table)) / OFFSETSIZE;
+ (*table)->bytesUsed += spaceNeeded;
+ }
+ return 1;
+}
+
+static int
+allocateSpaceInDisplayTable(FileInfo *nested, TranslationTableOffset *offset, int count,
+ DisplayTableHeader **table) {
+ /* allocate memory for table and expand previously allocated memory if necessary */
+ int spaceNeeded = ((count + OFFSETSIZE - 1) / OFFSETSIZE) * OFFSETSIZE;
+ TranslationTableOffset newSize = (*table)->bytesUsed + spaceNeeded;
+ TranslationTableOffset size = (*table)->tableSize;
+ if (newSize > size) {
+ DisplayTableHeader *newTable;
+ newSize += (newSize / OFFSETSIZE);
+ newTable = realloc(*table, newSize);
+ if (!newTable) {
+ compileError(nested, "Not enough memory for display table.");
+ _lou_outOfMemory();
+ }
+ memset(((unsigned char *)newTable) + size, 0, newSize - size);
+ /* update references to the old table */
+ {
+ DisplayTableChainEntry *entry;
+ for (entry = displayTableChain; entry != NULL; entry = entry->next)
+ if (entry->table == *table) entry->table = (DisplayTableHeader *)newTable;
+ }
+ *table = (DisplayTableHeader *)newTable;
+ (*table)->tableSize = newSize;
+ }
+ if (offset != NULL) {
+ *offset = ((*table)->bytesUsed - sizeof(**table)) / OFFSETSIZE;
+ (*table)->bytesUsed += spaceNeeded;
+ }
+ return 1;
+}
+
+static int
+allocateTranslationTable(FileInfo *nested, TranslationTableHeader **table) {
+ /* Allocate memory for the table and a guess on the number of rules */
+ const TranslationTableOffset startSize = 2 * sizeof(**table);
+ if (*table) return 1;
+ TranslationTableOffset bytesUsed =
+ sizeof(**table) + OFFSETSIZE; /* So no offset is ever zero */
+ if (!(*table = malloc(startSize))) {
+ compileError(nested, "Not enough memory");
+ if (*table != NULL) free(*table);
+ *table = NULL;
+ _lou_outOfMemory();
+ }
+ memset(*table, 0, startSize);
+ (*table)->tableSize = startSize;
+ (*table)->bytesUsed = bytesUsed;
+ return 1;
+}
+
+static int
+allocateDisplayTable(FileInfo *nested, DisplayTableHeader **table) {
+ /* Allocate memory for the table and a guess on the number of rules */
+ const TranslationTableOffset startSize = 2 * sizeof(**table);
+ if (*table) return 1;
+ TranslationTableOffset bytesUsed =
+ sizeof(**table) + OFFSETSIZE; /* So no offset is ever zero */
+ if (!(*table = malloc(startSize))) {
+ compileError(nested, "Not enough memory");
+ if (*table != NULL) free(*table);
+ *table = NULL;
+ _lou_outOfMemory();
+ }
+ memset(*table, 0, startSize);
+ (*table)->tableSize = startSize;
+ (*table)->bytesUsed = bytesUsed;
+ return 1;
+}
+
+static TranslationTableCharacter *
+compile_findCharOrDots(widechar c, int m, TranslationTableHeader *table) {
+ /* Look up a character or dot pattern. If m is 0 look up a character,
+ * otherwise look up a dot pattern. Although the algorithms are almost
+ * identical, different tables are needed for characters and dots because
+ * of the possibility of conflicts. */
+ TranslationTableCharacter *character;
+ TranslationTableOffset bucket;
+ unsigned long int makeHash = _lou_charHash(c);
+ if (m == 0)
+ bucket = table->characters[makeHash];
+ else
+ bucket = table->dots[makeHash];
+ while (bucket) {
+ character = (TranslationTableCharacter *)&table->ruleArea[bucket];
+ if (character->realchar == c) return character;
+ bucket = character->next;
+ }
+ return NULL;
+}
+
+static TranslationTableCharacter *
+addCharOrDots(FileInfo *nested, widechar c, int m, TranslationTableHeader **table) {
+ /* See if a character or dot pattern is in the appropriate table. If not,
+ * insert it. In either
+ * case, return a pointer to it. */
+ TranslationTableOffset bucket;
+ TranslationTableCharacter *character;
+ TranslationTableCharacter *oldchar;
+ TranslationTableOffset offset;
+ unsigned long int makeHash;
+ if ((character = compile_findCharOrDots(c, m, *table))) return character;
+ if (!allocateSpaceInTranslationTable(nested, &offset, sizeof(*character), table))
+ return NULL;
+ character = (TranslationTableCharacter *)&(*table)->ruleArea[offset];
+ memset(character, 0, sizeof(*character));
+ character->realchar = c;
+ makeHash = _lou_charHash(c);
+ if (m == 0)
+ bucket = (*table)->characters[makeHash];
+ else
+ bucket = (*table)->dots[makeHash];
+ if (!bucket) {
+ if (m == 0)
+ (*table)->characters[makeHash] = offset;
+ else
+ (*table)->dots[makeHash] = offset;
+ } else {
+ oldchar = (TranslationTableCharacter *)&(*table)->ruleArea[bucket];
+ while (oldchar->next)
+ oldchar = (TranslationTableCharacter *)&(*table)->ruleArea[oldchar->next];
+ oldchar->next = offset;
+ }
+ return character;
+}
+
+static CharOrDots *
+getCharOrDots(widechar c, int m, const DisplayTableHeader *table) {
+ CharOrDots *cdPtr;
+ TranslationTableOffset bucket;
+ unsigned long int makeHash = _lou_charHash(c);
+ if (m == 0)
+ bucket = table->charToDots[makeHash];
+ else
+ bucket = table->dotsToChar[makeHash];
+ while (bucket) {
+ cdPtr = (CharOrDots *)&table->ruleArea[bucket];
+ if (cdPtr->lookFor == c) return cdPtr;
+ bucket = cdPtr->next;
+ }
+ return NULL;
+}
+
+widechar EXPORT_CALL
+_lou_getDotsForChar(widechar c, const DisplayTableHeader *table) {
+ CharOrDots *cdPtr = getCharOrDots(c, 0, table);
+ if (cdPtr) return cdPtr->found;
+ return LOU_DOTS;
+}
+
+widechar EXPORT_CALL
+_lou_getCharFromDots(widechar d, const DisplayTableHeader *table) {
+ CharOrDots *cdPtr = getCharOrDots(d, 1, table);
+ if (cdPtr) return cdPtr->found;
+ return '\0';
+}
+
+static int
+putCharAndDots(FileInfo *nested, widechar c, widechar d, DisplayTableHeader **table) {
+ TranslationTableOffset bucket;
+ CharOrDots *cdPtr;
+ CharOrDots *oldcdPtr = NULL;
+ TranslationTableOffset offset;
+ unsigned long int makeHash;
+ if (!(cdPtr = getCharOrDots(c, 0, *table))) {
+ if (!allocateSpaceInDisplayTable(nested, &offset, sizeof(*cdPtr), table))
+ return 0;
+ cdPtr = (CharOrDots *)&(*table)->ruleArea[offset];
+ cdPtr->next = 0;
+ cdPtr->lookFor = c;
+ cdPtr->found = d;
+ makeHash = _lou_charHash(c);
+ bucket = (*table)->charToDots[makeHash];
+ if (!bucket)
+ (*table)->charToDots[makeHash] = offset;
+ else {
+ oldcdPtr = (CharOrDots *)&(*table)->ruleArea[bucket];
+ while (oldcdPtr->next)
+ oldcdPtr = (CharOrDots *)&(*table)->ruleArea[oldcdPtr->next];
+ oldcdPtr->next = offset;
+ }
+ }
+ if (!(cdPtr = getCharOrDots(d, 1, *table))) {
+ if (!allocateSpaceInDisplayTable(nested, &offset, sizeof(*cdPtr), table))
+ return 0;
+ cdPtr = (CharOrDots *)&(*table)->ruleArea[offset];
+ cdPtr->next = 0;
+ cdPtr->lookFor = d;
+ cdPtr->found = c;
+ makeHash = _lou_charHash(d);
+ bucket = (*table)->dotsToChar[makeHash];
+ if (!bucket)
+ (*table)->dotsToChar[makeHash] = offset;
+ else {
+ oldcdPtr = (CharOrDots *)&(*table)->ruleArea[bucket];
+ while (oldcdPtr->next)
+ oldcdPtr = (CharOrDots *)&(*table)->ruleArea[oldcdPtr->next];
+ oldcdPtr->next = offset;
+ }
+ }
+ return 1;
+}
+
+static inline const char *
+getPartName(int actionPart) {
+ return actionPart ? "action" : "test";
+}
+
+static int
+passFindCharacters(FileInfo *nested, widechar *instructions, int end,
+ widechar **characters, int *length) {
+ int IC = 0;
+ int lookback = 0;
+
+ *characters = NULL;
+ *length = 0;
+
+ while (IC < end) {
+ widechar instruction = instructions[IC];
+
+ switch (instruction) {
+ case pass_string:
+ case pass_dots: {
+ int count = instructions[IC + 1];
+ IC += 2;
+ if (count > lookback) {
+ *characters = &instructions[IC + lookback];
+ *length = count - lookback;
+ return 1;
+ } else {
+ lookback -= count;
+ }
+ IC += count;
+ continue;
+ }
+
+ case pass_attributes:
+ IC += 5;
+ if (instructions[IC - 2] == instructions[IC - 1] &&
+ instructions[IC - 1] <= lookback) {
+ lookback -= instructions[IC - 1];
+ continue;
+ }
+ goto NO_CHARACTERS;
+
+ case pass_swap:
+ IC += 2;
+ /* fall through */
+
+ case pass_groupstart:
+ case pass_groupend:
+ case pass_groupreplace:
+ IC += 3;
+
+ NO_CHARACTERS : { return 1; }
+
+ case pass_eq:
+ case pass_lt:
+ case pass_gt:
+ case pass_lteq:
+ case pass_gteq:
+ IC += 3;
+ continue;
+
+ case pass_lookback:
+ lookback += instructions[IC + 1];
+ IC += 2;
+ continue;
+
+ case pass_not:
+ case pass_startReplace:
+ case pass_endReplace:
+ case pass_first:
+ case pass_last:
+ case pass_copy:
+ case pass_omit:
+ case pass_plus:
+ case pass_hyphen:
+ IC += 1;
+ continue;
+
+ case pass_endTest:
+ goto NO_CHARACTERS;
+
+ default:
+ compileError(nested, "unhandled test suboperand: \\x%02x", instruction);
+ return 0;
+ }
+ }
+ goto NO_CHARACTERS;
+}
+
+/* The following functions are called by addRule to handle various cases. */
+
+static void
+addForwardRuleWithSingleChar(FileInfo *nested, TranslationTableOffset newRuleOffset,
+ TranslationTableRule *newRule, TranslationTableHeader **table) {
+ /* direction = 0, newRule->charslen = 1 */
+ TranslationTableRule *currentRule;
+ TranslationTableOffset *currentOffsetPtr;
+ TranslationTableCharacter *character;
+ int m = 0;
+ if (newRule->opcode == CTO_CompDots || newRule->opcode == CTO_Comp6) return;
+ if (newRule->opcode >= CTO_Pass2 && newRule->opcode <= CTO_Pass4) m = 1;
+ // get the character from the table, or if the character is not defined yet, define it
+ // (without adding attributes)
+ character = addCharOrDots(nested, newRule->charsdots[0], m, table);
+ if (m != 1 && character->attributes & CTC_Letter &&
+ (newRule->opcode == CTO_WholeWord || newRule->opcode == CTO_LargeSign)) {
+ if ((*table)->noLetsignCount < LETSIGNSIZE)
+ (*table)->noLetsign[(*table)->noLetsignCount++] = newRule->charsdots[0];
+ }
+ // if the new rule is a character definition rule, set the main definition rule of
+ // this character to it
+ // (possibly overwriting previous definition rules)
+ // adding the attributes to the character has already been done elsewhere
+ if (newRule->opcode >= CTO_Space && newRule->opcode < CTO_UpLow)
+ character->definitionRule = newRuleOffset;
+ // add the new rule to the list of rules associated with this character
+ // if the new rule is a character definition rule, it is inserted at the end of the
+ // list
+ // otherwise it is inserted before the first character definition rule
+ currentOffsetPtr = &character->otherRules;
+ while (*currentOffsetPtr) {
+ currentRule = (TranslationTableRule *)&(*table)->ruleArea[*currentOffsetPtr];
+ if (currentRule->charslen == 0) break;
+ if (currentRule->opcode >= CTO_Space && currentRule->opcode < CTO_UpLow)
+ if (!(newRule->opcode >= CTO_Space && newRule->opcode < CTO_UpLow)) break;
+ currentOffsetPtr = ¤tRule->charsnext;
+ }
+ newRule->charsnext = *currentOffsetPtr;
+ *currentOffsetPtr = newRuleOffset;
+}
+
+static void
+addForwardRuleWithMultipleChars(TranslationTableOffset newRuleOffset,
+ TranslationTableRule *newRule, TranslationTableHeader *table) {
+ /* direction = 0 newRule->charslen > 1 */
+ TranslationTableRule *currentRule = NULL;
+ TranslationTableOffset *currentOffsetPtr =
+ &table->forRules[_lou_stringHash(&newRule->charsdots[0], 0, NULL)];
+ while (*currentOffsetPtr) {
+ currentRule = (TranslationTableRule *)&table->ruleArea[*currentOffsetPtr];
+ if (newRule->charslen > currentRule->charslen) break;
+ if (newRule->charslen == currentRule->charslen)
+ if ((currentRule->opcode == CTO_Always) && (newRule->opcode != CTO_Always))
+ break;
+ currentOffsetPtr = ¤tRule->charsnext;
+ }
+ newRule->charsnext = *currentOffsetPtr;
+ *currentOffsetPtr = newRuleOffset;
+}
+
+static void
+addBackwardRuleWithSingleCell(FileInfo *nested, widechar cell,
+ TranslationTableOffset newRuleOffset, TranslationTableRule *newRule,
+ TranslationTableHeader **table) {
+ /* direction = 1, newRule->dotslen = 1 */
+ TranslationTableRule *currentRule;
+ TranslationTableOffset *currentOffsetPtr;
+ TranslationTableCharacter *dots;
+ if (newRule->opcode == CTO_SwapCc || newRule->opcode == CTO_Repeated)
+ return; /* too ambiguous */
+ // get the cell from the table, or if the cell is not defined yet, define it (without
+ // adding attributes)
+ dots = addCharOrDots(nested, cell, 1, table);
+ if (newRule->opcode >= CTO_Space && newRule->opcode < CTO_UpLow)
+ dots->definitionRule = newRuleOffset;
+ currentOffsetPtr = &dots->otherRules;
+ while (*currentOffsetPtr) {
+ currentRule = (TranslationTableRule *)&(*table)->ruleArea[*currentOffsetPtr];
+ if (newRule->charslen > currentRule->charslen || currentRule->dotslen == 0) break;
+ if (currentRule->opcode >= CTO_Space && currentRule->opcode < CTO_UpLow)
+ if (!(newRule->opcode >= CTO_Space && newRule->opcode < CTO_UpLow)) break;
+ currentOffsetPtr = ¤tRule->dotsnext;
+ }
+ newRule->dotsnext = *currentOffsetPtr;
+ *currentOffsetPtr = newRuleOffset;
+}
+
+static void
+addBackwardRuleWithMultipleCells(widechar *cells, int count,
+ TranslationTableOffset newRuleOffset, TranslationTableRule *newRule,
+ TranslationTableHeader *table) {
+ /* direction = 1, newRule->dotslen > 1 */
+ TranslationTableRule *currentRule = NULL;
+ TranslationTableOffset *currentOffsetPtr =
+ &table->backRules[_lou_stringHash(cells, 0, NULL)];
+ if (newRule->opcode == CTO_SwapCc) return;
+ while (*currentOffsetPtr) {
+ int currentLength;
+ int newLength;
+ currentRule = (TranslationTableRule *)&table->ruleArea[*currentOffsetPtr];
+ currentLength = currentRule->dotslen + currentRule->charslen;
+ newLength = count + newRule->charslen;
+ if (newLength > currentLength) break;
+ if (currentLength == newLength)
+ if ((currentRule->opcode == CTO_Always) && (newRule->opcode != CTO_Always))
+ break;
+ currentOffsetPtr = ¤tRule->dotsnext;
+ }
+ newRule->dotsnext = *currentOffsetPtr;
+ *currentOffsetPtr = newRuleOffset;
+}
+
+static int
+addForwardPassRule(TranslationTableOffset newRuleOffset, TranslationTableRule *newRule,
+ TranslationTableHeader *table) {
+ TranslationTableOffset *currentOffsetPtr;
+ TranslationTableRule *currentRule;
+ switch (newRule->opcode) {
+ case CTO_Correct:
+ currentOffsetPtr = &table->forPassRules[0];
+ break;
+ case CTO_Context:
+ currentOffsetPtr = &table->forPassRules[1];
+ break;
+ case CTO_Pass2:
+ currentOffsetPtr = &table->forPassRules[2];
+ break;
+ case CTO_Pass3:
+ currentOffsetPtr = &table->forPassRules[3];
+ break;
+ case CTO_Pass4:
+ currentOffsetPtr = &table->forPassRules[4];
+ break;
+ default:
+ return 0;
+ }
+ while (*currentOffsetPtr) {
+ currentRule = (TranslationTableRule *)&table->ruleArea[*currentOffsetPtr];
+ if (newRule->charslen > currentRule->charslen) break;
+ currentOffsetPtr = ¤tRule->charsnext;
+ }
+ newRule->charsnext = *currentOffsetPtr;
+ *currentOffsetPtr = newRuleOffset;
+ return 1;
+}
+
+static int
+addBackwardPassRule(TranslationTableOffset newRuleOffset, TranslationTableRule *newRule,
+ TranslationTableHeader *table) {
+ TranslationTableOffset *currentOffsetPtr;
+ TranslationTableRule *currentRule;
+ switch (newRule->opcode) {
+ case CTO_Correct:
+ currentOffsetPtr = &table->backPassRules[0];
+ break;
+ case CTO_Context:
+ currentOffsetPtr = &table->backPassRules[1];
+ break;
+ case CTO_Pass2:
+ currentOffsetPtr = &table->backPassRules[2];
+ break;
+ case CTO_Pass3:
+ currentOffsetPtr = &table->backPassRules[3];
+ break;
+ case CTO_Pass4:
+ currentOffsetPtr = &table->backPassRules[4];
+ break;
+ default:
+ return 0;
+ }
+ while (*currentOffsetPtr) {
+ currentRule = (TranslationTableRule *)&table->ruleArea[*currentOffsetPtr];
+ if (newRule->charslen > currentRule->charslen) break;
+ currentOffsetPtr = ¤tRule->dotsnext;
+ }
+ newRule->dotsnext = *currentOffsetPtr;
+ *currentOffsetPtr = newRuleOffset;
+ return 1;
+}
+
+static int
+addRule(FileInfo *nested, TranslationTableOpcode opcode, CharsString *ruleChars,
+ CharsString *ruleDots, TranslationTableCharacterAttributes after,
+ TranslationTableCharacterAttributes before, TranslationTableOffset *newRuleOffset,
+ TranslationTableRule **newRule, int noback, int nofor,
+ TranslationTableHeader **table) {
+ /* Add a rule to the table, using the hash function to find the start of
+ * chains and chaining both the chars and dots strings */
+ TranslationTableOffset ruleOffset;
+ int ruleSize = sizeof(TranslationTableRule) - (DEFAULTRULESIZE * CHARSIZE);
+ if (ruleChars) ruleSize += CHARSIZE * ruleChars->length;
+ if (ruleDots) ruleSize += CHARSIZE * ruleDots->length;
+ if (!allocateSpaceInTranslationTable(nested, &ruleOffset, ruleSize, table)) return 0;
+ TranslationTableRule *rule = (TranslationTableRule *)&(*table)->ruleArea[ruleOffset];
+ if (newRule) *newRule = rule;
+ if (newRuleOffset) *newRuleOffset = ruleOffset;
+ rule->opcode = opcode;
+ rule->after = after;
+ rule->before = before;
+ if (ruleChars)
+ memcpy(&rule->charsdots[0], &ruleChars->chars[0],
+ CHARSIZE * (rule->charslen = ruleChars->length));
+ else
+ rule->charslen = 0;
+ if (ruleDots)
+ memcpy(&rule->charsdots[rule->charslen], &ruleDots->chars[0],
+ CHARSIZE * (rule->dotslen = ruleDots->length));
+ else
+ rule->dotslen = 0;
+
+ /* link new rule into table. */
+ if (opcode == CTO_SwapCc || opcode == CTO_SwapCd || opcode == CTO_SwapDd) return 1;
+ if (opcode >= CTO_Context && opcode <= CTO_Pass4)
+ if (!(opcode == CTO_Context && rule->charslen > 0)) {
+ if (!nofor)
+ if (!addForwardPassRule(ruleOffset, rule, *table)) return 0;
+ if (!noback)
+ if (!addBackwardPassRule(ruleOffset, rule, *table)) return 0;
+ return 1;
+ }
+ if (!nofor) {
+ if (rule->charslen == 1)
+ addForwardRuleWithSingleChar(nested, ruleOffset, rule, table);
+ else if (rule->charslen > 1)
+ addForwardRuleWithMultipleChars(ruleOffset, rule, *table);
+ }
+ if (!noback) {
+ widechar *cells;
+ int count;
+
+ if (rule->opcode == CTO_Context) {
+ cells = &rule->charsdots[0];
+ count = rule->charslen;
+ } else {
+ cells = &rule->charsdots[rule->charslen];
+ count = rule->dotslen;
+ }
+
+ if (count == 1)
+ addBackwardRuleWithSingleCell(nested, *cells, ruleOffset, rule, table);
+ else if (count > 1)
+ addBackwardRuleWithMultipleCells(cells, count, ruleOffset, rule, *table);
+ }
+ return 1;
+}
+
+static const CharacterClass *
+findCharacterClass(const CharsString *name, const TranslationTableHeader *table) {
+ /* Find a character class, whether predefined or user-defined */
+ const CharacterClass *class = table->characterClasses;
+ while (class) {
+ if ((name->length == class->length) &&
+ (memcmp(&name->chars[0], class->name, CHARSIZE * name->length) == 0))
+ return class;
+ class = class->next;
+ }
+ return NULL;
+}
+
+static CharacterClass *
+addCharacterClass(FileInfo *nested, const widechar *name, int length,
+ TranslationTableHeader *table) {
+ /* Define a character class, Whether predefined or user-defined */
+ CharacterClass **classes = &table->characterClasses;
+ ;
+ TranslationTableCharacterAttributes *nextAttribute =
+ &table->nextCharacterClassAttribute;
+ CharacterClass *class;
+ if (*nextAttribute) {
+ if (!(class = malloc(sizeof(*class) + CHARSIZE * (length - 1))))
+ _lou_outOfMemory();
+ else {
+ memset(class, 0, sizeof(*class));
+ memcpy(class->name, name, CHARSIZE * (class->length = length));
+ class->attribute = *nextAttribute;
+ if (*nextAttribute == CTC_Class4)
+ *nextAttribute = CTC_UserDefined0;
+ else if (*nextAttribute == CTC_UserDefined7)
+ *nextAttribute = CTC_Class13;
+ else
+ *nextAttribute <<= 1;
+ class->next = *classes;
+ *classes = class;
+ return class;
+ }
+ }
+ compileError(nested, "character class table overflow.");
+ return NULL;
+}
+
+static void
+deallocateCharacterClasses(TranslationTableHeader *table) {
+ CharacterClass **classes = &table->characterClasses;
+ while (*classes) {
+ CharacterClass *class = *classes;
+ *classes = (*classes)->next;
+ if (class) free(class);
+ }
+}
+
+static int
+allocateCharacterClasses(TranslationTableHeader *table) {
+ /* Allocate memory for predifined character classes */
+ int k = 0;
+ table->characterClasses = NULL;
+ table->nextCharacterClassAttribute = 1;
+ while (characterClassNames[k]) {
+ widechar wname[MAXSTRING];
+ int length = (int)strlen(characterClassNames[k]);
+ int kk;
+ for (kk = 0; kk < length; kk++) wname[kk] = (widechar)characterClassNames[k][kk];
+ if (!addCharacterClass(NULL, wname, length, table)) {
+ deallocateCharacterClasses(table);
+ return 0;
+ }
+ k++;
+ }
+ return 1;
+}
+
+static TranslationTableOpcode
+getOpcode(FileInfo *nested, const CharsString *token) {
+ static TranslationTableOpcode lastOpcode = 0;
+ TranslationTableOpcode opcode = lastOpcode;
+
+ do {
+ if (token->length == opcodeLengths[opcode])
+ if (eqasc2uni((unsigned char *)opcodeNames[opcode], &token->chars[0],
+ token->length)) {
+ lastOpcode = opcode;
+ return opcode;
+ }
+ opcode++;
+ if (opcode >= CTO_None) opcode = 0;
+ } while (opcode != lastOpcode);
+ compileError(nested, "opcode %s not defined.",
+ _lou_showString(&token->chars[0], token->length, 0));
+ return CTO_None;
+}
+
+TranslationTableOpcode EXPORT_CALL
+_lou_findOpcodeNumber(const char *toFind) {
+ /* Used by tools such as lou_debug */
+ static TranslationTableOpcode lastOpcode = 0;
+ TranslationTableOpcode opcode = lastOpcode;
+ int length = (int)strlen(toFind);
+ do {
+ if (length == opcodeLengths[opcode] &&
+ strcasecmp(toFind, opcodeNames[opcode]) == 0) {
+ lastOpcode = opcode;
+ return opcode;
+ }
+ opcode++;
+ if (opcode >= CTO_None) opcode = 0;
+ } while (opcode != lastOpcode);
+ return CTO_None;
+}
+
+const char *EXPORT_CALL
+_lou_findOpcodeName(TranslationTableOpcode opcode) {
+ static char scratchBuf[MAXSTRING];
+ /* Used by tools such as lou_debug */
+ if (opcode < 0 || opcode >= CTO_None) {
+ sprintf(scratchBuf, "%u", opcode);
+ return scratchBuf;
+ }
+ return opcodeNames[opcode];
+}
+
+static widechar
+hexValue(FileInfo *nested, const widechar *digits, int length) {
+ int k;
+ unsigned int binaryValue = 0;
+ for (k = 0; k < length; k++) {
+ unsigned int hexDigit = 0;
+ if (digits[k] >= '0' && digits[k] <= '9')
+ hexDigit = digits[k] - '0';
+ else if (digits[k] >= 'a' && digits[k] <= 'f')
+ hexDigit = digits[k] - 'a' + 10;
+ else if (digits[k] >= 'A' && digits[k] <= 'F')
+ hexDigit = digits[k] - 'A' + 10;
+ else {
+ compileError(nested, "invalid %d-digit hexadecimal number", length);
+ return (widechar)0xffffffff;
+ }
+ binaryValue |= hexDigit << (4 * (length - 1 - k));
+ }
+ return (widechar)binaryValue;
+}
+
+#define MAXBYTES 7
+static const unsigned int first0Bit[MAXBYTES] = { 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC,
+ 0XFE };
+
+static int
+parseChars(FileInfo *nested, CharsString *result, CharsString *token) {
+ int in = 0;
+ int out = 0;
+ int lastOutSize = 0;
+ int lastIn;
+ unsigned int ch = 0;
+ int numBytes = 0;
+ unsigned int utf32 = 0;
+ int k;
+ while (in < token->length) {
+ ch = token->chars[in++] & 0xff;
+ if (ch < 128) {
+ if (ch == '\\') { /* escape sequence */
+ switch (ch = token->chars[in]) {
+ case '\\':
+ break;
+ case 'e':
+ ch = 0x1b;
+ break;
+ case 'f':
+ ch = 12;
+ break;
+ case 'n':
+ ch = 10;
+ break;
+ case 'r':
+ ch = 13;
+ break;
+ case 's':
+ ch = ' ';
+ break;
+ case 't':
+ ch = 9;
+ break;
+ case 'v':
+ ch = 11;
+ break;
+ case 'w':
+ ch = LOU_ENDSEGMENT;
+ break;
+ case 34:
+ ch = QUOTESUB;
+ break;
+ case 'X':
+ compileWarning(nested, "\\Xhhhh (with a capital 'X') is deprecated.");
+ case 'x':
+ if (token->length - in > 4) {
+ ch = hexValue(nested, &token->chars[in + 1], 4);
+ in += 4;
+ }
+ break;
+ case 'Y':
+ compileWarning(
+ nested, "\\Yhhhhh (with a capital 'Y') is deprecated.");
+ case 'y':
+ if (CHARSIZE == 2) {
+ not32:
+ compileError(nested,
+ "liblouis has not been compiled for 32-bit Unicode");
+ break;
+ }
+ if (token->length - in > 5) {
+ ch = hexValue(nested, &token->chars[in + 1], 5);
+ in += 5;
+ }
+ break;
+ case 'Z':
+ compileWarning(
+ nested, "\\Zhhhhhhhh (with a capital 'Z') is deprecated.");
+ case 'z':
+ if (CHARSIZE == 2) goto not32;
+ if (token->length - in > 8) {
+ ch = hexValue(nested, &token->chars[in + 1], 8);
+ in += 8;
+ }
+ break;
+ default:
+ compileError(nested, "invalid escape sequence '\\%c'", ch);
+ break;
+ }
+ in++;
+ }
+ if (out >= MAXSTRING - 1) {
+ compileError(nested, "Token too long");
+ result->length = MAXSTRING - 1;
+ return 1;
+ }
+ result->chars[out++] = (widechar)ch;
+ continue;
+ }
+ lastOutSize = out;
+ lastIn = in;
+ for (numBytes = MAXBYTES - 1; numBytes > 0; numBytes--)
+ if (ch >= first0Bit[numBytes]) break;
+ utf32 = ch & (0XFF - first0Bit[numBytes]);
+ for (k = 0; k < numBytes; k++) {
+ if (in >= MAXSTRING - 1) break;
+ if (out >= MAXSTRING - 1) {
+ compileError(nested, "Token too long");
+ result->length = lastOutSize;
+ return 1;
+ }
+ if (token->chars[in] < 128 || (token->chars[in] & 0x0040)) {
+ compileWarning(nested, "invalid UTF-8. Assuming Latin-1.");
+ result->chars[out++] = token->chars[lastIn];
+ in = lastIn + 1;
+ continue;
+ }
+ utf32 = (utf32 << 6) + (token->chars[in++] & 0x3f);
+ }
+ if (out >= MAXSTRING - 1) {
+ compileError(nested, "Token too long");
+ result->length = lastOutSize;
+ return 1;
+ }
+ if (CHARSIZE == 2 && utf32 > 0xffff) utf32 = 0xffff;
+ result->chars[out++] = (widechar)utf32;
+ }
+ result->length = out;
+ return 1;
+}
+
+int EXPORT_CALL
+_lou_extParseChars(const char *inString, widechar *outString) {
+ /* Parse external character strings */
+ CharsString wideIn;
+ CharsString result;
+ int k;
+ for (k = 0; inString[k] && k < MAXSTRING - 1; k++) wideIn.chars[k] = inString[k];
+ wideIn.chars[k] = 0;
+ wideIn.length = k;
+ parseChars(NULL, &result, &wideIn);
+ if (errorCount) {
+ errorCount = 0;
+ return 0;
+ }
+ for (k = 0; k < result.length; k++) outString[k] = result.chars[k];
+ return result.length;
+}
+
+static int
+parseDots(FileInfo *nested, CharsString *cells, const CharsString *token) {
+ /* get dot patterns */
+ widechar cell = 0; /* assembly place for dots */
+ int cellCount = 0;
+ int index;
+ int start = 0;
+
+ for (index = 0; index < token->length; index++) {
+ int started = index != start;
+ widechar character = token->chars[index];
+ switch (character) { /* or dots to make up Braille cell */
+ {
+ int dot;
+ case '1':
+ dot = LOU_DOT_1;
+ goto haveDot;
+ case '2':
+ dot = LOU_DOT_2;
+ goto haveDot;
+ case '3':
+ dot = LOU_DOT_3;
+ goto haveDot;
+ case '4':
+ dot = LOU_DOT_4;
+ goto haveDot;
+ case '5':
+ dot = LOU_DOT_5;
+ goto haveDot;
+ case '6':
+ dot = LOU_DOT_6;
+ goto haveDot;
+ case '7':
+ dot = LOU_DOT_7;
+ goto haveDot;
+ case '8':
+ dot = LOU_DOT_8;
+ goto haveDot;
+ case '9':
+ dot = LOU_DOT_9;
+ goto haveDot;
+ case 'a':
+ case 'A':
+ dot = LOU_DOT_10;
+ goto haveDot;
+ case 'b':
+ case 'B':
+ dot = LOU_DOT_11;
+ goto haveDot;
+ case 'c':
+ case 'C':
+ dot = LOU_DOT_12;
+ goto haveDot;
+ case 'd':
+ case 'D':
+ dot = LOU_DOT_13;
+ goto haveDot;
+ case 'e':
+ case 'E':
+ dot = LOU_DOT_14;
+ goto haveDot;
+ case 'f':
+ case 'F':
+ dot = LOU_DOT_15;
+ haveDot:
+ if (started && !cell) goto invalid;
+ if (cell & dot) {
+ compileError(nested, "dot specified more than once.");
+ return 0;
+ }
+ cell |= dot;
+ break;
+ }
+ case '0': /* blank */
+ if (started) goto invalid;
+ break;
+ case '-': /* got all dots for this cell */
+ if (!started) {
+ compileError(nested, "missing cell specification.");
+ return 0;
+ }
+ cells->chars[cellCount++] = cell | LOU_DOTS;
+ cell = 0;
+ start = index + 1;
+ break;
+ default:
+ invalid:
+ compileError(
+ nested, "invalid dot number %s.", _lou_showString(&character, 1, 0));
+ return 0;
+ }
+ }
+ if (index == start) {
+ compileError(nested, "missing cell specification.");
+ return 0;
+ }
+ cells->chars[cellCount++] = cell | LOU_DOTS; /* last cell */
+ cells->length = cellCount;
+ return 1;
+}
+
+int EXPORT_CALL
+_lou_extParseDots(const char *inString, widechar *outString) {
+ /* Parse external dot patterns */
+ CharsString wideIn;
+ CharsString result;
+ int k;
+ for (k = 0; inString[k] && k < MAXSTRING - 1; k++) wideIn.chars[k] = inString[k];
+ wideIn.chars[k] = 0;
+ wideIn.length = k;
+ parseDots(NULL, &result, &wideIn);
+ if (errorCount) {
+ errorCount = 0;
+ return 0;
+ }
+ for (k = 0; k < result.length; k++) outString[k] = result.chars[k];
+ outString[k] = 0;
+ return result.length;
+}
+
+static int
+getCharacters(FileInfo *nested, CharsString *characters, int *lastToken) {
+ /* Get ruleChars string */
+ CharsString token;
+ if (getToken(nested, &token, "characters", lastToken))
+ if (parseChars(nested, characters, &token)) return 1;
+ return 0;
+}
+
+static int
+getRuleCharsText(FileInfo *nested, CharsString *ruleChars, int *lastToken) {
+ CharsString token;
+ if (getToken(nested, &token, "Characters operand", lastToken))
+ if (parseChars(nested, ruleChars, &token)) return 1;
+ return 0;
+}
+
+static int
+getRuleDotsText(FileInfo *nested, CharsString *ruleDots, int *lastToken) {
+ CharsString token;
+ if (getToken(nested, &token, "characters", lastToken))
+ if (parseChars(nested, ruleDots, &token)) return 1;
+ return 0;
+}
+
+static int
+getRuleDotsPattern(FileInfo *nested, CharsString *ruleDots, int *lastToken) {
+ /* Interpret the dets operand */
+ CharsString token;
+ if (getToken(nested, &token, "Dots operand", lastToken)) {
+ if (token.length == 1 && token.chars[0] == '=') {
+ ruleDots->length = 0;
+ return 1;
+ }
+ if (parseDots(nested, ruleDots, &token)) return 1;
+ }
+ return 0;
+}
+
+static int
+getCharacterClass(FileInfo *nested, const CharacterClass **class,
+ const TranslationTableHeader *table, int *lastToken) {
+ CharsString token;
+ if (getToken(nested, &token, "character class name", lastToken)) {
+ if ((*class = findCharacterClass(&token, table))) return 1;
+ compileError(nested, "character class not defined.");
+ }
+ return 0;
+}
+
+static int
+includeFile(FileInfo *nested, CharsString *includedFile, TranslationTableHeader **table,
+ DisplayTableHeader **displayTable);
+
+static TranslationTableOffset
+findRuleName(const CharsString *name, const TranslationTableHeader *table) {
+ const RuleName *nameRule = table->ruleNames;
+ while (nameRule) {
+ if ((name->length == nameRule->length) &&
+ (memcmp(&name->chars[0], nameRule->name, CHARSIZE * name->length) == 0))
+ return nameRule->ruleOffset;
+ nameRule = nameRule->next;
+ }
+ return 0;
+}
+
+static int
+addRuleName(FileInfo *nested, CharsString *name, TranslationTableOffset newRuleOffset,
+ TranslationTableHeader *table) {
+ int k;
+ RuleName *nameRule;
+ if (!(nameRule = malloc(sizeof(*nameRule) + CHARSIZE * (name->length - 1)))) {
+ compileError(nested, "not enough memory");
+ _lou_outOfMemory();
+ }
+ memset(nameRule, 0, sizeof(*nameRule));
+ // a name is a sequence of characters in the ranges 'a'..'z' and 'A'..'Z'
+ for (k = 0; k < name->length; k++) {
+ widechar c = name->chars[k];
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
+ nameRule->name[k] = c;
+ else {
+ compileError(nested, "a name may contain only letters");
+ return 0;
+ }
+ }
+ nameRule->length = name->length;
+ nameRule->ruleOffset = newRuleOffset;
+ nameRule->next = table->ruleNames;
+ table->ruleNames = nameRule;
+ return 1;
+}
+
+static void
+deallocateRuleNames(TranslationTableHeader *table) {
+ RuleName **ruleNames = &table->ruleNames;
+ while (*ruleNames) {
+ RuleName *nameRule = *ruleNames;
+ *ruleNames = nameRule->next;
+ if (nameRule) free(nameRule);
+ }
+}
+
+static int
+compileSwapDots(FileInfo *nested, CharsString *source, CharsString *dest) {
+ int k = 0;
+ int kk = 0;
+ CharsString dotsSource;
+ CharsString dotsDest;
+ dest->length = 0;
+ dotsSource.length = 0;
+ while (k <= source->length) {
+ if (source->chars[k] != ',' && k != source->length)
+ dotsSource.chars[dotsSource.length++] = source->chars[k];
+ else {
+ if (!parseDots(nested, &dotsDest, &dotsSource)) return 0;
+ dest->chars[dest->length++] = dotsDest.length + 1;
+ for (kk = 0; kk < dotsDest.length; kk++)
+ dest->chars[dest->length++] = dotsDest.chars[kk];
+ dotsSource.length = 0;
+ }
+ k++;
+ }
+ return 1;
+}
+
+static int
+compileSwap(FileInfo *nested, TranslationTableOpcode opcode, int *lastToken,
+ TranslationTableOffset *newRuleOffset, TranslationTableRule **newRule, int noback,
+ int nofor, TranslationTableHeader **table) {
+ CharsString ruleChars;
+ CharsString ruleDots;
+ CharsString name;
+ CharsString matches;
+ CharsString replacements;
+ TranslationTableOffset ruleOffset;
+ if (!getToken(nested, &name, "name operand", lastToken)) return 0;
+ if (!getToken(nested, &matches, "matches operand", lastToken)) return 0;
+ if (!getToken(nested, &replacements, "replacements operand", lastToken)) return 0;
+ if (opcode == CTO_SwapCc || opcode == CTO_SwapCd) {
+ if (!parseChars(nested, &ruleChars, &matches)) return 0;
+ } else {
+ if (!compileSwapDots(nested, &matches, &ruleChars)) return 0;
+ }
+ if (opcode == CTO_SwapCc) {
+ if (!parseChars(nested, &ruleDots, &replacements)) return 0;
+ } else {
+ if (!compileSwapDots(nested, &replacements, &ruleDots)) return 0;
+ }
+ if (!addRule(nested, opcode, &ruleChars, &ruleDots, 0, 0, &ruleOffset, newRule,
+ noback, nofor, table))
+ return 0;
+ if (!addRuleName(nested, &name, ruleOffset, *table)) return 0;
+ if (newRuleOffset) *newRuleOffset = ruleOffset;
+ return 1;
+}
+
+static int
+getNumber(widechar *source, widechar *dest) {
+ /* Convert a string of wide character digits to an integer */
+ int k = 0;
+ *dest = 0;
+ while (source[k] >= '0' && source[k] <= '9') *dest = 10 * *dest + (source[k++] - '0');
+ return k;
+}
+
+/* Start of multipass compiler */
+
+static int
+passGetAttributes(CharsString *passLine, int *passLinepos,
+ TranslationTableCharacterAttributes *passAttributes, FileInfo *passNested) {
+ int more = 1;
+ *passAttributes = 0;
+ while (more) {
+ switch (passLine->chars[*passLinepos]) {
+ case pass_any:
+ *passAttributes = 0xffffffff;
+ break;
+ case pass_digit:
+ *passAttributes |= CTC_Digit;
+ break;
+ case pass_litDigit:
+ *passAttributes |= CTC_LitDigit;
+ break;
+ case pass_letter:
+ *passAttributes |= CTC_Letter;
+ break;
+ case pass_math:
+ *passAttributes |= CTC_Math;
+ break;
+ case pass_punctuation:
+ *passAttributes |= CTC_Punctuation;
+ break;
+ case pass_sign:
+ *passAttributes |= CTC_Sign;
+ break;
+ case pass_space:
+ *passAttributes |= CTC_Space;
+ break;
+ case pass_uppercase:
+ *passAttributes |= CTC_UpperCase;
+ break;
+ case pass_lowercase:
+ *passAttributes |= CTC_LowerCase;
+ break;
+ case pass_class1:
+ *passAttributes |= CTC_Class1;
+ break;
+ case pass_class2:
+ *passAttributes |= CTC_Class2;
+ break;
+ case pass_class3:
+ *passAttributes |= CTC_Class3;
+ break;
+ case pass_class4:
+ *passAttributes |= CTC_Class4;
+ break;
+ default:
+ more = 0;
+ break;
+ }
+ if (more) (*passLinepos)++;
+ }
+ if (!*passAttributes) {
+ compileError(passNested, "missing attribute");
+ (*passLinepos)--;
+ return 0;
+ }
+ return 1;
+}
+
+static int
+passGetDots(CharsString *passLine, int *passLinepos, CharsString *passHoldString,
+ FileInfo *passNested) {
+ CharsString collectDots;
+ collectDots.length = 0;
+ while (*passLinepos < passLine->length &&
+ (passLine->chars[*passLinepos] == '-' ||
+ (passLine->chars[*passLinepos] >= '0' &&
+ passLine->chars[*passLinepos] <= '9') ||
+ ((passLine->chars[*passLinepos] | 32) >= 'a' &&
+ (passLine->chars[*passLinepos] | 32) <= 'f')))
+ collectDots.chars[collectDots.length++] = passLine->chars[(*passLinepos)++];
+ if (!parseDots(passNested, passHoldString, &collectDots)) return 0;
+ return 1;
+}
+
+static int
+passGetString(CharsString *passLine, int *passLinepos, CharsString *passHoldString,
+ FileInfo *passNested) {
+ passHoldString->length = 0;
+ while (1) {
+ if ((*passLinepos >= passLine->length) || !passLine->chars[*passLinepos]) {
+ compileError(passNested, "unterminated string");
+ return 0;
+ }
+ if (passLine->chars[*passLinepos] == 34) break;
+ if (passLine->chars[*passLinepos] == QUOTESUB)
+ passHoldString->chars[passHoldString->length++] = 34;
+ else
+ passHoldString->chars[passHoldString->length++] =
+ passLine->chars[*passLinepos];
+ (*passLinepos)++;
+ }
+ passHoldString->chars[passHoldString->length] = 0;
+ (*passLinepos)++;
+ return 1;
+}
+
+static int
+passGetNumber(CharsString *passLine, int *passLinepos, widechar *passHoldNumber) {
+ /* Convert a string of wide character digits to an integer */
+ *passHoldNumber = 0;
+ while ((*passLinepos < passLine->length) && (passLine->chars[*passLinepos] >= '0') &&
+ (passLine->chars[*passLinepos] <= '9'))
+ *passHoldNumber =
+ 10 * (*passHoldNumber) + (passLine->chars[(*passLinepos)++] - '0');
+ return 1;
+}
+
+static int
+passGetVariableNumber(FileInfo *nested, CharsString *passLine, int *passLinepos,
+ widechar *passHoldNumber) {
+ if (!passGetNumber(passLine, passLinepos, passHoldNumber)) return 0;
+ if ((*passHoldNumber >= 0) && (*passHoldNumber < NUMVAR)) return 1;
+ compileError(nested, "variable number out of range");
+ return 0;
+}
+
+static int
+passGetName(CharsString *passLine, int *passLinepos, CharsString *passHoldString) {
+ passHoldString->length = 0;
+ // a name is a sequence of characters in the ranges 'a'..'z' and 'A'..'Z'
+ do {
+ widechar c = passLine->chars[*passLinepos];
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+ passHoldString->chars[passHoldString->length++] = c;
+ (*passLinepos)++;
+ } else {
+ break;
+ }
+ } while (*passLinepos < passLine->length);
+ return 1;
+}
+
+static inline int
+wantsString(TranslationTableOpcode opcode, int actionPart, int nofor) {
+ if (opcode == CTO_Correct) return 1;
+ if (opcode != CTO_Context) return 0;
+ return !nofor == !actionPart;
+}
+
+static int
+verifyStringOrDots(FileInfo *nested, TranslationTableOpcode opcode, int isString,
+ int actionPart, int nofor) {
+ if (!wantsString(opcode, actionPart, nofor) == !isString) return 1;
+
+ compileError(nested, "%s are not allowed in the %s part of a %s translation %s rule.",
+ isString ? "strings" : "dots", getPartName(actionPart),
+ nofor ? "backward" : "forward", _lou_findOpcodeName(opcode));
+
+ return 0;
+}
+
+static int
+compilePassOpcode(FileInfo *nested, TranslationTableOpcode opcode,
+ TranslationTableOffset *newRuleOffset, TranslationTableRule **newRule, int noback,
+ int nofor, TranslationTableHeader **table) {
+ static CharsString passRuleChars;
+ static CharsString passRuleDots;
+ /* Compile the operands of a pass opcode */
+ widechar passSubOp;
+ const CharacterClass *class;
+ TranslationTableOffset ruleOffset = 0;
+ TranslationTableRule *rule = NULL;
+ int k;
+ int kk = 0;
+ int endTest = 0;
+ widechar *passInstructions = passRuleDots.chars;
+ int passIC = 0; /* Instruction counter */
+ passRuleChars.length = 0;
+ FileInfo *passNested = nested;
+ CharsString passHoldString;
+ widechar passHoldNumber;
+ CharsString passLine;
+ int passLinepos = 0;
+ TranslationTableCharacterAttributes passAttributes;
+ passHoldString.length = 0;
+ for (k = nested->linepos; k < nested->linelen; k++)
+ passHoldString.chars[passHoldString.length++] = nested->line[k];
+#define SEPCHAR 0x0001
+ for (k = 0; k < passHoldString.length && passHoldString.chars[k] > 32; k++)
+ ;
+ if (k < passHoldString.length)
+ passHoldString.chars[k] = SEPCHAR;
+ else {
+ compileError(passNested, "Invalid multipass operands");
+ return 0;
+ }
+ parseChars(passNested, &passLine, &passHoldString);
+ /* Compile test part */
+ for (k = 0; k < passLine.length && passLine.chars[k] != SEPCHAR; k++)
+ ;
+ endTest = k;
+ passLine.chars[endTest] = pass_endTest;
+ passLinepos = 0;
+ while (passLinepos <= endTest) {
+ if (passIC >= MAXSTRING) {
+ compileError(passNested, "Test part in multipass operand too long");
+ return 0;
+ }
+ switch ((passSubOp = passLine.chars[passLinepos])) {
+ case pass_lookback:
+ passInstructions[passIC++] = pass_lookback;
+ passLinepos++;
+ passGetNumber(&passLine, &passLinepos, &passHoldNumber);
+ if (passHoldNumber == 0) passHoldNumber = 1;
+ passInstructions[passIC++] = passHoldNumber;
+ break;
+ case pass_not:
+ passInstructions[passIC++] = pass_not;
+ passLinepos++;
+ break;
+ case pass_first:
+ passInstructions[passIC++] = pass_first;
+ passLinepos++;
+ break;
+ case pass_last:
+ passInstructions[passIC++] = pass_last;
+ passLinepos++;
+ break;
+ case pass_search:
+ passInstructions[passIC++] = pass_search;
+ passLinepos++;
+ break;
+ case pass_string:
+ if (!verifyStringOrDots(nested, opcode, 1, 0, nofor)) {
+ return 0;
+ }
+ passLinepos++;
+ passInstructions[passIC++] = pass_string;
+ passGetString(&passLine, &passLinepos, &passHoldString, passNested);
+ goto testDoCharsDots;
+ case pass_dots:
+ if (!verifyStringOrDots(nested, opcode, 0, 0, nofor)) {
+ return 0;
+ }
+ passLinepos++;
+ passInstructions[passIC++] = pass_dots;
+ passGetDots(&passLine, &passLinepos, &passHoldString, passNested);
+ testDoCharsDots:
+ if (passHoldString.length == 0) return 0;
+ if (passIC >= MAXSTRING) {
+ compileError(passNested,
+ "@ operand in test part of multipass operand too long");
+ return 0;
+ }
+ passInstructions[passIC++] = passHoldString.length;
+ for (kk = 0; kk < passHoldString.length; kk++) {
+ if (passIC >= MAXSTRING) {
+ compileError(passNested,
+ "@ operand in test part of multipass operand too long");
+ return 0;
+ }
+ passInstructions[passIC++] = passHoldString.chars[kk];
+ }
+ break;
+ case pass_startReplace:
+ passInstructions[passIC++] = pass_startReplace;
+ passLinepos++;
+ break;
+ case pass_endReplace:
+ passInstructions[passIC++] = pass_endReplace;
+ passLinepos++;
+ break;
+ case pass_variable:
+ passLinepos++;
+ if (!passGetVariableNumber(nested, &passLine, &passLinepos, &passHoldNumber))
+ return 0;
+ switch (passLine.chars[passLinepos]) {
+ case pass_eq:
+ passInstructions[passIC++] = pass_eq;
+ goto doComp;
+ case pass_lt:
+ if (passLine.chars[passLinepos + 1] == pass_eq) {
+ passLinepos++;
+ passInstructions[passIC++] = pass_lteq;
+ } else
+ passInstructions[passIC++] = pass_lt;
+ goto doComp;
+ case pass_gt:
+ if (passLine.chars[passLinepos + 1] == pass_eq) {
+ passLinepos++;
+ passInstructions[passIC++] = pass_gteq;
+ } else
+ passInstructions[passIC++] = pass_gt;
+ doComp:
+ passInstructions[passIC++] = passHoldNumber;
+ passLinepos++;
+ passGetNumber(&passLine, &passLinepos, &passHoldNumber);
+ passInstructions[passIC++] = passHoldNumber;
+ break;
+ default:
+ compileError(passNested, "incorrect comparison operator");
+ return 0;
+ }
+ break;
+ case pass_attributes:
+ passLinepos++;
+ if (!passGetAttributes(&passLine, &passLinepos, &passAttributes, passNested))
+ return 0;
+ insertAttributes:
+ passInstructions[passIC++] = pass_attributes;
+ passInstructions[passIC++] = passAttributes >> 16;
+ passInstructions[passIC++] = passAttributes & 0xffff;
+ getRange:
+ if (passLine.chars[passLinepos] == pass_until) {
+ passLinepos++;
+ passInstructions[passIC++] = 1;
+ passInstructions[passIC++] = 0xffff;
+ break;
+ }
+ passGetNumber(&passLine, &passLinepos, &passHoldNumber);
+ if (passHoldNumber == 0) {
+ passHoldNumber = passInstructions[passIC++] = 1;
+ passInstructions[passIC++] = 1; /* This is not an error */
+ break;
+ }
+ passInstructions[passIC++] = passHoldNumber;
+ if (passLine.chars[passLinepos] != pass_hyphen) {
+ passInstructions[passIC++] = passHoldNumber;
+ break;
+ }
+ passLinepos++;
+ passGetNumber(&passLine, &passLinepos, &passHoldNumber);
+ if (passHoldNumber == 0) {
+ compileError(passNested, "invalid range");
+ return 0;
+ }
+ passInstructions[passIC++] = passHoldNumber;
+ break;
+ case pass_groupstart:
+ case pass_groupend:
+ passLinepos++;
+ passGetName(&passLine, &passLinepos, &passHoldString);
+ ruleOffset = findRuleName(&passHoldString, *table);
+ if (ruleOffset)
+ rule = (TranslationTableRule *)&(*table)->ruleArea[ruleOffset];
+ if (rule && rule->opcode == CTO_Grouping) {
+ passInstructions[passIC++] = passSubOp;
+ passInstructions[passIC++] = ruleOffset >> 16;
+ passInstructions[passIC++] = ruleOffset & 0xffff;
+ break;
+ } else {
+ compileError(passNested, "%s is not a grouping name",
+ _lou_showString(
+ &passHoldString.chars[0], passHoldString.length, 0));
+ return 0;
+ }
+ break;
+ case pass_swap:
+ passLinepos++;
+ passGetName(&passLine, &passLinepos, &passHoldString);
+ if ((class = findCharacterClass(&passHoldString, *table))) {
+ passAttributes = class->attribute;
+ goto insertAttributes;
+ }
+ ruleOffset = findRuleName(&passHoldString, *table);
+ if (ruleOffset)
+ rule = (TranslationTableRule *)&(*table)->ruleArea[ruleOffset];
+ if (rule &&
+ (rule->opcode == CTO_SwapCc || rule->opcode == CTO_SwapCd ||
+ rule->opcode == CTO_SwapDd)) {
+ passInstructions[passIC++] = pass_swap;
+ passInstructions[passIC++] = ruleOffset >> 16;
+ passInstructions[passIC++] = ruleOffset & 0xffff;
+ goto getRange;
+ }
+ compileError(passNested, "%s is neither a class name nor a swap name.",
+ _lou_showString(&passHoldString.chars[0], passHoldString.length, 0));
+ return 0;
+ case pass_endTest:
+ passInstructions[passIC++] = pass_endTest;
+ passLinepos++;
+ break;
+ default:
+ compileError(passNested, "incorrect operator '%c ' in test part",
+ passLine.chars[passLinepos]);
+ return 0;
+ }
+
+ } /* Compile action part */
+
+ /* Compile action part */
+ while (passLinepos < passLine.length && passLine.chars[passLinepos] <= 32)
+ passLinepos++;
+ while (passLinepos < passLine.length && passLine.chars[passLinepos] > 32) {
+ if (passIC >= MAXSTRING) {
+ compileError(passNested, "Action part in multipass operand too long");
+ return 0;
+ }
+ switch ((passSubOp = passLine.chars[passLinepos])) {
+ case pass_string:
+ if (!verifyStringOrDots(nested, opcode, 1, 1, nofor)) {
+ return 0;
+ }
+ passLinepos++;
+ passInstructions[passIC++] = pass_string;
+ passGetString(&passLine, &passLinepos, &passHoldString, passNested);
+ goto actionDoCharsDots;
+ case pass_dots:
+ if (!verifyStringOrDots(nested, opcode, 0, 1, nofor)) {
+ return 0;
+ }
+ passLinepos++;
+ passGetDots(&passLine, &passLinepos, &passHoldString, passNested);
+ passInstructions[passIC++] = pass_dots;
+ actionDoCharsDots:
+ if (passHoldString.length == 0) return 0;
+ if (passIC >= MAXSTRING) {
+ compileError(passNested,
+ "@ operand in action part of multipass operand too long");
+ return 0;
+ }
+ passInstructions[passIC++] = passHoldString.length;
+ for (kk = 0; kk < passHoldString.length; kk++) {
+ if (passIC >= MAXSTRING) {
+ compileError(passNested,
+ "@ operand in action part of multipass operand too long");
+ return 0;
+ }
+ passInstructions[passIC++] = passHoldString.chars[kk];
+ }
+ break;
+ case pass_variable:
+ passLinepos++;
+ if (!passGetVariableNumber(nested, &passLine, &passLinepos, &passHoldNumber))
+ return 0;
+ switch (passLine.chars[passLinepos]) {
+ case pass_eq:
+ passInstructions[passIC++] = pass_eq;
+ passInstructions[passIC++] = passHoldNumber;
+ passLinepos++;
+ passGetNumber(&passLine, &passLinepos, &passHoldNumber);
+ passInstructions[passIC++] = passHoldNumber;
+ break;
+ case pass_plus:
+ case pass_hyphen:
+ passInstructions[passIC++] = passLine.chars[passLinepos++];
+ passInstructions[passIC++] = passHoldNumber;
+ break;
+ default:
+ compileError(passNested, "incorrect variable operator in action part");
+ return 0;
+ }
+ break;
+ case pass_copy:
+ passInstructions[passIC++] = pass_copy;
+ passLinepos++;
+ break;
+ case pass_omit:
+ passInstructions[passIC++] = pass_omit;
+ passLinepos++;
+ break;
+ case pass_groupreplace:
+ case pass_groupstart:
+ case pass_groupend:
+ passLinepos++;
+ passGetName(&passLine, &passLinepos, &passHoldString);
+ ruleOffset = findRuleName(&passHoldString, *table);
+ if (ruleOffset)
+ rule = (TranslationTableRule *)&(*table)->ruleArea[ruleOffset];
+ if (rule && rule->opcode == CTO_Grouping) {
+ passInstructions[passIC++] = passSubOp;
+ passInstructions[passIC++] = ruleOffset >> 16;
+ passInstructions[passIC++] = ruleOffset & 0xffff;
+ break;
+ }
+ compileError(passNested, "%s is not a grouping name",
+ _lou_showString(&passHoldString.chars[0], passHoldString.length, 0));
+ return 0;
+ case pass_swap:
+ passLinepos++;
+ passGetName(&passLine, &passLinepos, &passHoldString);
+ ruleOffset = findRuleName(&passHoldString, *table);
+ if (ruleOffset)
+ rule = (TranslationTableRule *)&(*table)->ruleArea[ruleOffset];
+ if (rule &&
+ (rule->opcode == CTO_SwapCc || rule->opcode == CTO_SwapCd ||
+ rule->opcode == CTO_SwapDd)) {
+ passInstructions[passIC++] = pass_swap;
+ passInstructions[passIC++] = ruleOffset >> 16;
+ passInstructions[passIC++] = ruleOffset & 0xffff;
+ break;
+ }
+ compileError(passNested, "%s is not a swap name.",
+ _lou_showString(&passHoldString.chars[0], passHoldString.length, 0));
+ return 0;
+ break;
+ default:
+ compileError(passNested, "incorrect operator in action part");
+ return 0;
+ }
+ }
+
+ /* Analyze and add rule */
+ passRuleDots.length = passIC;
+
+ {
+ widechar *characters;
+ int length;
+ int found = passFindCharacters(
+ passNested, passInstructions, passRuleDots.length, &characters, &length);
+
+ if (!found) return 0;
+
+ if (characters) {
+ for (k = 0; k < length; k += 1) passRuleChars.chars[k] = characters[k];
+ passRuleChars.length = k;
+ }
+ }
+
+ if (!addRule(passNested, opcode, &passRuleChars, &passRuleDots, 0, 0, newRuleOffset,
+ newRule, noback, nofor, table))
+ return 0;
+ return 1;
+}
+
+/* End of multipass compiler */
+
+static int
+compileBrailleIndicator(FileInfo *nested, const char *ermsg,
+ TranslationTableOpcode opcode, int *lastToken,
+ TranslationTableOffset *newRuleOffset, TranslationTableRule **newRule, int noback,
+ int nofor, TranslationTableHeader **table) {
+ CharsString token;
+ CharsString cells;
+ if (getToken(nested, &token, ermsg, lastToken))
+ if (parseDots(nested, &cells, &token))
+ if (!addRule(nested, opcode, NULL, &cells, 0, 0, newRuleOffset, newRule,
+ noback, nofor, table))
+ return 0;
+ return 1;
+}
+
+static int
+compileNumber(FileInfo *nested, int *lastToken) {
+ CharsString token;
+ widechar dest;
+ if (!getToken(nested, &token, "number", lastToken)) return 0;
+ getNumber(&token.chars[0], &dest);
+ if (!(dest > 0)) {
+ compileError(nested, "a nonzero positive number is required");
+ return 0;
+ }
+ return dest;
+}
+
+static int
+compileGrouping(FileInfo *nested, int *lastToken, TranslationTableOffset *newRuleOffset,
+ TranslationTableRule **newRule, int noback, int nofor,
+ TranslationTableHeader **table, DisplayTableHeader **displayTable) {
+ int k;
+ CharsString name;
+ CharsString groupChars;
+ CharsString groupDots;
+ CharsString dotsParsed;
+ if (!getToken(nested, &name, "name operand", lastToken)) return 0;
+ if (!getRuleCharsText(nested, &groupChars, lastToken)) return 0;
+ if (!getToken(nested, &groupDots, "dots operand", lastToken)) return 0;
+ for (k = 0; k < groupDots.length && groupDots.chars[k] != ','; k++)
+ ;
+ if (k == groupDots.length) {
+ compileError(
+ nested, "Dots operand must consist of two cells separated by a comma");
+ return 0;
+ }
+ groupDots.chars[k] = '-';
+ if (!parseDots(nested, &dotsParsed, &groupDots)) return 0;
+ if (groupChars.length != 2 || dotsParsed.length != 2) {
+ compileError(nested,
+ "two Unicode characters and two cells separated by a comma are needed.");
+ return 0;
+ }
+ if (table) {
+ TranslationTableOffset ruleOffset;
+ TranslationTableCharacter *charsDotsPtr;
+ charsDotsPtr = addCharOrDots(nested, groupChars.chars[0], 0, table);
+ charsDotsPtr->attributes |= CTC_Math;
+ charsDotsPtr->uppercase = charsDotsPtr->realchar;
+ charsDotsPtr->lowercase = charsDotsPtr->realchar;
+ charsDotsPtr = addCharOrDots(nested, groupChars.chars[1], 0, table);
+ charsDotsPtr->attributes |= CTC_Math;
+ charsDotsPtr->uppercase = charsDotsPtr->realchar;
+ charsDotsPtr->lowercase = charsDotsPtr->realchar;
+ charsDotsPtr = addCharOrDots(nested, dotsParsed.chars[0], 1, table);
+ charsDotsPtr->attributes |= CTC_Math;
+ charsDotsPtr->uppercase = charsDotsPtr->realchar;
+ charsDotsPtr->lowercase = charsDotsPtr->realchar;
+ charsDotsPtr = addCharOrDots(nested, dotsParsed.chars[1], 1, table);
+ charsDotsPtr->attributes |= CTC_Math;
+ charsDotsPtr->uppercase = charsDotsPtr->realchar;
+ charsDotsPtr->lowercase = charsDotsPtr->realchar;
+ if (!addRule(nested, CTO_Grouping, &groupChars, &dotsParsed, 0, 0, &ruleOffset,
+ newRule, noback, nofor, table))
+ return 0;
+ if (!addRuleName(nested, &name, ruleOffset, *table)) return 0;
+ if (newRuleOffset) *newRuleOffset = ruleOffset;
+ }
+ if (displayTable) {
+ putCharAndDots(nested, groupChars.chars[0], dotsParsed.chars[0], displayTable);
+ putCharAndDots(nested, groupChars.chars[1], dotsParsed.chars[1], displayTable);
+ }
+ if (table) {
+ widechar endChar;
+ widechar endDots;
+ endChar = groupChars.chars[1];
+ endDots = dotsParsed.chars[1];
+ groupChars.length = dotsParsed.length = 1;
+ if (!addRule(nested, CTO_Math, &groupChars, &dotsParsed, 0, 0, newRuleOffset,
+ newRule, noback, nofor, table))
+ return 0;
+ groupChars.chars[0] = endChar;
+ dotsParsed.chars[0] = endDots;
+ if (!addRule(nested, CTO_Math, &groupChars, &dotsParsed, 0, 0, newRuleOffset,
+ newRule, noback, nofor, table))
+ return 0;
+ }
+ return 1;
+}
+
+static int
+compileUplow(FileInfo *nested, int *lastToken, TranslationTableOffset *newRuleOffset,
+ TranslationTableRule **newRule, int noback, int nofor,
+ TranslationTableHeader **table, DisplayTableHeader **displayTable) {
+ int k;
+ TranslationTableCharacter *upperChar;
+ TranslationTableCharacter *lowerChar;
+ TranslationTableCharacter *upperCell = NULL;
+ TranslationTableCharacter *lowerCell = NULL;
+ CharsString ruleChars;
+ CharsString ruleDots;
+ CharsString upperDots;
+ CharsString lowerDots;
+ int haveLowerDots = 0;
+ TranslationTableCharacterAttributes attr;
+ if (!getRuleCharsText(nested, &ruleChars, lastToken)) return 0;
+ if (!getToken(nested, &ruleDots, "dots operand", lastToken)) return 0;
+ for (k = 0; k < ruleDots.length && ruleDots.chars[k] != ','; k++)
+ ;
+ if (k == ruleDots.length) {
+ if (!parseDots(nested, &upperDots, &ruleDots)) return 0;
+ lowerDots.length = upperDots.length;
+ for (k = 0; k < upperDots.length; k++) lowerDots.chars[k] = upperDots.chars[k];
+ lowerDots.chars[k] = 0;
+ } else {
+ haveLowerDots = ruleDots.length;
+ ruleDots.length = k;
+ if (!parseDots(nested, &upperDots, &ruleDots)) return 0;
+ ruleDots.length = 0;
+ k++;
+ for (; k < haveLowerDots; k++)
+ ruleDots.chars[ruleDots.length++] = ruleDots.chars[k];
+ if (!parseDots(nested, &lowerDots, &ruleDots)) return 0;
+ }
+ if (ruleChars.length != 2 || upperDots.length < 1) {
+ compileError(nested,
+ "Exactly two Unicode characters and at least one cell are required.");
+ return 0;
+ }
+ if (haveLowerDots && lowerDots.length < 1) {
+ compileError(nested, "at least one cell is required after the comma.");
+ return 0;
+ }
+ if (table) {
+ upperChar = addCharOrDots(nested, ruleChars.chars[0], 0, table);
+ upperChar->attributes |= CTC_Letter | CTC_UpperCase;
+ upperChar->uppercase = ruleChars.chars[0];
+ upperChar->lowercase = ruleChars.chars[1];
+ lowerChar = addCharOrDots(nested, ruleChars.chars[1], 0, table);
+ lowerChar->attributes |= CTC_Letter | CTC_LowerCase;
+ lowerChar->uppercase = ruleChars.chars[0];
+ lowerChar->lowercase = ruleChars.chars[1];
+ for (k = 0; k < upperDots.length; k++)
+ if (!compile_findCharOrDots(upperDots.chars[k], 1, *table)) {
+ attr = CTC_Letter | CTC_UpperCase;
+ upperCell = addCharOrDots(nested, upperDots.chars[k], 1, table);
+ upperCell->attributes |= attr;
+ upperCell->uppercase = upperCell->realchar;
+ }
+ if (haveLowerDots) {
+ for (k = 0; k < lowerDots.length; k++)
+ if (!compile_findCharOrDots(lowerDots.chars[k], 1, *table)) {
+ attr = CTC_Letter | CTC_LowerCase;
+ lowerCell = addCharOrDots(nested, lowerDots.chars[k], 1, table);
+ if (lowerDots.length != 1) attr = CTC_Space;
+ lowerCell->attributes |= attr;
+ lowerCell->lowercase = lowerCell->realchar;
+ }
+ } else if (upperCell != NULL && upperDots.length == 1)
+ upperCell->attributes |= CTC_LowerCase;
+ if (upperCell != NULL) upperCell->lowercase = lowerDots.chars[0];
+ if (lowerCell != NULL) lowerCell->uppercase = upperDots.chars[0];
+ }
+ if (displayTable) {
+ if (lowerDots.length == 1)
+ putCharAndDots(nested, ruleChars.chars[1], lowerDots.chars[0], displayTable);
+ if (upperDots.length == 1)
+ putCharAndDots(nested, ruleChars.chars[0], upperDots.chars[0], displayTable);
+ }
+ if (table) {
+ ruleChars.length = 1;
+ ruleChars.chars[2] = ruleChars.chars[0];
+ ruleChars.chars[0] = ruleChars.chars[1];
+ if (!addRule(nested, CTO_LowerCase, &ruleChars, &lowerDots, 0, 0, newRuleOffset,
+ newRule, noback, nofor, table))
+ return 0;
+ ruleChars.chars[0] = ruleChars.chars[2];
+ if (!addRule(nested, CTO_UpperCase, &ruleChars, &upperDots, 0, 0, newRuleOffset,
+ newRule, noback, nofor, table))
+ return 0;
+ }
+ return 1;
+}
+
+/* Functions for compiling hyphenation tables */
+
+typedef struct HyphenDict { /* hyphenation dictionary: finite state machine */
+ int numStates;
+ HyphenationState *states;
+} HyphenDict;
+
+#define DEFAULTSTATE 0xffff
+#define HYPHENHASHSIZE 8191
+
+typedef struct HyphenHashEntry {
+ struct HyphenHashEntry *next;
+ CharsString *key;
+ int val;
+} HyphenHashEntry;
+
+typedef struct HyphenHashTab {
+ HyphenHashEntry *entries[HYPHENHASHSIZE];
+} HyphenHashTab;
+
+/* a hash function from ASU - adapted from Gtk+ */
+static unsigned int
+hyphenStringHash(const CharsString *s) {
+ int k;
+ unsigned int h = 0, g;
+ for (k = 0; k < s->length; k++) {
+ h = (h << 4) + s->chars[k];
+ if ((g = h & 0xf0000000)) {
+ h = h ^ (g >> 24);
+ h = h ^ g;
+ }
+ }
+ return h;
+}
+
+static HyphenHashTab *
+hyphenHashNew(void) {
+ HyphenHashTab *hashTab;
+ if (!(hashTab = malloc(sizeof(HyphenHashTab)))) _lou_outOfMemory();
+ memset(hashTab, 0, sizeof(HyphenHashTab));
+ return hashTab;
+}
+
+static void
+hyphenHashFree(HyphenHashTab *hashTab) {
+ int i;
+ HyphenHashEntry *e, *next;
+ for (i = 0; i < HYPHENHASHSIZE; i++)
+ for (e = hashTab->entries[i]; e; e = next) {
+ next = e->next;
+ free(e->key);
+ free(e);
+ }
+ free(hashTab);
+}
+
+/* assumes that key is not already present! */
+static void
+hyphenHashInsert(HyphenHashTab *hashTab, const CharsString *key, int val) {
+ int i, j;
+ HyphenHashEntry *e;
+ i = hyphenStringHash(key) % HYPHENHASHSIZE;
+ if (!(e = malloc(sizeof(HyphenHashEntry)))) _lou_outOfMemory();
+ e->next = hashTab->entries[i];
+ e->key = malloc((key->length + 1) * CHARSIZE);
+ if (!e->key) _lou_outOfMemory();
+ e->key->length = key->length;
+ for (j = 0; j < key->length; j++) e->key->chars[j] = key->chars[j];
+ e->val = val;
+ hashTab->entries[i] = e;
+}
+
+/* return val if found, otherwise DEFAULTSTATE */
+static int
+hyphenHashLookup(HyphenHashTab *hashTab, const CharsString *key) {
+ int i, j;
+ HyphenHashEntry *e;
+ if (key->length == 0) return 0;
+ i = hyphenStringHash(key) % HYPHENHASHSIZE;
+ for (e = hashTab->entries[i]; e; e = e->next) {
+ if (key->length != e->key->length) continue;
+ for (j = 0; j < key->length; j++)
+ if (key->chars[j] != e->key->chars[j]) break;
+ if (j == key->length) return e->val;
+ }
+ return DEFAULTSTATE;
+}
+
+static int
+hyphenGetNewState(HyphenDict *dict, HyphenHashTab *hashTab, const CharsString *string) {
+ hyphenHashInsert(hashTab, string, dict->numStates);
+ /* predicate is true if dict->numStates is a power of two */
+ if (!(dict->numStates & (dict->numStates - 1)))
+ dict->states =
+ realloc(dict->states, (dict->numStates << 1) * sizeof(HyphenationState));
+ if (!dict->states) _lou_outOfMemory();
+ dict->states[dict->numStates].hyphenPattern = 0;
+ dict->states[dict->numStates].fallbackState = DEFAULTSTATE;
+ dict->states[dict->numStates].numTrans = 0;
+ dict->states[dict->numStates].trans.pointer = NULL;
+ return dict->numStates++;
+}
+
+/* add a transition from state1 to state2 through ch - assumes that the
+ * transition does not already exist */
+static void
+hyphenAddTrans(HyphenDict *dict, int state1, int state2, widechar ch) {
+ int numTrans;
+ numTrans = dict->states[state1].numTrans;
+ if (numTrans == 0)
+ dict->states[state1].trans.pointer = malloc(sizeof(HyphenationTrans));
+ else if (!(numTrans & (numTrans - 1)))
+ dict->states[state1].trans.pointer = realloc(dict->states[state1].trans.pointer,
+ (numTrans << 1) * sizeof(HyphenationTrans));
+ dict->states[state1].trans.pointer[numTrans].ch = ch;
+ dict->states[state1].trans.pointer[numTrans].newState = state2;
+ dict->states[state1].numTrans++;
+}
+
+static int
+compileHyphenation(FileInfo *nested, CharsString *encoding, int *lastToken,
+ TranslationTableHeader **table) {
+ CharsString hyph;
+ HyphenationTrans *holdPointer;
+ HyphenHashTab *hashTab;
+ CharsString word;
+ char pattern[MAXSTRING + 1];
+ unsigned int stateNum = 0, lastState = 0;
+ int i, j, k = encoding->length;
+ widechar ch;
+ int found;
+ HyphenHashEntry *e;
+ HyphenDict dict;
+ TranslationTableOffset holdOffset;
+ /* Set aside enough space for hyphenation states and transitions in
+ * translation table. Must be done before anything else */
+ allocateSpaceInTranslationTable(nested, NULL, 250000, table);
+ hashTab = hyphenHashNew();
+ dict.numStates = 1;
+ dict.states = malloc(sizeof(HyphenationState));
+ if (!dict.states) _lou_outOfMemory();
+ dict.states[0].hyphenPattern = 0;
+ dict.states[0].fallbackState = DEFAULTSTATE;
+ dict.states[0].numTrans = 0;
+ dict.states[0].trans.pointer = NULL;
+ do {
+ if (encoding->chars[0] == 'I') {
+ if (!getToken(nested, &hyph, NULL, lastToken)) continue;
+ } else {
+ /* UTF-8 */
+ if (!getToken(nested, &word, NULL, lastToken)) continue;
+ parseChars(nested, &hyph, &word);
+ }
+ if (hyph.length == 0 || hyph.chars[0] == '#' || hyph.chars[0] == '%' ||
+ hyph.chars[0] == '<')
+ continue; /* comment */
+ j = 0;
+ pattern[j] = '0';
+ for (i = 0; i < hyph.length; i++) {
+ if (hyph.chars[i] >= '0' && hyph.chars[i] <= '9')
+ pattern[j] = (char)hyph.chars[i];
+ else {
+ word.chars[j] = hyph.chars[i];
+ pattern[++j] = '0';
+ }
+ }
+ word.chars[j] = 0;
+ word.length = j;
+ pattern[j + 1] = 0;
+ for (i = 0; pattern[i] == '0'; i++)
+ ;
+ found = hyphenHashLookup(hashTab, &word);
+ if (found != DEFAULTSTATE)
+ stateNum = found;
+ else
+ stateNum = hyphenGetNewState(&dict, hashTab, &word);
+ k = j + 2 - i;
+ if (k > 0) {
+ allocateSpaceInTranslationTable(
+ nested, &dict.states[stateNum].hyphenPattern, k, table);
+ memcpy(&(*table)->ruleArea[dict.states[stateNum].hyphenPattern], &pattern[i],
+ k);
+ }
+ /* now, put in the prefix transitions */
+ while (found == DEFAULTSTATE) {
+ lastState = stateNum;
+ ch = word.chars[word.length-- - 1];
+ found = hyphenHashLookup(hashTab, &word);
+ if (found != DEFAULTSTATE)
+ stateNum = found;
+ else
+ stateNum = hyphenGetNewState(&dict, hashTab, &word);
+ hyphenAddTrans(&dict, stateNum, lastState, ch);
+ }
+ } while (_lou_getALine(nested));
+ /* put in the fallback states */
+ for (i = 0; i < HYPHENHASHSIZE; i++) {
+ for (e = hashTab->entries[i]; e; e = e->next) {
+ for (j = 1; j <= e->key->length; j++) {
+ word.length = 0;
+ for (k = j; k < e->key->length; k++)
+ word.chars[word.length++] = e->key->chars[k];
+ stateNum = hyphenHashLookup(hashTab, &word);
+ if (stateNum != DEFAULTSTATE) break;
+ }
+ if (e->val) dict.states[e->val].fallbackState = stateNum;
+ }
+ }
+ hyphenHashFree(hashTab);
+ /* Transfer hyphenation information to table */
+ for (i = 0; i < dict.numStates; i++) {
+ if (dict.states[i].numTrans == 0)
+ dict.states[i].trans.offset = 0;
+ else {
+ holdPointer = dict.states[i].trans.pointer;
+ allocateSpaceInTranslationTable(nested, &dict.states[i].trans.offset,
+ dict.states[i].numTrans * sizeof(HyphenationTrans), table);
+ memcpy(&(*table)->ruleArea[dict.states[i].trans.offset], holdPointer,
+ dict.states[i].numTrans * sizeof(HyphenationTrans));
+ free(holdPointer);
+ }
+ }
+ allocateSpaceInTranslationTable(
+ nested, &holdOffset, dict.numStates * sizeof(HyphenationState), table);
+ (*table)->hyphenStatesArray = holdOffset;
+ /* Prevents segmentation fault if table is reallocated */
+ memcpy(&(*table)->ruleArea[(*table)->hyphenStatesArray], &dict.states[0],
+ dict.numStates * sizeof(HyphenationState));
+ free(dict.states);
+ return 1;
+}
+
+static int
+compileCharDef(FileInfo *nested, TranslationTableOpcode opcode,
+ TranslationTableCharacterAttributes attributes, int *lastToken,
+ TranslationTableOffset *newRuleOffset, TranslationTableRule **newRule, int noback,
+ int nofor, TranslationTableHeader **table, DisplayTableHeader **displayTable) {
+ CharsString ruleChars;
+ CharsString ruleDots;
+ if (!getRuleCharsText(nested, &ruleChars, lastToken)) return 0;
+ if (!getRuleDotsPattern(nested, &ruleDots, lastToken)) return 0;
+ if (ruleChars.length != 1) {
+ compileError(nested, "Exactly one character is required.");
+ return 0;
+ }
+ if (ruleDots.length < 1) {
+ compileError(nested, "At least one cell is required.");
+ return 0;
+ }
+ if (table) {
+ TranslationTableCharacter *character;
+ TranslationTableCharacter *cell = NULL;
+ int k;
+ if (attributes & (CTC_UpperCase | CTC_LowerCase)) attributes |= CTC_Letter;
+ character = addCharOrDots(nested, ruleChars.chars[0], 0, table);
+ character->attributes |= attributes;
+ character->uppercase = character->lowercase = character->realchar;
+ for (k = ruleDots.length - 1; k >= 0; k -= 1) {
+ cell = compile_findCharOrDots(ruleDots.chars[k], 1, *table);
+ if (!cell) {
+ cell = addCharOrDots(nested, ruleDots.chars[k], 1, table);
+ cell->uppercase = cell->lowercase = cell->realchar;
+ }
+ }
+ if (ruleDots.length == 1) cell->attributes |= attributes;
+ }
+ if (displayTable && ruleDots.length == 1)
+ putCharAndDots(nested, ruleChars.chars[0], ruleDots.chars[0], displayTable);
+ if (table)
+ if (!addRule(nested, opcode, &ruleChars, &ruleDots, 0, 0, newRuleOffset, newRule,
+ noback, nofor, table))
+ return 0;
+ return 1;
+}
+
+static int
+compileBeforeAfter(FileInfo *nested, int *lastToken) {
+ /* 1=before, 2=after, 0=error */
+ CharsString token;
+ CharsString tmp;
+ if (getToken(nested, &token, "last word before or after", lastToken))
+ if (parseChars(nested, &tmp, &token)) {
+ if (eqasc2uni((unsigned char *)"before", tmp.chars, 6)) return 1;
+ if (eqasc2uni((unsigned char *)"after", tmp.chars, 5)) return 2;
+ }
+ return 0;
+}
+
+static int
+compileRule(FileInfo *nested, TranslationTableOffset *newRuleOffset,
+ TranslationTableRule **newRule, TranslationTableHeader **table,
+ DisplayTableHeader **displayTable) {
+ int lastToken = 0;
+ int ok = 1;
+ CharsString token;
+ TranslationTableOpcode opcode;
+ CharsString ruleChars;
+ CharsString ruleDots;
+ CharsString cells;
+ CharsString scratchPad;
+ CharsString emphClass;
+ TranslationTableCharacterAttributes after = 0;
+ TranslationTableCharacterAttributes before = 0;
+ TranslationTableCharacter *c = NULL;
+ widechar *patterns = NULL;
+ int k, i;
+ int noback, nofor;
+ noback = nofor = 0;
+doOpcode:
+ if (!getToken(nested, &token, NULL, &lastToken)) return 1; /* blank line */
+ if (token.chars[0] == '#' || token.chars[0] == '<') return 1; /* comment */
+ if (nested->lineNumber == 1 &&
+ (eqasc2uni((unsigned char *)"ISO", token.chars, 3) ||
+ eqasc2uni((unsigned char *)"UTF-8", token.chars, 5))) {
+ if (table)
+ compileHyphenation(nested, &token, &lastToken, table);
+ else
+ /* ignore the whole file */
+ while (_lou_getALine(nested))
+ ;
+ return 1;
+ }
+ opcode = getOpcode(nested, &token);
+ switch (opcode) {
+ case CTO_IncludeFile: {
+ CharsString includedFile;
+ if (getToken(nested, &token, "include file name", &lastToken))
+ if (parseChars(nested, &includedFile, &token))
+ if (!includeFile(nested, &includedFile, table, displayTable)) ok = 0;
+ break;
+ }
+ case CTO_NoBack:
+ if (nofor) {
+ compileError(nested, "%s already specified.", _lou_findOpcodeName(CTO_NoFor));
+ ok = 0;
+ break;
+ }
+ noback = 1;
+ goto doOpcode;
+ case CTO_NoFor:
+ if (noback) {
+ compileError(
+ nested, "%s already specified.", _lou_findOpcodeName(CTO_NoBack));
+ ok = 0;
+ break;
+ }
+ nofor = 1;
+ goto doOpcode;
+ case CTO_Space:
+ compileCharDef(nested, opcode, CTC_Space, &lastToken, newRuleOffset, newRule,
+ noback, nofor, table, displayTable);
+ break;
+ case CTO_Digit:
+ compileCharDef(nested, opcode, CTC_Digit, &lastToken, newRuleOffset, newRule,
+ noback, nofor, table, displayTable);
+ break;
+ case CTO_LitDigit:
+ compileCharDef(nested, opcode, CTC_LitDigit, &lastToken, newRuleOffset, newRule,
+ noback, nofor, table, displayTable);
+ break;
+ case CTO_Punctuation:
+ compileCharDef(nested, opcode, CTC_Punctuation, &lastToken, newRuleOffset,
+ newRule, noback, nofor, table, displayTable);
+ break;
+ case CTO_Math:
+ compileCharDef(nested, opcode, CTC_Math, &lastToken, newRuleOffset, newRule,
+ noback, nofor, table, displayTable);
+ break;
+ case CTO_Sign:
+ compileCharDef(nested, opcode, CTC_Sign, &lastToken, newRuleOffset, newRule,
+ noback, nofor, table, displayTable);
+ break;
+ case CTO_Letter:
+ compileCharDef(nested, opcode, CTC_Letter, &lastToken, newRuleOffset, newRule,
+ noback, nofor, table, displayTable);
+ break;
+ case CTO_UpperCase:
+ compileCharDef(nested, opcode, CTC_UpperCase, &lastToken, newRuleOffset, newRule,
+ noback, nofor, table, displayTable);
+ break;
+ case CTO_LowerCase:
+ compileCharDef(nested, opcode, CTC_LowerCase, &lastToken, newRuleOffset, newRule,
+ noback, nofor, table, displayTable);
+ break;
+ case CTO_Grouping:
+ ok = compileGrouping(nested, &lastToken, newRuleOffset, newRule, noback, nofor,
+ table, displayTable);
+ break;
+ case CTO_UpLow:
+ ok = compileUplow(nested, &lastToken, newRuleOffset, newRule, noback, nofor,
+ table, displayTable);
+ break;
+ case CTO_Display:
+ if (!displayTable) break;
+ if (getRuleCharsText(nested, &ruleChars, &lastToken))
+ if (getRuleDotsPattern(nested, &ruleDots, &lastToken)) {
+ if (ruleChars.length != 1 || ruleDots.length != 1) {
+ compileError(
+ nested, "Exactly one character and one cell are required.");
+ ok = 0;
+ }
+ putCharAndDots(
+ nested, ruleChars.chars[0], ruleDots.chars[0], displayTable);
+ }
+ break;
+ /* now only opcodes follow that don't modify the display table */
+ default:
+ if (!table) break;
+ switch (opcode) {
+ case CTO_None:
+ break;
+ case CTO_Locale:
+ compileWarning(nested,
+ "The locale opcode is not implemented. Use the locale meta data "
+ "instead.");
+ break;
+ case CTO_Undefined: {
+ // not passing pointer because compileBrailleIndicator may reallocate table
+ TranslationTableOffset ruleOffset = (*table)->undefined;
+ ok = compileBrailleIndicator(nested, "undefined character opcode",
+ CTO_Undefined, &lastToken, &ruleOffset, newRule, noback, nofor,
+ table);
+ (*table)->undefined = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_Match: {
+ TranslationTableRule *rule;
+ TranslationTableOffset ruleOffset;
+ CharsString ptn_before, ptn_after;
+ TranslationTableOffset patternsOffset;
+ int len, mrk;
+
+ size_t patternsByteSize = sizeof(*patterns) * 27720;
+ patterns = (widechar *)malloc(patternsByteSize);
+ if (!patterns) _lou_outOfMemory();
+ memset(patterns, 0xffff, patternsByteSize);
+
+ noback = 1;
+ getCharacters(nested, &ptn_before, &lastToken);
+ getRuleCharsText(nested, &ruleChars, &lastToken);
+ getCharacters(nested, &ptn_after, &lastToken);
+ getRuleDotsPattern(nested, &ruleDots, &lastToken);
+
+ if (!addRule(nested, opcode, &ruleChars, &ruleDots, after, before,
+ &ruleOffset, &rule, noback, nofor, table)) {
+ ok = 0;
+ break;
+ }
+ if (ptn_before.chars[0] == '-' && ptn_before.length == 1)
+ len = _lou_pattern_compile(
+ &ptn_before.chars[0], 0, &patterns[1], 13841, *table);
+ else
+ len = _lou_pattern_compile(&ptn_before.chars[0], ptn_before.length,
+ &patterns[1], 13841, *table);
+ if (!len) {
+ ok = 0;
+ break;
+ }
+ mrk = patterns[0] = len + 1;
+ _lou_pattern_reverse(&patterns[1]);
+
+ if (ptn_after.chars[0] == '-' && ptn_after.length == 1)
+ len = _lou_pattern_compile(
+ &ptn_after.chars[0], 0, &patterns[mrk], 13841, *table);
+ else
+ len = _lou_pattern_compile(&ptn_after.chars[0], ptn_after.length,
+ &patterns[mrk], 13841, *table);
+ if (!len) {
+ ok = 0;
+ break;
+ }
+ len += mrk;
+
+ if (!allocateSpaceInTranslationTable(
+ nested, &patternsOffset, len * sizeof(widechar), table)) {
+ ok = 0;
+ break;
+ }
+
+ /* realloc may have moved table, so make sure rule is still valid */
+ rule = (TranslationTableRule *)&(*table)->ruleArea[ruleOffset];
+ memcpy(&(*table)->ruleArea[patternsOffset], patterns, len * sizeof(widechar));
+ rule->patterns = patternsOffset;
+
+ if (newRule) *newRule = rule;
+ if (newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+
+ case CTO_BackMatch: {
+ TranslationTableRule *rule;
+ TranslationTableOffset ruleOffset;
+ CharsString ptn_before, ptn_after;
+ TranslationTableOffset patternOffset;
+ int len, mrk;
+
+ size_t patternsByteSize = sizeof(*patterns) * 27720;
+ patterns = (widechar *)malloc(patternsByteSize);
+ if (!patterns) _lou_outOfMemory();
+ memset(patterns, 0xffff, patternsByteSize);
+
+ nofor = 1;
+ getCharacters(nested, &ptn_before, &lastToken);
+ getRuleCharsText(nested, &ruleChars, &lastToken);
+ getCharacters(nested, &ptn_after, &lastToken);
+ getRuleDotsPattern(nested, &ruleDots, &lastToken);
+
+ if (!addRule(nested, opcode, &ruleChars, &ruleDots, 0, 0, &ruleOffset, &rule,
+ noback, nofor, table)) {
+ ok = 0;
+ break;
+ }
+ if (ptn_before.chars[0] == '-' && ptn_before.length == 1)
+ len = _lou_pattern_compile(
+ &ptn_before.chars[0], 0, &patterns[1], 13841, *table);
+ else
+ len = _lou_pattern_compile(&ptn_before.chars[0], ptn_before.length,
+ &patterns[1], 13841, *table);
+ if (!len) {
+ ok = 0;
+ break;
+ }
+ mrk = patterns[0] = len + 1;
+ _lou_pattern_reverse(&patterns[1]);
+
+ if (ptn_after.chars[0] == '-' && ptn_after.length == 1)
+ len = _lou_pattern_compile(
+ &ptn_after.chars[0], 0, &patterns[mrk], 13841, *table);
+ else
+ len = _lou_pattern_compile(&ptn_after.chars[0], ptn_after.length,
+ &patterns[mrk], 13841, *table);
+ if (!len) {
+ ok = 0;
+ break;
+ }
+ len += mrk;
+
+ if (!allocateSpaceInTranslationTable(
+ nested, &patternOffset, len * sizeof(widechar), table)) {
+ ok = 0;
+ break;
+ }
+
+ /* realloc may have moved table, so make sure rule is still valid */
+ rule = (TranslationTableRule *)&(*table)->ruleArea[ruleOffset];
+
+ memcpy(&(*table)->ruleArea[patternOffset], patterns, len * sizeof(widechar));
+ rule->patterns = patternOffset;
+
+ if (newRule) *newRule = rule;
+ if (newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+
+ case CTO_BegCapsPhrase: {
+ // not passing pointer because compileBrailleIndicator may reallocate table
+ TranslationTableOffset ruleOffset =
+ (*table)->emphRules[capsRule][begPhraseOffset];
+ ok = compileBrailleIndicator(nested, "first word capital sign",
+ CTO_BegCapsPhraseRule, &lastToken, &ruleOffset, newRule, noback,
+ nofor, table);
+ (*table)->emphRules[capsRule][begPhraseOffset] = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_EndCapsPhrase: {
+ TranslationTableOffset ruleOffset;
+ switch (compileBeforeAfter(nested, &lastToken)) {
+ case 1: // before
+ if ((*table)->emphRules[capsRule][endPhraseAfterOffset]) {
+ compileError(nested, "Capital sign after last word already defined.");
+ ok = 0;
+ break;
+ }
+ // not passing pointer because compileBrailleIndicator may reallocate
+ // table
+ ruleOffset = (*table)->emphRules[capsRule][endPhraseBeforeOffset];
+ ok = compileBrailleIndicator(nested, "capital sign before last word",
+ CTO_EndCapsPhraseBeforeRule, &lastToken, &ruleOffset, newRule,
+ noback, nofor, table);
+ (*table)->emphRules[capsRule][endPhraseBeforeOffset] = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ case 2: // after
+ if ((*table)->emphRules[capsRule][endPhraseBeforeOffset]) {
+ compileError(
+ nested, "Capital sign before last word already defined.");
+ ok = 0;
+ break;
+ }
+ // not passing pointer because compileBrailleIndicator may reallocate
+ // table
+ ruleOffset = (*table)->emphRules[capsRule][endPhraseAfterOffset];
+ ok = compileBrailleIndicator(nested, "capital sign after last word",
+ CTO_EndCapsPhraseAfterRule, &lastToken, &ruleOffset, newRule,
+ noback, nofor, table);
+ (*table)->emphRules[capsRule][endPhraseAfterOffset] = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ default: // error
+ compileError(nested, "Invalid lastword indicator location.");
+ ok = 0;
+ break;
+ }
+ break;
+ }
+ case CTO_BegCaps: {
+ // not passing pointer because compileBrailleIndicator may reallocate table
+ TranslationTableOffset ruleOffset = (*table)->emphRules[capsRule][begOffset];
+ ok = compileBrailleIndicator(nested, "first letter capital sign",
+ CTO_BegCapsRule, &lastToken, &ruleOffset, newRule, noback, nofor,
+ table);
+ (*table)->emphRules[capsRule][begOffset] = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_EndCaps: {
+ // not passing pointer because compileBrailleIndicator may reallocate table
+ TranslationTableOffset ruleOffset = (*table)->emphRules[capsRule][endOffset];
+ ok = compileBrailleIndicator(nested, "last letter capital sign",
+ CTO_EndCapsRule, &lastToken, &ruleOffset, newRule, noback, nofor,
+ table);
+ (*table)->emphRules[capsRule][endOffset] = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_CapsLetter: {
+ // not passing pointer because compileBrailleIndicator may reallocate table
+ TranslationTableOffset ruleOffset =
+ (*table)->emphRules[capsRule][letterOffset];
+ ok = compileBrailleIndicator(nested, "single letter capital sign",
+ CTO_CapsLetterRule, &lastToken, &ruleOffset, newRule, noback, nofor,
+ table);
+ (*table)->emphRules[capsRule][letterOffset] = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_BegCapsWord: {
+ // not passing pointer because compileBrailleIndicator may reallocate table
+ TranslationTableOffset ruleOffset =
+ (*table)->emphRules[capsRule][begWordOffset];
+ ok = compileBrailleIndicator(nested, "capital word", CTO_BegCapsWordRule,
+ &lastToken, &ruleOffset, newRule, noback, nofor, table);
+ (*table)->emphRules[capsRule][begWordOffset] = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_EndCapsWord: {
+ // not passing pointer because compileBrailleIndicator may reallocate table
+ TranslationTableOffset ruleOffset =
+ (*table)->emphRules[capsRule][endWordOffset];
+ ok = compileBrailleIndicator(nested, "capital word stop", CTO_EndCapsWordRule,
+ &lastToken, &ruleOffset, newRule, noback, nofor, table);
+ (*table)->emphRules[capsRule][endWordOffset] = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_LenCapsPhrase:
+ ok = (*table)->emphRules[capsRule][lenPhraseOffset] =
+ compileNumber(nested, &lastToken);
+ break;
+
+ /* these 9 general purpose emphasis opcodes are compiled further down to more
+ * specific internal opcodes:
+ * - emphletter
+ * - begemphword
+ * - endemphword
+ * - begemph
+ * - endemph
+ * - begemphphrase
+ * - endemphphrase
+ * - lenemphphrase
+ */
+ case CTO_EmphClass:
+ if (getToken(nested, &token, "emphasis class", &lastToken))
+ if (parseChars(nested, &emphClass, &token)) {
+ char *s = malloc(sizeof(char) * (emphClass.length + 1));
+ for (k = 0; k < emphClass.length; k++)
+ s[k] = (char)emphClass.chars[k];
+ s[k++] = '\0';
+ for (i = 0; (*table)->emphClasses[i]; i++)
+ if (strcmp(s, (*table)->emphClasses[i]) == 0) {
+ _lou_logMessage(
+ LOU_LOG_WARN, "Duplicate emphasis class: %s", s);
+ warningCount++;
+ free(s);
+ return 1;
+ }
+ if (i < MAX_EMPH_CLASSES) {
+ switch (i) {
+ /* For backwards compatibility (i.e. because programs will assume
+ * the first 3 typeform bits are `italic', `underline' and `bold')
+ * we require that the first 3 emphclass definitions are (in that
+ * order):
+ *
+ * emphclass italic
+ * emphclass underline
+ * emphclass bold
+ *
+ * While it would be possible to use the emphclass opcode only for
+ * defining
+ * _additional_ classes (not allowing for them to be called
+ * italic, underline or bold), thereby reducing the amount of
+ * boilerplate, we deliberately choose not to do that in order to
+ * not give italic, underline and bold any special status. The
+ * hope is that eventually all programs will use liblouis for
+ * emphasis the recommended way (i.e. by looking up the supported
+ * typeforms in
+ * the documentation or API) so that we can drop this restriction.
+ */
+ case 0:
+ if (strcmp(s, "italic") != 0) {
+ _lou_logMessage(LOU_LOG_ERROR,
+ "First emphasis class must be \"italic\" but got "
+ "%s",
+ s);
+ errorCount++;
+ free(s);
+ return 0;
+ }
+ break;
+ case 1:
+ if (strcmp(s, "underline") != 0) {
+ _lou_logMessage(LOU_LOG_ERROR,
+ "Second emphasis class must be \"underline\" but "
+ "got "
+ "%s",
+ s);
+ errorCount++;
+ free(s);
+ return 0;
+ }
+ break;
+ case 2:
+ if (strcmp(s, "bold") != 0) {
+ _lou_logMessage(LOU_LOG_ERROR,
+ "Third emphasis class must be \"bold\" but got "
+ "%s",
+ s);
+ errorCount++;
+ free(s);
+ return 0;
+ }
+ break;
+ }
+ (*table)->emphClasses[i] = s;
+ (*table)->emphClasses[i + 1] = NULL;
+ ok = 1;
+ break;
+ } else {
+ _lou_logMessage(LOU_LOG_ERROR,
+ "Max number of emphasis classes (%i) reached",
+ MAX_EMPH_CLASSES);
+ errorCount++;
+ free(s);
+ ok = 0;
+ break;
+ }
+ }
+ compileError(nested, "emphclass must be followed by a valid class name.");
+ ok = 0;
+ break;
+ case CTO_EmphLetter:
+ case CTO_BegEmphWord:
+ case CTO_EndEmphWord:
+ case CTO_BegEmph:
+ case CTO_EndEmph:
+ case CTO_BegEmphPhrase:
+ case CTO_EndEmphPhrase:
+ case CTO_LenEmphPhrase: {
+ ok = 0;
+ TranslationTableOffset ruleOffset = 0;
+ if (getToken(nested, &token, "emphasis class", &lastToken))
+ if (parseChars(nested, &emphClass, &token)) {
+ char *s = malloc(sizeof(char) * (emphClass.length + 1));
+ for (k = 0; k < emphClass.length; k++)
+ s[k] = (char)emphClass.chars[k];
+ s[k++] = '\0';
+ for (i = 0; (*table)->emphClasses[i]; i++)
+ if (strcmp(s, (*table)->emphClasses[i]) == 0) break;
+ if (!(*table)->emphClasses[i]) {
+ _lou_logMessage(
+ LOU_LOG_ERROR, "Emphasis class %s not declared", s);
+ errorCount++;
+ free(s);
+ break;
+ }
+ i++; // in table->emphRules the first index is used for caps
+ if (opcode == CTO_EmphLetter) {
+ // not passing pointer because compileBrailleIndicator may
+ // reallocate table
+ ruleOffset = (*table)->emphRules[i][letterOffset];
+ ok = compileBrailleIndicator(nested, "single letter",
+ CTO_Emph1LetterRule + letterOffset + (8 * i), &lastToken,
+ &ruleOffset, newRule, noback, nofor, table);
+ (*table)->emphRules[i][letterOffset] = ruleOffset;
+ } else if (opcode == CTO_BegEmphWord) {
+ // not passing pointer because compileBrailleIndicator may
+ // reallocate table
+ ruleOffset = (*table)->emphRules[i][begWordOffset];
+ ok = compileBrailleIndicator(nested, "word",
+ CTO_Emph1LetterRule + begWordOffset + (8 * i), &lastToken,
+ &ruleOffset, newRule, noback, nofor, table);
+ (*table)->emphRules[i][begWordOffset] = ruleOffset;
+ } else if (opcode == CTO_EndEmphWord) {
+ // not passing pointer because compileBrailleIndicator may
+ // reallocate table
+ ruleOffset = (*table)->emphRules[i][endWordOffset];
+ ok = compileBrailleIndicator(nested, "word stop",
+ CTO_Emph1LetterRule + endWordOffset + (8 * i), &lastToken,
+ &ruleOffset, newRule, noback, nofor, table);
+ (*table)->emphRules[i][endWordOffset] = ruleOffset;
+ } else if (opcode == CTO_BegEmph) {
+ /* fail if both begemph and any of begemphphrase or begemphword
+ * are defined */
+ if ((*table)->emphRules[i][begWordOffset] ||
+ (*table)->emphRules[i][begPhraseOffset]) {
+ compileError(nested,
+ "Cannot define emphasis for both no context and word "
+ "or "
+ "phrase context, i.e. cannot have both begemph and "
+ "begemphword or begemphphrase.");
+ ok = 0;
+ break;
+ }
+ // not passing pointer because compileBrailleIndicator may
+ // reallocate table
+ ruleOffset = (*table)->emphRules[i][begOffset];
+ ok = compileBrailleIndicator(nested, "first letter",
+ CTO_Emph1LetterRule + begOffset + (8 * i), &lastToken,
+ &ruleOffset, newRule, noback, nofor, table);
+ (*table)->emphRules[i][begOffset] = ruleOffset;
+ } else if (opcode == CTO_EndEmph) {
+ if ((*table)->emphRules[i][endWordOffset] ||
+ (*table)->emphRules[i][endPhraseBeforeOffset] ||
+ (*table)->emphRules[i][endPhraseAfterOffset]) {
+ compileError(nested,
+ "Cannot define emphasis for both no context and word "
+ "or "
+ "phrase context, i.e. cannot have both endemph and "
+ "endemphword or endemphphrase.");
+ ok = 0;
+ break;
+ }
+ // not passing pointer because compileBrailleIndicator may
+ // reallocate table
+ ruleOffset = (*table)->emphRules[i][endOffset];
+ ok = compileBrailleIndicator(nested, "last letter",
+ CTO_Emph1LetterRule + endOffset + (8 * i), &lastToken,
+ &ruleOffset, newRule, noback, nofor, table);
+ (*table)->emphRules[i][endOffset] = ruleOffset;
+ } else if (opcode == CTO_BegEmphPhrase) {
+ // not passing pointer because compileBrailleIndicator may
+ // reallocate table
+ ruleOffset = (*table)->emphRules[i][begPhraseOffset];
+ ok = compileBrailleIndicator(nested, "first word",
+ CTO_Emph1LetterRule + begPhraseOffset + (8 * i),
+ &lastToken, &ruleOffset, newRule, noback, nofor, table);
+ (*table)->emphRules[i][begPhraseOffset] = ruleOffset;
+ } else if (opcode == CTO_EndEmphPhrase)
+ switch (compileBeforeAfter(nested, &lastToken)) {
+ case 1: // before
+ if ((*table)->emphRules[i][endPhraseAfterOffset]) {
+ compileError(nested, "last word after already defined.");
+ ok = 0;
+ break;
+ }
+ // not passing pointer because compileBrailleIndicator may
+ // reallocate table
+ ruleOffset = (*table)->emphRules[i][endPhraseBeforeOffset];
+ ok = compileBrailleIndicator(nested, "last word before",
+ CTO_Emph1LetterRule + endPhraseBeforeOffset + (8 * i),
+ &lastToken, &ruleOffset, newRule, noback, nofor,
+ table);
+ (*table)->emphRules[i][endPhraseBeforeOffset] = ruleOffset;
+ break;
+ case 2: // after
+ if ((*table)->emphRules[i][endPhraseBeforeOffset]) {
+ compileError(nested, "last word before already defined.");
+ ok = 0;
+ break;
+ }
+ // not passing pointer because compileBrailleIndicator may
+ // reallocate table
+ ruleOffset = (*table)->emphRules[i][endPhraseAfterOffset];
+ ok = compileBrailleIndicator(nested, "last word after",
+ CTO_Emph1LetterRule + endPhraseAfterOffset + (8 * i),
+ &lastToken, &ruleOffset, newRule, noback, nofor,
+ table);
+ (*table)->emphRules[i][endPhraseAfterOffset] = ruleOffset;
+ break;
+ default: // error
+ compileError(nested, "Invalid lastword indicator location.");
+ ok = 0;
+ break;
+ }
+ else if (opcode == CTO_LenEmphPhrase)
+ ok = (*table)->emphRules[i][lenPhraseOffset] =
+ compileNumber(nested, &lastToken);
+ free(s);
+ }
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_LetterSign: {
+ // not passing pointer because compileBrailleIndicator may reallocate table
+ TranslationTableOffset ruleOffset = (*table)->letterSign;
+ ok = compileBrailleIndicator(nested, "letter sign", CTO_LetterRule,
+ &lastToken, &ruleOffset, newRule, noback, nofor, table);
+ (*table)->letterSign = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_NoLetsignBefore:
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ if (((*table)->noLetsignBeforeCount + ruleChars.length) > LETSIGNSIZE) {
+ compileError(nested, "More than %d characters", LETSIGNSIZE);
+ ok = 0;
+ break;
+ }
+ for (k = 0; k < ruleChars.length; k++)
+ (*table)->noLetsignBefore[(*table)->noLetsignBeforeCount++] =
+ ruleChars.chars[k];
+ }
+ break;
+ case CTO_NoLetsign:
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ if (((*table)->noLetsignCount + ruleChars.length) > LETSIGNSIZE) {
+ compileError(nested, "More than %d characters", LETSIGNSIZE);
+ ok = 0;
+ break;
+ }
+ for (k = 0; k < ruleChars.length; k++)
+ (*table)->noLetsign[(*table)->noLetsignCount++] = ruleChars.chars[k];
+ }
+ break;
+ case CTO_NoLetsignAfter:
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ if (((*table)->noLetsignAfterCount + ruleChars.length) > LETSIGNSIZE) {
+ compileError(nested, "More than %d characters", LETSIGNSIZE);
+ ok = 0;
+ break;
+ }
+ for (k = 0; k < ruleChars.length; k++)
+ (*table)->noLetsignAfter[(*table)->noLetsignAfterCount++] =
+ ruleChars.chars[k];
+ }
+ break;
+ case CTO_NumberSign: {
+ // not passing pointer because compileBrailleIndicator may reallocate table
+ TranslationTableOffset ruleOffset = (*table)->numberSign;
+ ok = compileBrailleIndicator(nested, "number sign", CTO_NumberRule,
+ &lastToken, &ruleOffset, newRule, noback, nofor, table);
+ (*table)->numberSign = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_Attribute:
+
+ c = NULL;
+ ok = 1;
+ if (!getToken(nested, &ruleChars, "attribute number", &lastToken)) {
+ compileError(nested, "Expected attribute number.");
+ ok = 0;
+ break;
+ }
+
+ k = -1;
+ switch (ruleChars.chars[0]) {
+ case '0':
+ k = 0;
+ break;
+ case '1':
+ k = 1;
+ break;
+ case '2':
+ k = 2;
+ break;
+ case '3':
+ k = 3;
+ break;
+ case '4':
+ k = 4;
+ break;
+ case '5':
+ k = 5;
+ break;
+ case '6':
+ k = 6;
+ break;
+ case '7':
+ k = 7;
+ break;
+ }
+ if (k == -1) {
+ compileError(nested, "Invalid attribute number.");
+ ok = 0;
+ break;
+ }
+
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ for (i = 0; i < ruleChars.length; i++) {
+ c = compile_findCharOrDots(ruleChars.chars[i], 0, *table);
+ if (c)
+ c->attributes |= (CTC_UserDefined0 << k);
+ else {
+ compileError(nested, "Attribute character undefined");
+ ok = 0;
+ break;
+ }
+ }
+ }
+ break;
+
+ case CTO_NumericModeChars:
+
+ c = NULL;
+ ok = 1;
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ for (k = 0; k < ruleChars.length; k++) {
+ c = compile_findCharOrDots(ruleChars.chars[k], 0, *table);
+ if (c)
+ c->attributes |= CTC_NumericMode;
+ else {
+ compileError(nested, "Numeric mode character undefined");
+ ok = 0;
+ break;
+ }
+ }
+ (*table)->usesNumericMode = 1;
+ }
+ break;
+
+ case CTO_MidEndNumericModeChars:
+
+ c = NULL;
+ ok = 1;
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ for (k = 0; k < ruleChars.length; k++) {
+ c = compile_findCharOrDots(ruleChars.chars[k], 0, *table);
+ if (c)
+ c->attributes |= CTC_MidEndNumericMode;
+ else {
+ compileError(nested, "Midendnumeric mode character undefined");
+ ok = 0;
+ break;
+ }
+ }
+ (*table)->usesNumericMode = 1;
+ }
+ break;
+
+ case CTO_NumericNoContractChars:
+
+ c = NULL;
+ ok = 1;
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ for (k = 0; k < ruleChars.length; k++) {
+ c = compile_findCharOrDots(ruleChars.chars[k], 0, *table);
+ if (c)
+ c->attributes |= CTC_NumericNoContract;
+ else {
+ compileError(
+ nested, "Numeric no contraction character undefined");
+ ok = 0;
+ break;
+ }
+ }
+ (*table)->usesNumericMode = 1;
+ }
+ break;
+
+ case CTO_NoContractSign: {
+ // not passing pointer because compileBrailleIndicator may reallocate table
+ TranslationTableOffset ruleOffset = (*table)->noContractSign;
+ ok = compileBrailleIndicator(nested, "no contractions sign",
+ CTO_NoContractRule, &lastToken, &ruleOffset, newRule, noback, nofor,
+ table);
+ (*table)->noContractSign = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_SeqDelimiter:
+
+ c = NULL;
+ ok = 1;
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ for (k = 0; k < ruleChars.length; k++) {
+ c = compile_findCharOrDots(ruleChars.chars[k], 0, *table);
+ if (c)
+ c->attributes |= CTC_SeqDelimiter;
+ else {
+ compileError(nested, "Sequence delimiter character undefined");
+ ok = 0;
+ break;
+ }
+ }
+ (*table)->usesSequences = 1;
+ }
+ break;
+
+ case CTO_SeqBeforeChars:
+
+ c = NULL;
+ ok = 1;
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ for (k = 0; k < ruleChars.length; k++) {
+ c = compile_findCharOrDots(ruleChars.chars[k], 0, *table);
+ if (c)
+ c->attributes |= CTC_SeqBefore;
+ else {
+ compileError(nested, "Sequence before character undefined");
+ ok = 0;
+ break;
+ }
+ }
+ }
+ break;
+
+ case CTO_SeqAfterChars:
+
+ c = NULL;
+ ok = 1;
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ for (k = 0; k < ruleChars.length; k++) {
+ c = compile_findCharOrDots(ruleChars.chars[k], 0, *table);
+ if (c)
+ c->attributes |= CTC_SeqAfter;
+ else {
+ compileError(nested, "Sequence after character undefined");
+ ok = 0;
+ break;
+ }
+ }
+ }
+ break;
+
+ case CTO_SeqAfterPattern:
+
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ if (((*table)->seqPatternsCount + ruleChars.length + 1) >
+ SEQPATTERNSIZE) {
+ compileError(nested, "More than %d characters", SEQPATTERNSIZE);
+ ok = 0;
+ break;
+ }
+ for (k = 0; k < ruleChars.length; k++)
+ (*table)->seqPatterns[(*table)->seqPatternsCount++] =
+ ruleChars.chars[k];
+ (*table)->seqPatterns[(*table)->seqPatternsCount++] = 0;
+ }
+ break;
+ case CTO_SeqAfterExpression:
+
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ for ((*table)->seqAfterExpressionLength = 0;
+ (*table)->seqAfterExpressionLength < ruleChars.length;
+ (*table)->seqAfterExpressionLength++)
+ (*table)->seqAfterExpression[(*table)->seqAfterExpressionLength] =
+ ruleChars.chars[(*table)->seqAfterExpressionLength];
+ (*table)->seqAfterExpression[(*table)->seqAfterExpressionLength] = 0;
+ }
+ break;
+
+ case CTO_CapsModeChars:
+
+ c = NULL;
+ ok = 1;
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ for (k = 0; k < ruleChars.length; k++) {
+ c = compile_findCharOrDots(ruleChars.chars[k], 0, *table);
+ if (c)
+ c->attributes |= CTC_CapsMode;
+ else {
+ compileError(nested, "Capital mode character undefined");
+ ok = 0;
+ break;
+ }
+ }
+ }
+ break;
+
+ case CTO_EmphModeChars:
+
+ c = NULL;
+ ok = 1;
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ for (k = 0; k < ruleChars.length; k++) {
+ c = compile_findCharOrDots(ruleChars.chars[k], 0, *table);
+ if (c)
+ c->attributes |= CTC_EmphMode;
+ else {
+ compileError(nested, "Emphasis mode character undefined");
+ ok = 0;
+ break;
+ }
+ }
+ }
+ (*table)->usesEmphMode = 1;
+ break;
+
+ case CTO_BegComp: {
+ // not passing pointer because compileBrailleIndicator may reallocate table
+ TranslationTableOffset ruleOffset = (*table)->begComp;
+ ok = compileBrailleIndicator(nested, "begin computer braille",
+ CTO_BegCompRule, &lastToken, &ruleOffset, newRule, noback, nofor,
+ table);
+ (*table)->begComp = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_EndComp: {
+ // not passing pointer because compileBrailleIndicator may reallocate table
+ TranslationTableOffset ruleOffset = (*table)->endComp;
+ ok = compileBrailleIndicator(nested, "end computer braslle", CTO_EndCompRule,
+ &lastToken, &ruleOffset, newRule, noback, nofor, table);
+ (*table)->endComp = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_Syllable:
+ (*table)->syllables = 1;
+ case CTO_Always:
+ case CTO_NoCross:
+ case CTO_LargeSign:
+ case CTO_WholeWord:
+ case CTO_PartWord:
+ case CTO_JoinNum:
+ case CTO_JoinableWord:
+ case CTO_LowWord:
+ case CTO_SuffixableWord:
+ case CTO_PrefixableWord:
+ case CTO_BegWord:
+ case CTO_BegMidWord:
+ case CTO_MidWord:
+ case CTO_MidEndWord:
+ case CTO_EndWord:
+ case CTO_PrePunc:
+ case CTO_PostPunc:
+ case CTO_BegNum:
+ case CTO_MidNum:
+ case CTO_EndNum:
+ case CTO_Repeated:
+ case CTO_RepWord:
+ if (getRuleCharsText(nested, &ruleChars, &lastToken))
+ if (getRuleDotsPattern(nested, &ruleDots, &lastToken)) {
+ if (ruleDots.length == 0) // `=`
+ for (k = 0; k < ruleChars.length; k++) {
+ c = compile_findCharOrDots(ruleChars.chars[k], 0, *table);
+ if (!c || !c->definitionRule) {
+ compileError(nested, "Character %s is not defined",
+ _lou_showString(&ruleChars.chars[k], 1, 0));
+ return 0;
+ }
+ }
+ if (!addRule(nested, opcode, &ruleChars, &ruleDots, after, before,
+ newRuleOffset, newRule, noback, nofor, table))
+ ok = 0;
+ }
+ // if (opcode == CTO_MidNum)
+ // {
+ // TranslationTableCharacter *c = compile_findCharOrDots(ruleChars.chars[0],
+ // 0); if(c)
+ // c->attributes |= CTC_NumericMode;
+ // }
+ break;
+ case CTO_CompDots:
+ case CTO_Comp6: {
+ TranslationTableOffset ruleOffset;
+ if (!getRuleCharsText(nested, &ruleChars, &lastToken)) return 0;
+ if (ruleChars.length != 1 || ruleChars.chars[0] > 255) {
+ compileError(nested, "first operand must be 1 character and < 256");
+ return 0;
+ }
+ if (!getRuleDotsPattern(nested, &ruleDots, &lastToken)) return 0;
+ if (!addRule(nested, opcode, &ruleChars, &ruleDots, after, before,
+ &ruleOffset, newRule, noback, nofor, table))
+ ok = 0;
+ (*table)->compdotsPattern[ruleChars.chars[0]] = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_ExactDots:
+ if (!getRuleCharsText(nested, &ruleChars, &lastToken)) return 0;
+ if (ruleChars.chars[0] != '@') {
+ compileError(nested, "The operand must begin with an at sign (@)");
+ return 0;
+ }
+ for (k = 1; k < ruleChars.length; k++)
+ scratchPad.chars[k - 1] = ruleChars.chars[k];
+ scratchPad.length = ruleChars.length - 1;
+ if (!parseDots(nested, &ruleDots, &scratchPad)) return 0;
+ if (!addRule(nested, opcode, &ruleChars, &ruleDots, before, after,
+ newRuleOffset, newRule, noback, nofor, table))
+ ok = 0;
+ break;
+ case CTO_CapsNoCont: {
+ TranslationTableOffset ruleOffset;
+ ruleChars.length = 1;
+ ruleChars.chars[0] = 'a';
+ if (!addRule(nested, CTO_CapsNoContRule, &ruleChars, NULL, after, before,
+ &ruleOffset, newRule, noback, nofor, table))
+ ok = 0;
+ (*table)->capsNoCont = ruleOffset;
+ if (ok && newRuleOffset) *newRuleOffset = ruleOffset;
+ break;
+ }
+ case CTO_Replace:
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ if (lastToken)
+ ruleDots.length = ruleDots.chars[0] = 0;
+ else {
+ getRuleDotsText(nested, &ruleDots, &lastToken);
+ if (ruleDots.chars[0] == '#')
+ ruleDots.length = ruleDots.chars[0] = 0;
+ else if (ruleDots.chars[0] == '\\' && ruleDots.chars[1] == '#')
+ memcpy(&ruleDots.chars[0], &ruleDots.chars[1],
+ ruleDots.length-- * CHARSIZE);
+ }
+ }
+ for (k = 0; k < ruleChars.length; k++)
+ addCharOrDots(nested, ruleChars.chars[k], 0, table);
+ for (k = 0; k < ruleDots.length; k++)
+ addCharOrDots(nested, ruleDots.chars[k], 0, table);
+ if (!addRule(nested, opcode, &ruleChars, &ruleDots, after, before,
+ newRuleOffset, newRule, noback, nofor, table))
+ ok = 0;
+ break;
+ case CTO_Correct:
+ (*table)->corrections = 1;
+ goto doPass;
+ case CTO_Pass2:
+ if ((*table)->numPasses < 2) (*table)->numPasses = 2;
+ goto doPass;
+ case CTO_Pass3:
+ if ((*table)->numPasses < 3) (*table)->numPasses = 3;
+ goto doPass;
+ case CTO_Pass4:
+ if ((*table)->numPasses < 4) (*table)->numPasses = 4;
+ doPass:
+ case CTO_Context:
+ if (!(nofor || noback)) {
+ compileError(nested, "%s or %s must be specified.",
+ _lou_findOpcodeName(CTO_NoFor), _lou_findOpcodeName(CTO_NoBack));
+ ok = 0;
+ break;
+ }
+ if (!compilePassOpcode(
+ nested, opcode, newRuleOffset, newRule, noback, nofor, table))
+ ok = 0;
+ break;
+ case CTO_Contraction:
+ case CTO_NoCont:
+ case CTO_CompBrl:
+ case CTO_Literal:
+ if (getRuleCharsText(nested, &ruleChars, &lastToken)) {
+ for (k = 0; k < ruleChars.length; k++) {
+ c = compile_findCharOrDots(ruleChars.chars[k], 0, *table);
+ if (!c || !c->definitionRule) {
+ compileError(nested, "Character %s is not defined",
+ _lou_showString(&ruleChars.chars[k], 1, 0));
+ return 0;
+ }
+ }
+ if (!addRule(nested, opcode, &ruleChars, NULL, after, before,
+ newRuleOffset, newRule, noback, nofor, table))
+ ok = 0;
+ }
+ break;
+ case CTO_MultInd: {
+ int t;
+ ruleChars.length = 0;
+ if (getToken(nested, &token, "multiple braille indicators", &lastToken) &&
+ parseDots(nested, &cells, &token)) {
+ while ((t = getToken(nested, &token, "multind opcodes", &lastToken))) {
+ opcode = getOpcode(nested, &token);
+ if (opcode >= CTO_CapsLetter && opcode < CTO_MultInd)
+ ruleChars.chars[ruleChars.length++] = (widechar)opcode;
+ else {
+ compileError(nested, "Not a braille indicator opcode.");
+ ok = 0;
+ }
+ if (t == 2) break;
+ }
+ } else
+ ok = 0;
+ if (!addRule(nested, CTO_MultInd, &ruleChars, &cells, after, before,
+ newRuleOffset, newRule, noback, nofor, table))
+ ok = 0;
+ break;
+ }
+
+ case CTO_Class: {
+ CharsString characters;
+ const CharacterClass *class;
+ if (!(*table)->characterClasses) {
+ if (!allocateCharacterClasses(*table)) ok = 0;
+ }
+ if (getToken(nested, &token, "character class name", &lastToken)) {
+ class = findCharacterClass(&token, *table);
+ if (!class)
+ // no class with that name: create one
+ class = addCharacterClass(
+ nested, &token.chars[0], token.length, *table);
+ if (class) {
+ // there is a class with that name or a new class was successfully
+ // created
+ if (getCharacters(nested, &characters, &lastToken)) {
+ int index;
+ for (index = 0; index < characters.length; ++index) {
+ TranslationTableRule *defRule;
+ // get the character from the table and add the new class to
+ // its attributes if the character is not defined yet, define
+ // it
+ TranslationTableCharacter *character = addCharOrDots(
+ nested, characters.chars[index], 0, table);
+ character->attributes |= class->attribute;
+ // also add the attribute to the associated dots (if any)
+ if (character->definitionRule) {
+ defRule = (TranslationTableRule *)&(*table)
+ ->ruleArea[character->definitionRule];
+ if (defRule->dotslen == 1) {
+ character = compile_findCharOrDots(
+ defRule->charsdots[defRule->charslen], 1,
+ *table);
+ if (character)
+ character->attributes |= class->attribute;
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ {
+ TranslationTableCharacterAttributes *attributes;
+ const CharacterClass *class;
+ case CTO_After:
+ attributes = &after;
+ goto doClass;
+ case CTO_Before:
+ attributes = &before;
+ doClass:
+ if (!(*table)->characterClasses) {
+ if (!allocateCharacterClasses(*table)) ok = 0;
+ }
+ if (getCharacterClass(nested, &class, *table, &lastToken)) {
+ *attributes |= class->attribute;
+ goto doOpcode;
+ }
+ break;
+ }
+
+ case CTO_EmpMatchBefore:
+ before |= CTC_EmpMatch;
+ goto doOpcode;
+ case CTO_EmpMatchAfter:
+ after |= CTC_EmpMatch;
+ goto doOpcode;
+
+ case CTO_SwapCc:
+ case CTO_SwapCd:
+ case CTO_SwapDd:
+ if (!compileSwap(nested, opcode, &lastToken, newRuleOffset, newRule, noback,
+ nofor, table))
+ ok = 0;
+ break;
+ case CTO_Hyphen:
+ case CTO_DecPoint:
+ // case CTO_Apostrophe:
+ // case CTO_Initial:
+ if (getRuleCharsText(nested, &ruleChars, &lastToken))
+ if (getRuleDotsPattern(nested, &ruleDots, &lastToken)) {
+ if (ruleChars.length != 1 || ruleDots.length < 1) {
+ compileError(nested,
+ "One Unicode character and at least one cell are "
+ "required.");
+ ok = 0;
+ }
+ if (!addRule(nested, opcode, &ruleChars, &ruleDots, after, before,
+ newRuleOffset, newRule, noback, nofor, table))
+ ok = 0;
+ // if (opcode == CTO_DecPoint)
+ // {
+ // TranslationTableCharacter *c =
+ // compile_findCharOrDots(ruleChars.chars[0], 0);
+ // if(c)
+ // c->attributes |= CTC_NumericMode;
+ // }
+ }
+ break;
+ default:
+ compileError(nested, "unimplemented opcode.");
+ ok = 0;
+ break;
+ }
+ }
+
+ if (patterns != NULL) free(patterns);
+
+ return ok;
+}
+
+int EXPORT_CALL
+lou_readCharFromFile(const char *fileName, int *mode) {
+ /* Read a character from a file, whether big-endian, little-endian or
+ * ASCII8 */
+ int ch;
+ static FileInfo nested;
+ if (fileName == NULL) return 0;
+ if (*mode == 1) {
+ *mode = 0;
+ nested.fileName = fileName;
+ nested.encoding = noEncoding;
+ nested.status = 0;
+ nested.lineNumber = 0;
+ if (!(nested.in = fopen(nested.fileName, "r"))) {
+ _lou_logMessage(LOU_LOG_ERROR, "Cannot open file '%s'", nested.fileName);
+ *mode = 1;
+ return EOF;
+ }
+ }
+ if (nested.in == NULL) {
+ *mode = 1;
+ return EOF;
+ }
+ ch = getAChar(&nested);
+ if (ch == EOF) {
+ fclose(nested.in);
+ nested.in = NULL;
+ *mode = 1;
+ }
+ return ch;
+}
+
+static int
+compileString(const char *inString, TranslationTableHeader **table,
+ DisplayTableHeader **displayTable) {
+ /* This function can be used to make changes to tables on the fly. */
+ int k;
+ FileInfo nested;
+ if (inString == NULL) return 0;
+ memset(&nested, 0, sizeof(nested));
+ nested.fileName = inString;
+ nested.encoding = noEncoding;
+ nested.lineNumber = 1;
+ nested.status = 0;
+ nested.linepos = 0;
+ for (k = 0; inString[k]; k++) nested.line[k] = inString[k];
+ nested.line[k] = 0;
+ nested.linelen = k;
+ return compileRule(&nested, NULL, NULL, table, displayTable);
+}
+
+static int
+setDefaults(TranslationTableHeader *table) {
+ if (!table->emphRules[emph1Rule][lenPhraseOffset])
+ table->emphRules[emph1Rule][lenPhraseOffset] = 4;
+ if (!table->emphRules[emph2Rule][lenPhraseOffset])
+ table->emphRules[emph2Rule][lenPhraseOffset] = 4;
+ if (!table->emphRules[emph3Rule][lenPhraseOffset])
+ table->emphRules[emph3Rule][lenPhraseOffset] = 4;
+ if (table->numPasses == 0) table->numPasses = 1;
+ return 1;
+}
+
+/* =============== *
+ * TABLE RESOLVING *
+ * =============== *
+ *
+ * A table resolver is a function that resolves a `tableList` path against a
+ * `base` path, and returns the resolved table(s) as a list of absolute file
+ * paths.
+ *
+ * The function must have the following signature:
+ *
+ * char ** (const char * tableList, const char * base)
+ *
+ * In general, `tableList` is a path in the broad sense. The default
+ * implementation accepts only *file* paths. But another implementation could
+ * for instance handle URI's. `base` is always a file path however.
+ *
+ * The idea is to give other programs that use liblouis the ability to define
+ * their own table resolver (in C, Java, Python, etc.) when the default
+ * resolver is not satisfying. (see also lou_registerTableResolver)
+ *
+ */
+
+/**
+ * Resolve a single (sub)table.
+ *
+ * Tries to resolve `table` against `base` if base is an absolute path. If
+ * that fails, searches `searchPath`.
+ *
+ */
+static char *
+resolveSubtable(const char *table, const char *base, const char *searchPath) {
+ char *tableFile;
+ static struct stat info;
+
+ if (table == NULL || table[0] == '\0') return NULL;
+ tableFile = (char *)malloc(MAXSTRING * sizeof(char) * 2);
+
+ //
+ // First try to resolve against base
+ //
+ if (base) {
+ int k;
+ strcpy(tableFile, base);
+ k = (int)strlen(tableFile);
+ while (k >= 0 && tableFile[k] != '/' && tableFile[k] != '\\') k--;
+ tableFile[++k] = '\0';
+ strcat(tableFile, table);
+ if (stat(tableFile, &info) == 0 && !(info.st_mode & S_IFDIR)) {
+ _lou_logMessage(LOU_LOG_DEBUG, "found table %s", tableFile);
+ return tableFile;
+ }
+ }
+
+ //
+ // It could be an absolute path, or a path relative to the current working
+ // directory
+ //
+ strcpy(tableFile, table);
+ if (stat(tableFile, &info) == 0 && !(info.st_mode & S_IFDIR)) {
+ _lou_logMessage(LOU_LOG_DEBUG, "found table %s", tableFile);
+ return tableFile;
+ }
+
+ //
+ // Then search `LOUIS_TABLEPATH`, `dataPath` and `programPath`
+ //
+ if (searchPath[0] != '\0') {
+ char *dir;
+ int last;
+ char *cp;
+ char *searchPath_copy = strdup(searchPath);
+ for (dir = searchPath_copy;; dir = cp + 1) {
+ for (cp = dir; *cp != '\0' && *cp != ','; cp++)
+ ;
+ last = (*cp == '\0');
+ *cp = '\0';
+ if (dir == cp) dir = ".";
+ sprintf(tableFile, "%s%c%s", dir, DIR_SEP, table);
+ if (stat(tableFile, &info) == 0 && !(info.st_mode & S_IFDIR)) {
+ _lou_logMessage(LOU_LOG_DEBUG, "found table %s", tableFile);
+ free(searchPath_copy);
+ return tableFile;
+ }
+ if (last) break;
+ sprintf(tableFile, "%s%c%s%c%s%c%s", dir, DIR_SEP, "liblouis", DIR_SEP,
+ "tables", DIR_SEP, table);
+ if (stat(tableFile, &info) == 0 && !(info.st_mode & S_IFDIR)) {
+ _lou_logMessage(LOU_LOG_DEBUG, "found table %s", tableFile);
+ free(searchPath_copy);
+ return tableFile;
+ }
+ if (last) break;
+ }
+ free(searchPath_copy);
+ }
+ free(tableFile);
+ return NULL;
+}
+
+char *EXPORT_CALL
+_lou_getTablePath(void) {
+ char searchPath[MAXSTRING];
+ char *path;
+ char *cp;
+ int envset = 0;
+ cp = searchPath;
+ path = getenv("LOUIS_TABLEPATH");
+ if (path != NULL && path[0] != '\0') {
+ envset = 1;
+ cp += sprintf(cp, ",%s", path);
+ }
+ path = lou_getDataPath();
+ if (path != NULL && path[0] != '\0')
+ cp += sprintf(cp, ",%s%c%s%c%s", path, DIR_SEP, "liblouis", DIR_SEP, "tables");
+ if (!envset) {
+#ifdef _WIN32
+ path = lou_getProgramPath();
+ if (path != NULL) {
+ if (path[0] != '\0')
+ cp += sprintf(cp, ",%s%s", path, "\\share\\liblouis\\tables");
+ free(path);
+ }
+#else
+ cp += sprintf(cp, ",%s", TABLESDIR);
+#endif
+ }
+ if (searchPath[0] != '\0')
+ return strdup(&searchPath[1]);
+ else
+ return strdup(".");
+}
+
+/**
+ * The default table resolver
+ *
+ * Tries to resolve tableList against base. The search path is set to
+ * `LOUIS_TABLEPATH`, `dataPath` and `programPath` (in that order).
+ *
+ * @param table A file path, may be absolute or relative. May be a list of
+ * tables separated by comma's. In that case, the first table
+ * is used as the base for the other subtables.
+ * @param base A file path or directory path, or NULL.
+ * @return The file paths of the resolved subtables, or NULL if the table
+ * could not be resolved.
+ *
+ */
+char **EXPORT_CALL
+_lou_defaultTableResolver(const char *tableList, const char *base) {
+ char *searchPath;
+ char **tableFiles;
+ char *subTable;
+ char *tableList_copy;
+ char *cp;
+ int last;
+ int k;
+
+ /* Set up search path */
+ searchPath = _lou_getTablePath();
+
+ /* Count number of subtables in table list */
+ k = 0;
+ for (cp = (char *)tableList; *cp != '\0'; cp++)
+ if (*cp == ',') k++;
+ tableFiles = (char **)calloc(k + 2, sizeof(char *));
+ if (!tableFiles) _lou_outOfMemory();
+
+ /* Resolve subtables */
+ k = 0;
+ tableList_copy = strdup(tableList);
+ for (subTable = tableList_copy;; subTable = cp + 1) {
+ for (cp = subTable; *cp != '\0' && *cp != ','; cp++)
+ ;
+ last = (*cp == '\0');
+ *cp = '\0';
+ if (!(tableFiles[k++] = resolveSubtable(subTable, base, searchPath))) {
+ char *path;
+ _lou_logMessage(LOU_LOG_ERROR, "Cannot resolve table '%s'", subTable);
+ path = getenv("LOUIS_TABLEPATH");
+ if (path != NULL && path[0] != '\0')
+ _lou_logMessage(LOU_LOG_ERROR, "LOUIS_TABLEPATH=%s", path);
+ free(searchPath);
+ free(tableList_copy);
+ free_tablefiles(tableFiles);
+ return NULL;
+ }
+ if (k == 1) base = subTable;
+ if (last) break;
+ }
+ free(searchPath);
+ free(tableList_copy);
+ tableFiles[k] = NULL;
+ return tableFiles;
+}
+
+static char **(EXPORT_CALL *tableResolver)(
+ const char *tableList, const char *base) = &_lou_defaultTableResolver;
+
+static char **
+copyStringArray(char **array) {
+ int len;
+ char **copy;
+ if (!array) return NULL;
+ len = 0;
+ while (array[len]) len++;
+ copy = malloc((len + 1) * sizeof(char *));
+ copy[len] = NULL;
+ while (len) {
+ len--;
+ copy[len] = strdup(array[len]);
+ }
+ return copy;
+}
+
+char **EXPORT_CALL
+_lou_resolveTable(const char *tableList, const char *base) {
+ char **tableFiles = (*tableResolver)(tableList, base);
+ char **result = copyStringArray(tableFiles);
+ if (tableResolver == &_lou_defaultTableResolver) free_tablefiles(tableFiles);
+ return result;
+}
+
+/**
+ * Register a new table resolver. Overrides the default resolver.
+ *
+ * @param resolver The new resolver as a function pointer.
+ *
+ */
+void EXPORT_CALL
+lou_registerTableResolver(
+ char **(EXPORT_CALL *resolver)(const char *tableList, const char *base)) {
+ tableResolver = resolver;
+}
+
+static int fileCount = 0;
+
+/**
+ * Compile a single file
+ *
+ */
+static int
+compileFile(const char *fileName, TranslationTableHeader **table,
+ DisplayTableHeader **displayTable) {
+ FileInfo nested;
+ fileCount++;
+ nested.fileName = fileName;
+ nested.encoding = noEncoding;
+ nested.status = 0;
+ nested.lineNumber = 0;
+ if ((nested.in = fopen(nested.fileName, "rb"))) {
+ while (_lou_getALine(&nested))
+ compileRule(&nested, NULL, NULL, table, displayTable);
+ fclose(nested.in);
+ return 1;
+ } else
+ _lou_logMessage(LOU_LOG_ERROR, "Cannot open table '%s'", nested.fileName);
+ errorCount++;
+ return 0;
+}
+
+/**
+ * Free a char** array
+ */
+static void
+free_tablefiles(char **tables) {
+ char **table;
+ if (!tables) return;
+ for (table = tables; *table; table++) free(*table);
+ free(tables);
+}
+
+/**
+ * Implement include opcode
+ *
+ */
+static int
+includeFile(FileInfo *nested, CharsString *includedFile, TranslationTableHeader **table,
+ DisplayTableHeader **displayTable) {
+ int k;
+ char includeThis[MAXSTRING];
+ char **tableFiles;
+ int rv;
+ for (k = 0; k < includedFile->length; k++)
+ includeThis[k] = (char)includedFile->chars[k];
+ if (k >= MAXSTRING) {
+ compileError(nested, "Include statement too long: 'include %s'", includeThis);
+ return 0;
+ }
+ includeThis[k] = 0;
+ tableFiles = _lou_resolveTable(includeThis, nested->fileName);
+ if (tableFiles == NULL) {
+ errorCount++;
+ return 0;
+ }
+ if (tableFiles[1] != NULL) {
+ free_tablefiles(tableFiles);
+ compileError(nested,
+ "Table list not supported in include statement: 'include %s'",
+ includeThis);
+ return 0;
+ }
+ rv = compileFile(*tableFiles, table, displayTable);
+ free_tablefiles(tableFiles);
+ return rv;
+}
+
+/**
+ * Compile source tables into a table in memory
+ *
+ */
+static int
+compileTable(const char *tableList, const char *displayTableList,
+ TranslationTableHeader **translationTable, DisplayTableHeader **displayTable) {
+ char **tableFiles;
+ char **subTable;
+ if (translationTable && !tableList) return 0;
+ if (displayTable && !displayTableList) return 0;
+ if (!translationTable && !displayTable) return 0;
+ if (translationTable) *translationTable = NULL;
+ if (displayTable) *displayTable = NULL;
+ errorCount = warningCount = fileCount = 0;
+ if (!opcodeLengths[0]) {
+ TranslationTableOpcode opcode;
+ for (opcode = 0; opcode < CTO_None; opcode++)
+ opcodeLengths[opcode] = (short)strlen(opcodeNames[opcode]);
+ }
+ if (translationTable) allocateTranslationTable(NULL, translationTable);
+ if (displayTable) allocateDisplayTable(NULL, displayTable);
+
+ if (translationTable) {
+ (*translationTable)->emphClasses[0] = NULL;
+ (*translationTable)->characterClasses = NULL;
+ (*translationTable)->ruleNames = NULL;
+ }
+
+ /* Compile things that are necesary for the proper operation of
+ * liblouis or liblouisxml or liblouisutdml */
+ /* TODO: These definitions seem to be necessary for proper functioning of
+ liblouisutdml. Find a way to satisfy those requirements without hard coding
+ some characters in every table notably behind the users back */
+ compileString("space \\xffff 123456789abcdef LOU_ENDSEGMENT", translationTable,
+ displayTable);
+
+ if (displayTable && translationTable && strcmp(tableList, displayTableList) == 0) {
+ /* Compile the display and translation tables in one go */
+
+ /* Compile all subtables in the list */
+ if (!(tableFiles = _lou_resolveTable(tableList, NULL))) {
+ errorCount++;
+ goto cleanup;
+ }
+ for (subTable = tableFiles; *subTable; subTable++)
+ if (!compileFile(*subTable, translationTable, displayTable)) goto cleanup;
+ } else {
+ /* Compile the display and translation tables separately */
+
+ if (displayTable) {
+ if (!(tableFiles = _lou_resolveTable(displayTableList, NULL))) {
+ errorCount++;
+ goto cleanup;
+ }
+ for (subTable = tableFiles; *subTable; subTable++)
+ if (!compileFile(*subTable, NULL, displayTable)) goto cleanup;
+ free_tablefiles(tableFiles);
+ tableFiles = NULL;
+ }
+ if (translationTable) {
+ if (!(tableFiles = _lou_resolveTable(tableList, NULL))) {
+ errorCount++;
+ goto cleanup;
+ }
+ for (subTable = tableFiles; *subTable; subTable++)
+ if (!compileFile(*subTable, translationTable, NULL)) goto cleanup;
+ }
+ }
+
+/* Clean up after compiling files */
+cleanup:
+ free_tablefiles(tableFiles);
+ if (warningCount) _lou_logMessage(LOU_LOG_WARN, "%d warnings issued", warningCount);
+ if (!errorCount) {
+ if (translationTable) setDefaults(*translationTable);
+ return 1;
+ } else {
+ _lou_logMessage(LOU_LOG_ERROR, "%d errors found.", errorCount);
+ if (translationTable) {
+ if (*translationTable) free(*translationTable);
+ *translationTable = NULL;
+ }
+ if (displayTable) {
+ if (*displayTable) free(*displayTable);
+ *displayTable = NULL;
+ }
+ return 0;
+ }
+}
+
+/* Return the emphasis classes declared in tableList. */
+char const **EXPORT_CALL
+lou_getEmphClasses(const char *tableList) {
+ const char *names[MAX_EMPH_CLASSES + 1];
+ unsigned int count = 0;
+ const TranslationTableHeader *table = _lou_getTranslationTable(tableList);
+ if (!table) return NULL;
+
+ while (count < MAX_EMPH_CLASSES) {
+ char const *name = table->emphClasses[count];
+ if (!name) break;
+ names[count++] = name;
+ }
+ names[count++] = NULL;
+
+ {
+ unsigned int size = count * sizeof(names[0]);
+ char const **result = malloc(size);
+ if (!result) return NULL;
+ /* The void* cast is necessary to stop MSVC from warning about
+ * different 'const' qualifiers (C4090). */
+ memcpy((void *)result, names, size);
+ return result;
+ }
+}
+
+void
+getTable(const char *tableList, const char *displayTableList,
+ TranslationTableHeader **translationTable, DisplayTableHeader **displayTable);
+
+void EXPORT_CALL
+_lou_getTable(const char *tableList, const char *displayTableList,
+ const TranslationTableHeader **translationTable,
+ const DisplayTableHeader **displayTable) {
+ TranslationTableHeader *newTable;
+ DisplayTableHeader *newDisplayTable;
+ getTable(tableList, displayTableList, &newTable, &newDisplayTable);
+ *translationTable = newTable;
+ *displayTable = newDisplayTable;
+}
+
+/* Checks and loads tableList. */
+const void *EXPORT_CALL
+lou_getTable(const char *tableList) {
+ const TranslationTableHeader *table;
+ const DisplayTableHeader *displayTable;
+ _lou_getTable(tableList, tableList, &table, &displayTable);
+ if (!table || !displayTable) return NULL;
+ return table;
+}
+
+const TranslationTableHeader *EXPORT_CALL
+_lou_getTranslationTable(const char *tableList) {
+ TranslationTableHeader *table;
+ getTable(tableList, NULL, &table, NULL);
+ return table;
+}
+
+const DisplayTableHeader *EXPORT_CALL
+_lou_getDisplayTable(const char *tableList) {
+ DisplayTableHeader *table;
+ getTable(NULL, tableList, NULL, &table);
+ return table;
+}
+
+void
+getTable(const char *translationTableList, const char *displayTableList,
+ TranslationTableHeader **translationTable, DisplayTableHeader **displayTable) {
+ /* Keep track of which tables have already been compiled */
+ int translationTableListLen, displayTableListLen = 0;
+ if (translationTableList == NULL || *translationTableList == 0)
+ translationTable = NULL;
+ if (displayTableList == NULL || *displayTableList == 0) displayTable = NULL;
+ /* See if translation table has already been compiled */
+ if (translationTable) {
+ translationTableListLen = (int)strlen(translationTableList);
+ *translationTable = NULL;
+ TranslationTableChainEntry *currentEntry = translationTableChain;
+ TranslationTableChainEntry *prevEntry = NULL;
+ while (currentEntry != NULL) {
+ if (translationTableListLen == currentEntry->tableListLength &&
+ (memcmp(¤tEntry->tableList[0], translationTableList,
+ translationTableListLen)) == 0) {
+ /* Move the table to the top of the table chain. */
+ if (prevEntry != NULL) {
+ prevEntry->next = currentEntry->next;
+ currentEntry->next = translationTableChain;
+ translationTableChain = currentEntry;
+ }
+ *translationTable = currentEntry->table;
+ break;
+ }
+ prevEntry = currentEntry;
+ currentEntry = currentEntry->next;
+ }
+ }
+ /* See if display table has already been compiled */
+ if (displayTable) {
+ displayTableListLen = (int)strlen(displayTableList);
+ *displayTable = NULL;
+ DisplayTableChainEntry *currentEntry = displayTableChain;
+ DisplayTableChainEntry *prevEntry = NULL;
+ while (currentEntry != NULL) {
+ if (displayTableListLen == currentEntry->tableListLength &&
+ (memcmp(¤tEntry->tableList[0], displayTableList,
+ displayTableListLen)) == 0) {
+ /* Move the table to the top of the table chain. */
+ if (prevEntry != NULL) {
+ prevEntry->next = currentEntry->next;
+ currentEntry->next = displayTableChain;
+ displayTableChain = currentEntry;
+ }
+ *displayTable = currentEntry->table;
+ break;
+ }
+ prevEntry = currentEntry;
+ currentEntry = currentEntry->next;
+ }
+ }
+ if ((translationTable && *translationTable == NULL) ||
+ (displayTable && *displayTable == NULL)) {
+ TranslationTableHeader *newTranslationTable = NULL;
+ DisplayTableHeader *newDisplayTable = NULL;
+ if (compileTable(translationTableList, displayTableList,
+ (translationTable && *translationTable == NULL) ? &newTranslationTable
+ : NULL,
+ (displayTable && *displayTable == NULL) ? &newDisplayTable : NULL)) {
+ /* Add a new entry to the top of the table chain. */
+ if (newTranslationTable != NULL) {
+ int entrySize =
+ sizeof(TranslationTableChainEntry) + translationTableListLen;
+ TranslationTableChainEntry *newEntry = malloc(entrySize);
+ if (!newEntry) _lou_outOfMemory();
+ newEntry->next = translationTableChain;
+ newEntry->table = newTranslationTable;
+ newEntry->tableListLength = translationTableListLen;
+ memcpy(&newEntry->tableList[0], translationTableList,
+ translationTableListLen);
+ translationTableChain = newEntry;
+ *translationTable = newTranslationTable;
+ }
+ if (newDisplayTable != NULL) {
+ int entrySize = sizeof(DisplayTableChainEntry) + displayTableListLen;
+ DisplayTableChainEntry *newEntry = malloc(entrySize);
+ if (!newEntry) _lou_outOfMemory();
+ newEntry->next = displayTableChain;
+ newEntry->table = newDisplayTable;
+ newEntry->tableListLength = displayTableListLen;
+ memcpy(&newEntry->tableList[0], displayTableList, displayTableListLen);
+ displayTableChain = newEntry;
+ *displayTable = newDisplayTable;
+ }
+ } else {
+ _lou_logMessage(
+ LOU_LOG_ERROR, "%s could not be compiled", translationTableList);
+ return;
+ }
+ }
+}
+
+int EXPORT_CALL
+lou_checkTable(const char *tableList) {
+ if (lou_getTable(tableList)) return 1;
+ return 0;
+}
+
+formtype EXPORT_CALL
+lou_getTypeformForEmphClass(const char *tableList, const char *emphClass) {
+ int i;
+ const TranslationTableHeader *table = _lou_getTranslationTable(tableList);
+ if (!table) return 0;
+ for (i = 0; table->emphClasses[i]; i++)
+ if (strcmp(emphClass, table->emphClasses[i]) == 0) return italic << i;
+ return 0;
+}
+
+static unsigned char *destSpacing = NULL;
+static int sizeDestSpacing = 0;
+static formtype *typebuf = NULL;
+static unsigned int *wordBuffer = NULL;
+static EmphasisInfo *emphasisBuffer = NULL;
+static int sizeTypebuf = 0;
+static widechar *passbuf[MAXPASSBUF] = { NULL };
+static int sizePassbuf[MAXPASSBUF] = { 0 };
+static int *posMapping1 = NULL;
+static int sizePosMapping1 = 0;
+static int *posMapping2 = NULL;
+static int sizePosMapping2 = 0;
+static int *posMapping3 = NULL;
+static int sizePosMapping3 = 0;
+void *EXPORT_CALL
+_lou_allocMem(AllocBuf buffer, int index, int srcmax, int destmax) {
+ if (srcmax < 1024) srcmax = 1024;
+ if (destmax < 1024) destmax = 1024;
+ switch (buffer) {
+ case alloc_typebuf:
+ if (destmax > sizeTypebuf) {
+ if (typebuf != NULL) free(typebuf);
+ // TODO: should this be srcmax?
+ typebuf = malloc((destmax + 4) * sizeof(formtype));
+ if (!typebuf) _lou_outOfMemory();
+ sizeTypebuf = destmax;
+ }
+ return typebuf;
+
+ case alloc_wordBuffer:
+
+ if (wordBuffer != NULL) free(wordBuffer);
+ wordBuffer = malloc((srcmax + 4) * sizeof(unsigned int));
+ if (!wordBuffer) _lou_outOfMemory();
+ return wordBuffer;
+
+ case alloc_emphasisBuffer:
+
+ if (emphasisBuffer != NULL) free(emphasisBuffer);
+ emphasisBuffer = malloc((srcmax + 4) * sizeof(EmphasisInfo));
+ if (!emphasisBuffer) _lou_outOfMemory();
+ return emphasisBuffer;
+
+ case alloc_destSpacing:
+ if (destmax > sizeDestSpacing) {
+ if (destSpacing != NULL) free(destSpacing);
+ destSpacing = malloc(destmax + 4);
+ if (!destSpacing) _lou_outOfMemory();
+ sizeDestSpacing = destmax;
+ }
+ return destSpacing;
+ case alloc_passbuf:
+ if (index < 0 || index >= MAXPASSBUF) {
+ _lou_logMessage(LOU_LOG_FATAL, "Index out of bounds: %d\n", index);
+ exit(3);
+ }
+ if (destmax > sizePassbuf[index]) {
+ if (passbuf[index] != NULL) free(passbuf[index]);
+ passbuf[index] = malloc((destmax + 4) * CHARSIZE);
+ if (!passbuf[index]) _lou_outOfMemory();
+ sizePassbuf[index] = destmax;
+ }
+ return passbuf[index];
+ case alloc_posMapping1: {
+ int mapSize;
+ if (srcmax >= destmax)
+ mapSize = srcmax;
+ else
+ mapSize = destmax;
+ if (mapSize > sizePosMapping1) {
+ if (posMapping1 != NULL) free(posMapping1);
+ posMapping1 = malloc((mapSize + 4) * sizeof(int));
+ if (!posMapping1) _lou_outOfMemory();
+ sizePosMapping1 = mapSize;
+ }
+ }
+ return posMapping1;
+ case alloc_posMapping2: {
+ int mapSize;
+ if (srcmax >= destmax)
+ mapSize = srcmax;
+ else
+ mapSize = destmax;
+ if (mapSize > sizePosMapping2) {
+ if (posMapping2 != NULL) free(posMapping2);
+ posMapping2 = malloc((mapSize + 4) * sizeof(int));
+ if (!posMapping2) _lou_outOfMemory();
+ sizePosMapping2 = mapSize;
+ }
+ }
+ return posMapping2;
+ case alloc_posMapping3: {
+ int mapSize;
+ if (srcmax >= destmax)
+ mapSize = srcmax;
+ else
+ mapSize = destmax;
+ if (mapSize > sizePosMapping3) {
+ if (posMapping3 != NULL) free(posMapping3);
+ posMapping3 = malloc((mapSize + 4) * sizeof(int));
+ if (!posMapping3) _lou_outOfMemory();
+ sizePosMapping3 = mapSize;
+ }
+ }
+ return posMapping3;
+ default:
+ return NULL;
+ }
+}
+
+void EXPORT_CALL
+lou_free(void) {
+ TranslationTableChainEntry *currentEntry;
+ TranslationTableChainEntry *previousEntry;
+ lou_logEnd();
+ if (translationTableChain != NULL) {
+ currentEntry = translationTableChain;
+ while (currentEntry) {
+ int i;
+ TranslationTableHeader *t = (TranslationTableHeader *)currentEntry->table;
+ for (i = 0; t->emphClasses[i]; i++) free(t->emphClasses[i]);
+ if (t->characterClasses) deallocateCharacterClasses(t);
+ if (t->ruleNames) deallocateRuleNames(t);
+ free(t);
+ previousEntry = currentEntry;
+ currentEntry = currentEntry->next;
+ free(previousEntry);
+ }
+ translationTableChain = NULL;
+ }
+ if (typebuf != NULL) free(typebuf);
+ typebuf = NULL;
+ if (wordBuffer != NULL) free(wordBuffer);
+ wordBuffer = NULL;
+ if (emphasisBuffer != NULL) free(emphasisBuffer);
+ emphasisBuffer = NULL;
+ sizeTypebuf = 0;
+ if (destSpacing != NULL) free(destSpacing);
+ destSpacing = NULL;
+ sizeDestSpacing = 0;
+ {
+ int k;
+ for (k = 0; k < MAXPASSBUF; k++) {
+ if (passbuf[k] != NULL) free(passbuf[k]);
+ passbuf[k] = NULL;
+ sizePassbuf[k] = 0;
+ }
+ }
+ if (posMapping1 != NULL) free(posMapping1);
+ posMapping1 = NULL;
+ sizePosMapping1 = 0;
+ if (posMapping2 != NULL) free(posMapping2);
+ posMapping2 = NULL;
+ sizePosMapping2 = 0;
+ if (posMapping3 != NULL) free(posMapping3);
+ posMapping3 = NULL;
+ sizePosMapping3 = 0;
+ opcodeLengths[0] = 0;
+}
+
+const char *EXPORT_CALL
+lou_version(void) {
+ static const char *version = PACKAGE_VERSION;
+ return version;
+}
+
+int EXPORT_CALL
+lou_charSize(void) {
+ return CHARSIZE;
+}
+
+int EXPORT_CALL
+lou_compileString(const char *tableList, const char *inString) {
+ TranslationTableHeader *table;
+ DisplayTableHeader *displayTable;
+ getTable(tableList, tableList, &table, &displayTable);
+ if (!table) return 0;
+ if (!compileString(inString, &table, &displayTable)) return 0;
+ return 1;
+}
+
+int EXPORT_CALL
+_lou_compileTranslationRule(const char *tableList, const char *inString) {
+ TranslationTableHeader *table;
+ getTable(tableList, NULL, &table, NULL);
+ return compileString(inString, &table, NULL);
+}
+
+int EXPORT_CALL
+_lou_compileDisplayRule(const char *tableList, const char *inString) {
+ DisplayTableHeader *table;
+ getTable(NULL, tableList, NULL, &table);
+ return compileString(inString, NULL, &table);
+}
+
+/**
+ * This procedure provides a target for cals that serve as breakpoints
+ * for gdb.
+ */
+// char *EXPORT_CALL
+// lou_getTablePaths (void)
+// {
+// static char paths[MAXSTRING];
+// static char scratchBuf[MAXSTRING];
+// char *pathList;
+// strcpy (paths, tablePath);
+// strcat (paths, ",");
+// pathList = getenv ("LOUIS_TABLEPATH");
+// if (pathList)
+// {
+// strcat (paths, pathList);
+// strcat (paths, ",");
+// }
+// pathList = getcwd (scratchBuf, MAXSTRING);
+// if (pathList)
+// {
+// strcat (paths, pathList);
+// strcat (paths, ",");
+// }
+// pathList = lou_getDataPath ();
+// if (pathList)
+// {
+// strcat (paths, pathList);
+// strcat (paths, ",");
+// }
+// #ifdef _WIN32
+// strcpy (paths, lou_getProgramPath ());
+// strcat (paths, "\\share\\liblouss\\tables\\");
+// #else
+// strcpy (paths, TABLESDIR);
+// #endif
+// return paths;
+// }
diff --git a/liblouis/internal.h b/liblouis/internal.h
new file mode 100644
index 0000000..9ce579a
--- /dev/null
+++ b/liblouis/internal.h
@@ -0,0 +1,846 @@
+/* liblouis Braille Translation and Back-Translation Library
+
+ Based on the Linux screenreader BRLTTY, copyright (C) 1999-2006 by The
+ BRLTTY Team
+
+ Copyright (C) 2004, 2005, 2006 ViewPlus Technologies, Inc. www.viewplus.com
+ Copyright (C) 2004, 2005, 2006 JJB Software, Inc. www.jjb-software.com
+ Copyright (C) 2016 Mike Gray, American Printing House for the Blind
+ Copyright (C) 2016 Davy Kager, Dedicon
+
+ This file is part of liblouis.
+
+ liblouis is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 2.1 of the License, or
+ (at your option) any later version.
+
+ liblouis is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file
+ * @brief Internal API of liblouis
+ */
+
+#ifndef __LOUIS_H_
+#define __LOUIS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdio.h>
+#include "liblouis.h"
+
+#ifdef _WIN32
+#define PATH_SEP ';'
+#define DIR_SEP '\\'
+#else
+#define PATH_SEP ':'
+#define DIR_SEP '/'
+#endif
+
+#ifdef _MSC_VER
+#define strcasecmp _stricmp
+#endif
+
+#define NUMSWAPS 50
+#define NUMVAR 50
+#define LETSIGNSIZE 128
+#define SEQPATTERNSIZE 128
+#define CHARSIZE sizeof(widechar)
+#define DEFAULTRULESIZE 50
+
+typedef struct intCharTupple {
+ int key;
+ char value;
+} intCharTupple;
+
+/* HASHNUM must be prime */
+#define HASHNUM 1123
+
+#define MAXPASS 4
+#define MAXSTRING 2048
+
+#define MAX_EMPH_CLASSES 10 // {emph_1...emph_10} in typeforms enum (liblouis.h)
+
+typedef unsigned int TranslationTableOffset;
+#define OFFSETSIZE sizeof(TranslationTableOffset)
+
+typedef enum {
+ CTC_Space = 0x1,
+ CTC_Letter = 0x2,
+ CTC_Digit = 0x4,
+ CTC_Punctuation = 0x8,
+ CTC_UpperCase = 0x10,
+ CTC_LowerCase = 0x20,
+ CTC_Math = 0x40,
+ CTC_Sign = 0x80,
+ CTC_LitDigit = 0x100,
+ CTC_Class1 = 0x200,
+ CTC_Class2 = 0x400,
+ CTC_Class3 = 0x800,
+ CTC_Class4 = 0x1000,
+ CTC_SeqDelimiter = 0x2000,
+ CTC_SeqBefore = 0x4000,
+ CTC_SeqAfter = 0x8000,
+ CTC_UserDefined0 = 0x10000, // class 5
+ CTC_UserDefined1 = 0x20000,
+ CTC_UserDefined2 = 0x40000,
+ CTC_UserDefined3 = 0x80000,
+ CTC_UserDefined4 = 0x100000,
+ CTC_UserDefined5 = 0x200000,
+ CTC_UserDefined6 = 0x400000,
+ CTC_UserDefined7 = 0x800000, // class 12
+ CTC_CapsMode = 0x1000000,
+ CTC_EmphMode = 0x2000000,
+ CTC_NumericMode = 0x4000000,
+ CTC_NumericNoContract = 0x8000000,
+ CTC_EndOfInput = 0x10000000, // only used by pattern matcher
+ CTC_EmpMatch = 0x20000000, // only used in TranslationTableRule->before and
+ // TranslationTableRule->after
+ CTC_MidEndNumericMode = 0x40000000,
+ // 33 more bits available in a unsigned long long (at least 64 bits)
+ // currently used for classes 13 to 45
+ CTC_Class13 = 0x80000000,
+} TranslationTableCharacterAttribute;
+
+typedef enum {
+ pass_first = '`',
+ pass_last = '~',
+ pass_lookback = '_',
+ pass_string = '\"',
+ pass_dots = '@',
+ pass_omit = '?',
+ pass_startReplace = '[',
+ pass_endReplace = ']',
+ pass_startGroup = '{',
+ pass_endGroup = '}',
+ pass_variable = '#',
+ pass_not = '!',
+ pass_search = '/',
+ pass_any = 'a',
+ pass_digit = 'd',
+ pass_litDigit = 'D',
+ pass_letter = 'l',
+ pass_math = 'm',
+ pass_punctuation = 'p',
+ pass_sign = 'S',
+ pass_space = 's',
+ pass_uppercase = 'U',
+ pass_lowercase = 'u',
+ pass_class1 = 'w',
+ pass_class2 = 'x',
+ pass_class3 = 'y',
+ pass_class4 = 'z',
+ pass_attributes = '$',
+ pass_groupstart = '{',
+ pass_groupend = '}',
+ pass_groupreplace = ';',
+ pass_swap = '%',
+ pass_hyphen = '-',
+ pass_until = '.',
+ pass_eq = '=',
+ pass_lt = '<',
+ pass_gt = '>',
+ pass_endTest = 32,
+ pass_plus = '+',
+ pass_copy = '*',
+ pass_leftParen = '(',
+ pass_rightParen = ')',
+ pass_comma = ',',
+ pass_lteq = 130,
+ pass_gteq = 131,
+ pass_invalidToken = 132,
+ pass_noteq = 133,
+ pass_and = 134,
+ pass_or = 135,
+ pass_nameFound = 136,
+ pass_numberFound = 137,
+ pass_boolean = 138,
+ pass_class = 139,
+ pass_define = 140,
+ pass_emphasis = 141,
+ pass_group = 142,
+ pass_mark = 143,
+ pass_repGroup = 143,
+ pass_script = 144,
+ pass_noMoreTokens = 145,
+ pass_replace = 146,
+ pass_if = 147,
+ pass_then = 148,
+ pass_all = 255
+} pass_Codes;
+
+typedef unsigned long long TranslationTableCharacterAttributes;
+
+typedef struct {
+ TranslationTableOffset next;
+ widechar lookFor;
+ widechar found;
+} CharOrDots;
+
+typedef struct {
+ TranslationTableOffset next;
+ TranslationTableOffset definitionRule;
+ TranslationTableOffset otherRules;
+ TranslationTableCharacterAttributes attributes;
+ widechar realchar;
+ widechar uppercase;
+ widechar lowercase;
+} TranslationTableCharacter;
+
+typedef enum { /* Op codes */
+ CTO_IncludeFile,
+ CTO_Locale, /* Deprecated, do not use */
+ CTO_Undefined,
+ /* Do not change the order of the following opcodes! */
+ CTO_CapsLetter,
+ CTO_BegCapsWord,
+ CTO_EndCapsWord,
+ CTO_BegCaps,
+ CTO_EndCaps,
+ CTO_BegCapsPhrase,
+ CTO_EndCapsPhrase,
+ CTO_LenCapsPhrase,
+ /* End of ordered opcodes */
+ CTO_LetterSign,
+ CTO_NoLetsignBefore,
+ CTO_NoLetsign,
+ CTO_NoLetsignAfter,
+ CTO_NumberSign,
+ CTO_NumericModeChars,
+ CTO_MidEndNumericModeChars,
+ CTO_NumericNoContractChars,
+ CTO_SeqDelimiter,
+ CTO_SeqBeforeChars,
+ CTO_SeqAfterChars,
+ CTO_SeqAfterPattern,
+ CTO_SeqAfterExpression,
+ CTO_EmphClass,
+
+ /* Do not change the order of the following opcodes! */
+ CTO_EmphLetter,
+ CTO_BegEmphWord,
+ CTO_EndEmphWord,
+ CTO_BegEmph,
+ CTO_EndEmph,
+ CTO_BegEmphPhrase,
+ CTO_EndEmphPhrase,
+ CTO_LenEmphPhrase,
+ /* End of ordered opcodes */
+
+ CTO_CapsModeChars,
+ CTO_EmphModeChars,
+ CTO_BegComp,
+ CTO_CompBegEmph1,
+ CTO_CompEndEmph1,
+ CTO_CompBegEmph2,
+ CTO_CompEndEmph2,
+ CTO_CompBegEmph3,
+ CTO_CompEndEmph3,
+ CTO_CompCapSign,
+ CTO_CompBegCaps,
+ CTO_CompEndCaps,
+ CTO_EndComp,
+ CTO_NoContractSign,
+ CTO_MultInd,
+ CTO_CompDots,
+ CTO_Comp6,
+ CTO_Class, /* define a character class */
+ CTO_After, /* only match if after character in class */
+ CTO_Before, /* only match if before character in class 30 */
+ CTO_NoBack,
+ CTO_NoFor,
+ CTO_EmpMatchBefore,
+ CTO_EmpMatchAfter,
+ CTO_SwapCc,
+ CTO_SwapCd,
+ CTO_SwapDd,
+ CTO_Space,
+ CTO_Digit,
+ CTO_Punctuation,
+ CTO_Math,
+ CTO_Sign,
+ CTO_Letter,
+ CTO_UpperCase,
+ CTO_LowerCase,
+ CTO_Grouping,
+ CTO_UpLow,
+ CTO_LitDigit,
+ CTO_Display,
+ CTO_Replace,
+ CTO_Context,
+ CTO_Correct,
+ CTO_Pass2,
+ CTO_Pass3,
+ CTO_Pass4,
+ CTO_Repeated,
+ CTO_RepWord,
+ CTO_CapsNoCont,
+ CTO_Always,
+ CTO_ExactDots,
+ CTO_NoCross,
+ CTO_Syllable,
+ CTO_NoCont,
+ CTO_CompBrl,
+ CTO_Literal,
+ CTO_LargeSign,
+ CTO_WholeWord,
+ CTO_PartWord,
+ CTO_JoinNum,
+ CTO_JoinableWord,
+ CTO_LowWord,
+ CTO_Contraction,
+ CTO_SuffixableWord, /** whole word or beginning of word */
+ CTO_PrefixableWord, /** whole word or end of word */
+ CTO_BegWord, /** beginning of word only */
+ CTO_BegMidWord, /** beginning or middle of word */
+ CTO_MidWord, /** middle of word only 20 */
+ CTO_MidEndWord, /** middle or end of word */
+ CTO_EndWord, /** end of word only */
+ CTO_PrePunc, /** punctuation in string at beginning of word */
+ CTO_PostPunc, /** punctuation in string at end of word */
+ CTO_BegNum, /** beginning of number */
+ CTO_MidNum, /** middle of number, e.g., decimal point */
+ CTO_EndNum, /** end of number */
+ CTO_DecPoint,
+ CTO_Hyphen,
+ // CTO_Apostrophe,
+ // CTO_Initial,
+ CTO_NoBreak,
+ CTO_Match,
+ CTO_BackMatch,
+ CTO_Attribute,
+ CTO_None,
+
+ /* More internal opcodes */
+ CTO_LetterRule,
+ CTO_NumberRule,
+ CTO_NoContractRule,
+
+ /* Start of (11 x 9) internal opcodes values that match
+ * {"singlelettercaps"..."lenemphphrase"}
+ * Do not change the order of the following opcodes! */
+ CTO_CapsLetterRule,
+ CTO_BegCapsWordRule,
+ CTO_EndCapsWordRule,
+ CTO_BegCapsRule,
+ CTO_EndCapsRule,
+ CTO_BegCapsPhraseRule,
+ CTO_EndCapsPhraseBeforeRule,
+ CTO_EndCapsPhraseAfterRule,
+ CTO_Emph1LetterRule,
+ CTO_BegEmph1WordRule,
+ CTO_EndEmph1WordRule,
+ CTO_BegEmph1Rule,
+ CTO_EndEmph1Rule,
+ CTO_BegEmph1PhraseRule,
+ CTO_EndEmph1PhraseBeforeRule,
+ CTO_EndEmph1PhraseAfterRule,
+ CTO_Emph2LetterRule,
+ CTO_BegEmph2WordRule,
+ CTO_EndEmph2WordRule,
+ CTO_BegEmph2Rule,
+ CTO_EndEmph2Rule,
+ CTO_BegEmph2PhraseRule,
+ CTO_EndEmph2PhraseBeforeRule,
+ CTO_EndEmph2PhraseAfterRule,
+ CTO_Emph3LetterRule,
+ CTO_BegEmph3WordRule,
+ CTO_EndEmph3WordRule,
+ CTO_BegEmph3Rule,
+ CTO_EndEmph3Rule,
+ CTO_BegEmph3PhraseRule,
+ CTO_EndEmph3PhraseBeforeRule,
+ CTO_EndEmph3PhraseAfterRule,
+ CTO_Emph4LetterRule,
+ CTO_BegEmph4WordRule,
+ CTO_EndEmph4WordRule,
+ CTO_BegEmph4Rule,
+ CTO_EndEmph4Rule,
+ CTO_BegEmph4PhraseRule,
+ CTO_EndEmph4PhraseBeforeRule,
+ CTO_EndEmph4PhraseAfterRule,
+ CTO_Emph5LetterRule,
+ CTO_BegEmph5WordRule,
+ CTO_EndEmph5WordRule,
+ CTO_BegEmph5Rule,
+ CTO_EndEmph5Rule,
+ CTO_BegEmph5PhraseRule,
+ CTO_EndEmph5PhraseBeforeRule,
+ CTO_EndEmph5PhraseAfterRule,
+ CTO_Emph6LetterRule,
+ CTO_BegEmph6WordRule,
+ CTO_EndEmph6WordRule,
+ CTO_BegEmph6Rule,
+ CTO_EndEmph6Rule,
+ CTO_BegEmph6PhraseRule,
+ CTO_EndEmph6PhraseBeforeRule,
+ CTO_EndEmph6PhraseAfterRule,
+ CTO_Emph7LetterRule,
+ CTO_BegEmph7WordRule,
+ CTO_EndEmph7WordRule,
+ CTO_BegEmph7Rule,
+ CTO_EndEmph7Rule,
+ CTO_BegEmph7PhraseRule,
+ CTO_EndEmph7PhraseBeforeRule,
+ CTO_EndEmph7PhraseAfterRule,
+ CTO_Emph8LetterRule,
+ CTO_BegEmph8WordRule,
+ CTO_EndEmph8WordRule,
+ CTO_BegEmph8Rule,
+ CTO_EndEmph8Rule,
+ CTO_BegEmph8PhraseRule,
+ CTO_EndEmph8PhraseBeforeRule,
+ CTO_EndEmph8PhraseAfterRule,
+ CTO_Emph9LetterRule,
+ CTO_BegEmph9WordRule,
+ CTO_EndEmph9WordRule,
+ CTO_BegEmph9Rule,
+ CTO_EndEmph9Rule,
+ CTO_BegEmph9PhraseRule,
+ CTO_EndEmph9PhraseBeforeRule,
+ CTO_EndEmph9PhraseAfterRule,
+ CTO_Emph10LetterRule,
+ CTO_BegEmph10WordRule,
+ CTO_EndEmph10WordRule,
+ CTO_BegEmph10Rule,
+ CTO_EndEmph10Rule,
+ CTO_BegEmph10PhraseRule,
+ CTO_EndEmph10PhraseBeforeRule,
+ CTO_EndEmph10PhraseAfterRule,
+ /* End of ordered (10 x 9) internal opcodes */
+
+ CTO_BegCompRule,
+ CTO_CompBegEmph1Rule,
+ CTO_CompEndEmph1Rule,
+ CTO_CompBegEmph2Rule,
+ CTO_CompEndEmrh2Rule,
+ CTO_CompBegEmph3Rule,
+ CTO_CompEndEmph3Rule,
+ CTO_CompCapSignRule,
+ CTO_CompBegCapsRule,
+ CTO_CompEndCapsRule,
+ CTO_EndCompRule,
+ CTO_CapsNoContRule,
+ CTO_All
+} TranslationTableOpcode;
+
+typedef struct {
+ TranslationTableOffset charsnext; /** next chars entry */
+ TranslationTableOffset dotsnext; /** next dots entry */
+ TranslationTableCharacterAttributes after; /** character types which must follow */
+ TranslationTableCharacterAttributes before; /** character types which must precede */
+ TranslationTableOffset patterns; /** before and after patterns */
+ TranslationTableOpcode opcode; /** rule for testing validity of replacement */
+ short charslen; /** length of string to be replaced */
+ short dotslen; /** length of replacement string */
+ widechar charsdots[DEFAULTRULESIZE]; /** find and replacement strings */
+} TranslationTableRule;
+
+typedef struct /* state transition */
+{
+ widechar ch;
+ widechar newState;
+} HyphenationTrans;
+
+typedef union {
+ HyphenationTrans *pointer;
+ TranslationTableOffset offset;
+} PointOff;
+
+typedef struct /* one state */
+{
+ PointOff trans;
+ TranslationTableOffset hyphenPattern;
+ widechar fallbackState;
+ widechar numTrans;
+} HyphenationState;
+
+typedef struct CharacterClass {
+ struct CharacterClass *next;
+ TranslationTableCharacterAttributes attribute;
+ widechar length;
+ widechar name[1];
+} CharacterClass;
+
+typedef struct RuleName {
+ struct RuleName *next;
+ TranslationTableOffset ruleOffset;
+ widechar length;
+ widechar name[1];
+} RuleName;
+
+typedef struct {
+ TranslationTableOffset tableSize;
+ TranslationTableOffset bytesUsed;
+ TranslationTableOffset charToDots[HASHNUM];
+ TranslationTableOffset dotsToChar[HASHNUM];
+ TranslationTableOffset ruleArea[1]; /** Space for storing all rules and values */
+} DisplayTableHeader;
+
+/**
+ * Translation table header
+ */
+typedef struct { /* translation table */
+ int capsNoCont;
+ int numPasses;
+ int corrections;
+ int syllables;
+ int usesSequences;
+ int usesNumericMode;
+ int usesEmphMode;
+ TranslationTableOffset tableSize;
+ TranslationTableOffset bytesUsed;
+ TranslationTableOffset undefined;
+ TranslationTableOffset letterSign;
+ TranslationTableOffset numberSign;
+ TranslationTableOffset noContractSign;
+ widechar seqPatterns[SEQPATTERNSIZE];
+ char *emphClasses[MAX_EMPH_CLASSES + 1];
+ int seqPatternsCount;
+ widechar seqAfterExpression[SEQPATTERNSIZE];
+ int seqAfterExpressionLength;
+
+ /* emphRules, including caps. */
+ TranslationTableOffset emphRules[MAX_EMPH_CLASSES + 1][9];
+
+ /* state needed during compilation */
+ CharacterClass *characterClasses;
+ TranslationTableCharacterAttributes nextCharacterClassAttribute;
+ RuleName *ruleNames;
+
+ TranslationTableOffset begComp;
+ TranslationTableOffset compBegEmph1;
+ TranslationTableOffset compEndEmph1;
+ TranslationTableOffset compBegEmph2;
+ TranslationTableOffset compEndEmph2;
+ TranslationTableOffset compBegEmph3;
+ TranslationTableOffset compEndEmph3;
+ TranslationTableOffset compCapSign;
+ TranslationTableOffset compBegCaps;
+ TranslationTableOffset compEndCaps;
+ TranslationTableOffset endComp;
+ TranslationTableOffset hyphenStatesArray;
+ widechar noLetsignBefore[LETSIGNSIZE];
+ int noLetsignBeforeCount;
+ widechar noLetsign[LETSIGNSIZE];
+ int noLetsignCount;
+ widechar noLetsignAfter[LETSIGNSIZE];
+ int noLetsignAfterCount;
+ TranslationTableOffset characters[HASHNUM]; /** Character definitions */
+ TranslationTableOffset dots[HASHNUM]; /** Dot definitions */
+ TranslationTableOffset compdotsPattern[256];
+ TranslationTableOffset swapDefinitions[NUMSWAPS];
+ TranslationTableOffset forPassRules[MAXPASS + 1];
+ TranslationTableOffset backPassRules[MAXPASS + 1];
+ TranslationTableOffset forRules[HASHNUM]; /** chains of forward rules */
+ TranslationTableOffset backRules[HASHNUM]; /** Chains of backward rules */
+ TranslationTableOffset ruleArea[1]; /** Space for storing all rules and values */
+} TranslationTableHeader;
+
+typedef enum {
+ alloc_typebuf,
+ alloc_wordBuffer,
+ alloc_emphasisBuffer,
+ alloc_destSpacing,
+ alloc_passbuf,
+ alloc_posMapping1,
+ alloc_posMapping2,
+ alloc_posMapping3
+} AllocBuf;
+
+#define MAXPASSBUF 3
+
+typedef enum {
+ capsRule = 0,
+ emph1Rule = 1,
+ emph2Rule = 2,
+ emph3Rule = 3,
+ emph4Rule = 4,
+ emph5Rule = 5,
+ emph6Rule = 6,
+ emph7Rule = 7,
+ emph8Rule = 8,
+ emph9Rule = 9,
+ emph10Rule = 10
+} EmphRuleNumber;
+
+typedef enum {
+ begPhraseOffset = 0,
+ endPhraseBeforeOffset = 1,
+ endPhraseAfterOffset = 2,
+ begOffset = 3,
+ endOffset = 4,
+ letterOffset = 5,
+ begWordOffset = 6,
+ endWordOffset = 7,
+ lenPhraseOffset = 8
+} EmphCodeOffset;
+
+/* Grouping the begin, end, word and symbol bits and using the type of
+ * a single bit group for representing the emphasis classes allows us
+ * to do simple bit operations. */
+
+typedef struct {
+ unsigned int begin : 16;
+ unsigned int end : 16;
+ unsigned int word : 16;
+ unsigned int symbol : 16;
+} EmphasisInfo;
+
+/* An emphasis class is a bit field that contains a single "1" */
+typedef unsigned int EmphasisClass;
+
+typedef enum { noEncoding, bigEndian, littleEndian, ascii8 } EncodingType;
+
+typedef struct {
+ const char *fileName;
+ FILE *in;
+ int lineNumber;
+ EncodingType encoding;
+ int status;
+ int linelen;
+ int linepos;
+ int checkencoding[2];
+ widechar line[MAXSTRING];
+} FileInfo;
+
+/* The following function definitions are hooks into
+ * compileTranslationTable.c. Some are used by other library modules.
+ * Others are used by tools like lou_allround.c and lou_debug.c. */
+
+/**
+ * Comma separated list of directories to search for tables.
+ */
+char *EXPORT_CALL
+_lou_getTablePath(void);
+
+/**
+ * Resolve tableList against base.
+ */
+char **EXPORT_CALL
+_lou_resolveTable(const char *tableList, const char *base);
+
+/**
+ * The default table resolver
+ */
+char **EXPORT_CALL
+_lou_defaultTableResolver(const char *tableList, const char *base);
+
+/**
+ * Return single-cell dot pattern corresponding to a character.
+ * TODO: move to commonTranslationFunctions.c
+ */
+widechar EXPORT_CALL
+_lou_getDotsForChar(widechar c, const DisplayTableHeader *table);
+
+/**
+ * Return character corresponding to a single-cell dot pattern.
+ * TODO: move to commonTranslationFunctions.c
+ */
+widechar EXPORT_CALL
+_lou_getCharFromDots(widechar d, const DisplayTableHeader *table);
+
+void EXPORT_CALL
+_lou_getTable(const char *tableList, const char *displayTableList,
+ const TranslationTableHeader **translationTable,
+ const DisplayTableHeader **displayTable);
+
+const TranslationTableHeader *EXPORT_CALL
+_lou_getTranslationTable(const char *tableList);
+
+const DisplayTableHeader *EXPORT_CALL
+_lou_getDisplayTable(const char *tableList);
+
+int EXPORT_CALL
+_lou_compileTranslationRule(const char *tableList, const char *inString);
+
+int EXPORT_CALL
+_lou_compileDisplayRule(const char *tableList, const char *inString);
+
+/**
+ * Allocate memory for internal buffers
+ *
+ * Used by lou_translateString.c and lou_backTranslateString.c ONLY
+ * to allocate memory for internal buffers.
+ * TODO: move to utils.c
+ */
+void *EXPORT_CALL
+_lou_allocMem(AllocBuf buffer, int index, int srcmax, int destmax);
+
+/**
+ * Hash function for character strings
+ *
+ * @param lowercase Whether to convert the string to lowercase because
+ * making the hash of it.
+ */
+unsigned long int EXPORT_CALL
+_lou_stringHash(const widechar *c, int lowercase, const TranslationTableHeader *table);
+
+/**
+ * Hash function for single characters
+ */
+unsigned long int EXPORT_CALL
+_lou_charHash(widechar c);
+
+/**
+ * Return a string in the same format as the characters operand in opcodes
+ */
+const char *EXPORT_CALL
+_lou_showString(widechar const *chars, int length, int forceHex);
+
+/**
+ * Print out dot numbers
+ *
+ * @return a string containing the dot numbers. The longest possible
+ * output is "\123456789ABCDEF0/"
+ */
+const char *EXPORT_CALL
+_lou_unknownDots(widechar dots);
+
+/**
+ * Return a character string in the format of the dots operand
+ */
+const char *EXPORT_CALL
+_lou_showDots(widechar const *dots, int length);
+
+/**
+ * Return a character string where the attributes are indicated
+ * by the attribute letters used in multipass opcodes
+ */
+char *EXPORT_CALL
+_lou_showAttributes(TranslationTableCharacterAttributes a);
+
+/**
+ * Return number of the opcode
+ *
+ * @param toFind the opcodes
+ */
+TranslationTableOpcode EXPORT_CALL
+_lou_findOpcodeNumber(const char *tofind);
+
+/**
+ * Return the name of the opcode associated with an opcode number
+ *
+ * @param opcode an opcode
+ */
+const char *EXPORT_CALL
+_lou_findOpcodeName(TranslationTableOpcode opcode);
+
+/**
+ * Convert string to wide characters
+ *
+ * Takes a character string and produces a sequence of wide characters.
+ * Opposite of _lou_showString.
+ *
+ * @param inString the input string
+ * @param outString the output wide char sequence
+ * @return length of the widechar sequence.
+ */
+int EXPORT_CALL
+_lou_extParseChars(const char *inString, widechar *outString);
+
+/**
+ * Convert string to wide characters containing dot patterns
+ *
+ * Takes a character string and produces a sequence of wide characters
+ * containing dot patterns. Opposite of _lou_showDots.
+ * @param inString the input string
+ * @param outString the output wide char sequence
+ * @return length of the widechar sequence.
+ */
+int EXPORT_CALL
+_lou_extParseDots(const char *inString, widechar *outString);
+
+int EXPORT_CALL
+_lou_translate(const char *tableList, const char *displayTableList, const widechar *inbuf,
+ int *inlen, widechar *outbuf, int *outlen, formtype *typeform, char *spacing,
+ int *outputPos, int *inputPos, int *cursorPos, int mode,
+ const TranslationTableRule **rules, int *rulesLen);
+
+int EXPORT_CALL
+_lou_backTranslate(const char *tableList, const char *displayTableList,
+ const widechar *inbuf, int *inlen, widechar *outbuf, int *outlen,
+ formtype *typeform, char *spacing, int *outputPos, int *inputPos, int *cursorPos,
+ int mode, const TranslationTableRule **rules, int *rulesLen);
+
+void EXPORT_CALL
+_lou_resetPassVariables(void);
+
+int EXPORT_CALL
+_lou_handlePassVariableTest(const widechar *instructions, int *IC, int *itsTrue);
+
+int EXPORT_CALL
+_lou_handlePassVariableAction(const widechar *instructions, int *IC);
+
+int EXPORT_CALL
+_lou_pattern_compile(const widechar *input, const int input_max, widechar *expr_data,
+ const int expr_max, const TranslationTableHeader *t);
+
+void EXPORT_CALL
+_lou_pattern_reverse(widechar *expr_data);
+
+int EXPORT_CALL
+_lou_pattern_check(const widechar *input, const int input_start, const int input_minmax,
+ const int input_dir, const widechar *expr_data, const TranslationTableHeader *t);
+
+/**
+ * Read a line of widechar's from an input file
+ */
+int EXPORT_CALL
+_lou_getALine(FileInfo *info);
+
+#ifdef DEBUG
+/* Can be inserted in code to be used as a breakpoint in gdb */
+void EXPORT_CALL
+_lou_debugHook(void);
+#endif
+
+/**
+ * Print an out-of-memory message and exit
+ */
+void EXPORT_CALL
+_lou_outOfMemory(void);
+
+/**
+ * Helper for logging a widechar buffer
+ */
+void EXPORT_CALL
+_lou_logWidecharBuf(logLevels level, const char *msg, const widechar *wbuf, int wlen);
+
+void EXPORT_CALL
+_lou_logMessage(logLevels level, const char *format, ...);
+
+extern int translation_direction;
+
+/**
+ * Return 1 if given translation mode is valid. Return 0 otherwise.
+ */
+int EXPORT_CALL
+_lou_isValidMode(int mode);
+
+/**
+ * Return the default braille representation for a character.
+ */
+widechar EXPORT_CALL
+_lou_charToFallbackDots(widechar c);
+
+static inline int
+isASCII(widechar c) {
+ return (c >= 0X20) && (c < 0X7F);
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __LOUIS_H_ */
diff --git a/liblouis/liblouis.h.in b/liblouis/liblouis.h.in
new file mode 100644
index 0000000..9dfbb3a
--- /dev/null
+++ b/liblouis/liblouis.h.in
@@ -0,0 +1,440 @@
+/* liblouis Braille Translation and Back-Translation Library
+
+ Based on the Linux screenreader BRLTTY, copyright (C) 1999-2006 by The
+ BRLTTY Team
+
+ Copyright (C) 2004, 2005, 2006 ViewPlus Technologies, Inc. www.viewplus.com
+ Copyright (C) 2004, 2005, 2006 JJB Software, Inc. www.jjb-software.com
+ Copyright (C) 2016 Mike Gray, American Printing House for the Blind
+ Copyright (C) 2016 Davy Kager, Dedicon
+
+ This file is part of liblouis.
+
+ liblouis is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 2.1 of the License, or
+ (at your option) any later version.
+
+ liblouis is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file
+ * @brief Public API of liblouis
+ */
+
+#ifndef __LIBLOUIS_H_
+#define __LIBLOUIS_H_
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+// clang-format interacts badly with @foo@
+// clang-format off
+typedef @WIDECHAR_TYPE@ widechar;
+// clang-format on
+typedef unsigned short formtype;
+
+#ifdef _MSC_VER
+#ifdef _EXPORTING
+#define LIBLOUIS_API __declspec(dllexport)
+#else
+#define LIBLOUIS_API __declspec(dllimport)
+#endif
+#else
+#define LIBLOUIS_API
+#endif
+
+#ifdef __EMSCRIPTEN__
+#include "emscripten.h"
+#define EXPORT_CALL EMSCRIPTEN_KEEPALIVE
+#elif defined(_WIN32)
+#define EXPORT_CALL __stdcall
+LIBLOUIS_API
+char *EXPORT_CALL
+lou_getProgramPath(void);
+#else
+#define EXPORT_CALL
+#endif
+
+typedef enum {
+ plain_text = 0x0000,
+ emph_1 = 0x0001,
+ emph_2 = 0x0002,
+ emph_3 = 0x0004,
+ emph_4 = 0x0008,
+ emph_5 = 0x0010,
+ emph_6 = 0x0020,
+ emph_7 = 0x0040,
+ emph_8 = 0x0080,
+ emph_9 = 0x0100,
+ emph_10 = 0x0200,
+ computer_braille = 0x0400,
+ no_translate = 0x0800,
+ no_contract = 0x1000,
+ // SYLLABLE_MARKER_1 0x2000,
+ // SYLLABLE_MARKER_1 0x4000
+ // CAPSEMPH 0x4000
+} typeforms;
+
+#define italic emph_1
+#define underline emph_2
+#define bold emph_3
+
+#define comp_emph_1 emph_1
+#define comp_emph_2 emph_2
+#define comp_emph_3 emph_3
+
+#define EMPH_NAME_BOLD "bold"
+#define EMPH_NAME_ITALIC "italic"
+#define EMPH_NAME_UNDERLINE "underline"
+
+typedef enum {
+ noContractions = 1,
+ compbrlAtCursor = 2,
+ dotsIO = 4,
+ // for historic reasons 8 and 16 are free
+ compbrlLeftCursor = 32,
+ ucBrl = 64,
+ noUndefined = 128,
+ partialTrans = 256
+} translationModes;
+
+#define noUndefinedDots noUndefined
+
+LIBLOUIS_API
+const char *EXPORT_CALL
+lou_version(void);
+
+/**
+ * Return the size of widechar
+ */
+LIBLOUIS_API
+int EXPORT_CALL
+lou_charSize(void);
+
+LIBLOUIS_API
+int EXPORT_CALL
+lou_translateString(const char *tableList, const widechar *inbuf, int *inlen,
+ widechar *outbuf, int *outlen, formtype *typeform, char *spacing, int mode);
+
+LIBLOUIS_API
+int EXPORT_CALL
+lou_translate(const char *tableList, const widechar *inbuf, int *inlen, widechar *outbuf,
+ int *outlen, formtype *typeform, char *spacing, int *outputPos, int *inputPos,
+ int *cursorPos, int mode);
+
+LIBLOUIS_API
+int EXPORT_CALL
+lou_translatePrehyphenated(const char *tableList, const widechar *inbuf, int *inlen,
+ widechar *outbuf, int *outlen, formtype *typeform, char *spacing, int *outputPos,
+ int *inputPos, int *cursorPos, char *inputHyphens, char *outputHyphens, int mode);
+
+LIBLOUIS_API
+int EXPORT_CALL
+lou_hyphenate(
+ const char *tableList, const widechar *inbuf, int inlen, char *hyphens, int mode);
+
+/**
+ * Convert a string of dot patterns to a string of chars
+ *
+ * @param[in] tableList comma separated list of braille tables
+ * @param[in] inbuf widechar string of dot patterns, either in liblouis format or Unicode
+ * braille
+ * @param[out] outbuf widechar string corresponding to the dot patterns in `inbuf`
+ * @param[in,out] length of both `inbuf` and `outbuf`
+ * @param[in] mode (deprecated)
+ *
+ * @return 1 on success and 0 on failure.
+ */
+LIBLOUIS_API
+int EXPORT_CALL
+lou_dotsToChar(
+ const char *tableList, widechar *inbuf, widechar *outbuf, int length, int mode);
+LIBLOUIS_API
+int EXPORT_CALL
+lou_charToDots(const char *tableList, const widechar *inbuf, widechar *outbuf, int length,
+ int mode);
+LIBLOUIS_API
+int EXPORT_CALL
+lou_backTranslateString(const char *tableList, const widechar *inbuf, int *inlen,
+ widechar *outbuf, int *outlen, formtype *typeform, char *spacing, int mode);
+
+LIBLOUIS_API
+int EXPORT_CALL
+lou_backTranslate(const char *tableList, const widechar *inbuf, int *inlen,
+ widechar *outbuf, int *outlen, formtype *typeform, char *spacing, int *outputPos,
+ int *inputPos, int *cursorPos, int mode);
+/**
+ * Print error messages to a file
+ *
+ * @deprecated As of 2.6.0, applications using liblouis should
+ * implement their own logging system.
+ */
+LIBLOUIS_API
+void EXPORT_CALL
+lou_logPrint(const char *format, ...);
+
+/**
+ * Specify the name of the file to be used by lou_logPrint.
+ *
+ * If it is not used, this file is stderr
+ *
+ * @deprecated As of 2.6.0, applications using liblouis should
+ * implement their own logging system.
+ */
+LIBLOUIS_API
+void EXPORT_CALL
+lou_logFile(const char *filename);
+
+/**
+ * Read a character from a file, whether big-endian, little-endian or ASCII8
+ *
+ * and return it as an integer. EOF at end of file. Mode = 1 on first
+ * call, any other value thereafter
+ */
+LIBLOUIS_API
+int EXPORT_CALL
+lou_readCharFromFile(const char *fileName, int *mode);
+
+/**
+ * Close the log file so it can be read by other functions.
+ *
+ * @deprecated As of 2.6.0, applications using liblouis should
+ * implement their own logging system.
+ */
+LIBLOUIS_API
+void EXPORT_CALL
+lou_logEnd(void);
+
+/**
+ * Load and compile a translation table
+ *
+ * Check the table for errors. If none are found load the table into
+ * memory and return a pointer to it. If errors are found return a
+ * null pointer. It is called by lou_translateString() and
+ * lou_backTranslateString() and also by functions in liblouisutdml
+ * and by the tools.
+ */
+LIBLOUIS_API
+const void *EXPORT_CALL
+lou_getTable(const char *tableList);
+
+/**
+ * Check a translation table for errors.
+ *
+ * If no errors are found it load the table into memory and returns a
+ * non-zero value. Else the return value is 0.
+ */
+LIBLOUIS_API
+int EXPORT_CALL
+lou_checkTable(const char *tableList);
+
+/**
+ * Register a new table resolver. Overrides the default resolver. */
+LIBLOUIS_API
+void EXPORT_CALL
+lou_registerTableResolver(
+ char **(EXPORT_CALL *resolver)(const char *table, const char *base));
+
+/**
+ * Compile a table entry on the fly at run-time
+ *
+ * This function enables you to compile a table entry on the fly at
+ * run-time. The new entry is added to tableList and remains in
+ * force until lou_free() is called. If tableList has not
+ * previously been loaded it is loaded and compiled.
+ *
+ * @param inString contains the table entry to be added. It may be
+ * anything valid. Error messages will be produced if it is invalid.
+ *
+ * @return 1 on success and 0 on failure.
+ */
+LIBLOUIS_API
+int EXPORT_CALL
+lou_compileString(const char *tableList, const char *inString);
+
+/**
+ * Get the typeform bit for the named emphasis class.
+ *
+ * If the table defines the specified emphasis class the corresponding
+ * typeform is returned. Else the return value is 0.
+ */
+LIBLOUIS_API
+formtype EXPORT_CALL
+lou_getTypeformForEmphClass(const char *tableList, const char *emphClass);
+
+/**
+ * Return the emphasis class names declared in tableList as a
+ * NULL-terminated array of strings. The array is acquired with malloc()
+ * and should be released with free(). The strings must not be released,
+ * and are no longer valid after lou_free() has been called.
+ */
+LIBLOUIS_API
+char const **EXPORT_CALL
+lou_getEmphClasses(const char *tableList);
+
+/**
+ * Set the path used for searching for tables and liblouisutdml files.
+ *
+ * Overrides the installation path. */
+LIBLOUIS_API
+char *EXPORT_CALL
+lou_setDataPath(const char *path);
+
+/**
+ * Get the path set in the previous function. */
+LIBLOUIS_API
+char *EXPORT_CALL
+lou_getDataPath(void);
+
+typedef enum {
+ LOU_LOG_ALL = 0,
+ LOU_LOG_DEBUG = 10000,
+ LOU_LOG_INFO = 20000,
+ LOU_LOG_WARN = 30000,
+ LOU_LOG_ERROR = 40000,
+ LOU_LOG_FATAL = 50000,
+ LOU_LOG_OFF = 60000
+} logLevels;
+
+typedef void(EXPORT_CALL *logcallback)(logLevels level, const char *message);
+
+/**
+ * Register logging callbacks
+ * Set to NULL for default callback.
+ */
+LIBLOUIS_API
+void EXPORT_CALL
+lou_registerLogCallback(logcallback callback);
+
+/**
+ * Set the level for logging callback to be called at
+ */
+LIBLOUIS_API
+void EXPORT_CALL
+lou_setLogLevel(logLevels level);
+
+typedef enum { LOU_ROW_BRAILLE = 0X2800 } LOU_UnicodeConstants;
+
+/* ========================= Sort-of private API ========================= */
+
+/**
+ * Definitions of braille dots
+ */
+typedef enum BrailleDots {
+ LOU_DOT_1 = 0X01, /** dot 1 */
+ LOU_DOT_2 = 0X02, /** dot 2 */
+ LOU_DOT_3 = 0X04, /** dot 3 */
+ LOU_DOT_4 = 0X08, /** dot 4 */
+ LOU_DOT_5 = 0X10, /** dot 5 */
+ LOU_DOT_6 = 0X20, /** dot 6 */
+ LOU_DOT_7 = 0X40, /** dot 7 */
+ LOU_DOT_8 = 0X80, /** dot 8 */
+ LOU_DOT_9 = 0X100, /** virtual dot 9 */
+ LOU_DOT_10 = 0X200, /** virtual dot A */
+ LOU_DOT_11 = 0X400, /** virtual dot B */
+ LOU_DOT_12 = 0X800, /** virtual dot C */
+ LOU_DOT_13 = 0X1000, /** virtual dot D */
+ LOU_DOT_14 = 0X2000, /** virtual dot E */
+ LOU_DOT_15 = 0X4000, /** virtual dot F */
+ LOU_DOTS = 0X8000 /** if this bit is true, the widechar represents a dot pattern */
+} BrailleDots;
+
+/**
+ * A sentinel, used in liblouisutdml
+ */
+#define LOU_ENDSEGMENT 0xffff
+
+/* ========================= BETA API ========================= */
+
+// Use the following two function with care, API is subject to change!
+
+/**
+ * Parse, analyze and index tables.
+ *
+ * This function must be called prior to lou_findTable() and
+ * lou_listTables(). Table names must be provided as a NULL-terminated
+ * array of strings. Each table should resolve to exactly one file. An
+ * error message is given when a table contains invalid or duplicate
+ * metadata fields.
+ */
+LIBLOUIS_API
+void EXPORT_CALL
+lou_indexTables(const char **tables);
+
+/**
+ * Find the best match for a query.
+ *
+ * Returns the name of the table, or NULL when no match can be
+ * found. If lou_indexTables() has not been previously called, the
+ * table search path specified with LOUIS_TABLEPATH will be indexed
+ * first. An error message is given when the query is invalid. Freeing
+ * the memory of the returned string is the responsibility of the
+ * caller.
+ */
+LIBLOUIS_API
+char *EXPORT_CALL
+lou_findTable(const char *query);
+
+/**
+ * Find all matches for a query, best match first.
+ *
+ * Returns the names of the matched table as a NULL-terminated array
+ * of string. If lou_indexTables() has not been previously called, the
+ * table search path specified with LOUIS_TABLEPATH will be indexed
+ * first. An error message is given when the query is invalid. Freeing
+ * the memory of the returned array and strings is the responsibility
+ * of the caller.
+ */
+LIBLOUIS_API
+char **EXPORT_CALL
+lou_findTables(const char *query);
+
+/**
+ * Read metadata from a file.
+ *
+ * Returns the value of the metadata field specified by `key' in
+ * `table', or NULL when the field does not exist. Freeing the memory
+ * of the returned string is the responsibility of the caller.
+ */
+LIBLOUIS_API
+char *EXPORT_CALL
+lou_getTableInfo(const char *table, const char *key);
+
+/**
+ * List available tables.
+ *
+ * Returns the names of available tables as a NULL-terminated array of
+ * strings. Only tables that are discoverable, i.e. the have active
+ * metadata, are listed. If lou_indexTables() has not been previously
+ * called, the table search path specified with LOUIS_TABLEPATH will
+ * be indexed first. Freeing the memory of the returned array and
+ * strings is the responsibility of the caller.
+ */
+LIBLOUIS_API
+char **EXPORT_CALL
+lou_listTables(void);
+
+/* ====================== END OF BETA API ====================== */
+
+/**
+ * Free all memory allocated by liblouis.
+ *
+ * This function should be called at the end of the application to
+ * free all memory allocated by liblouis.
+ */
+LIBLOUIS_API
+void EXPORT_CALL
+lou_free(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __LIBLOUIS_H_ */
diff --git a/liblouis/logging.c b/liblouis/logging.c
new file mode 100644
index 0000000..bcf7c81
--- /dev/null
+++ b/liblouis/logging.c
@@ -0,0 +1,160 @@
+/* liblouis Braille Translation and Back-Translation Library
+
+ Copyright (C) 2004, 2005, 2006 ViewPlus Technologies, Inc. www.viewplus.com
+ Copyright (C) 2004, 2005, 2006 JJB Software, Inc. www.jjb-software.com
+
+ This file is part of liblouis.
+
+ liblouis is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 2.1 of the License, or
+ (at your option) any later version.
+
+ liblouis is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file
+ * @brief Logging
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "internal.h"
+
+void EXPORT_CALL
+_lou_logWidecharBuf(logLevels level, const char *msg, const widechar *wbuf, int wlen) {
+ /* When calculating output size:
+ * Each wdiechar is represented in hex, thus needing two bytes for each
+ * byte in the widechar (sizeof(widechar) * 2)
+ * Allow space for the "0x%X " formatting (+ 3)
+ * Number of characters in widechar buffer (wlen * )
+ * Give space for additional message (+ strlen(msg))
+ * Remember the null terminator (+ 1)
+ */
+ int logBufSize = (wlen * ((sizeof(widechar) * 3) + 3)) + 3 + (int)strlen(msg);
+ char *logMsg = malloc(logBufSize);
+ char *p = logMsg;
+ const char *formatString;
+ int i = 0;
+ if (sizeof(widechar) == 2)
+ formatString = "0x%04X ";
+ else
+ formatString = "0x%08X ";
+ for (i = 0; i < (int)strlen(msg); i++) logMsg[i] = msg[i];
+ p += strlen(msg);
+ for (i = 0; i < wlen; i++) {
+ p += sprintf(p, formatString, wbuf[i]);
+ }
+ *p = '~';
+ p++;
+ *p = ' ';
+ p++;
+ for (i = 0; i < wlen; i++) {
+ if (wbuf[i] & 0xff00)
+ *p = ' ';
+ else
+ *p = (char)wbuf[i];
+ p++;
+ }
+ *p = '\0';
+ _lou_logMessage(level, "%s", logMsg);
+ free(logMsg);
+}
+
+static void EXPORT_CALL
+defaultLogCallback(logLevels level, const char *message) {
+ lou_logPrint("%s",
+ message); // lou_logPrint takes formatting, protect against % in message
+}
+
+static logcallback logCallbackFunction = defaultLogCallback;
+void EXPORT_CALL
+lou_registerLogCallback(logcallback callback) {
+ if (callback == NULL)
+ logCallbackFunction = defaultLogCallback;
+ else
+ logCallbackFunction = callback;
+}
+
+static logLevels logLevel = LOU_LOG_INFO;
+void EXPORT_CALL
+lou_setLogLevel(logLevels level) {
+ logLevel = level;
+}
+
+void EXPORT_CALL
+_lou_logMessage(logLevels level, const char *format, ...) {
+ if (format == NULL) return;
+ if (level < logLevel) return;
+ if (logCallbackFunction != NULL) {
+#ifdef _WIN32
+ double f = 2.3; // Needed to force VC++ runtime floating point support
+#endif
+ char *s;
+ size_t len;
+ va_list argp;
+ va_start(argp, format);
+ len = vsnprintf(0, 0, format, argp);
+ va_end(argp);
+ if ((s = malloc(len + 1)) != 0) {
+ va_start(argp, format);
+ vsnprintf(s, len + 1, format, argp);
+ va_end(argp);
+ logCallbackFunction(level, s);
+ free(s);
+ }
+ }
+}
+
+static FILE *logFile = NULL;
+static char initialLogFileName[256] = "";
+
+void EXPORT_CALL
+lou_logFile(const char *fileName) {
+ if (logFile) {
+ fclose(logFile);
+ logFile = NULL;
+ }
+ if (fileName == NULL || fileName[0] == 0) return;
+ if (initialLogFileName[0] == 0) strcpy(initialLogFileName, fileName);
+ logFile = fopen(fileName, "a");
+ if (logFile == NULL && initialLogFileName[0] != 0)
+ logFile = fopen(initialLogFileName, "a");
+ if (logFile == NULL) {
+ fprintf(stderr, "Cannot open log file %s\n", fileName);
+ logFile = stderr;
+ }
+}
+
+void EXPORT_CALL
+lou_logPrint(const char *format, ...) {
+#ifndef __SYMBIAN32__
+ va_list argp;
+ if (format == NULL) return;
+ if (logFile == NULL) logFile = fopen(initialLogFileName, "a");
+ if (logFile == NULL) logFile = stderr;
+ va_start(argp, format);
+ vfprintf(logFile, format, argp);
+ fprintf(logFile, "\n");
+ fflush(logFile);
+ va_end(argp);
+#endif
+}
+
+/* Close the log file */
+void EXPORT_CALL
+lou_logEnd(void) {
+ if (logFile != NULL && logFile != stderr) fclose(logFile);
+ logFile = NULL;
+}
diff --git a/liblouis/lou_backTranslateString.c b/liblouis/lou_backTranslateString.c
new file mode 100644
index 0000000..18d2aa1
--- /dev/null
+++ b/liblouis/lou_backTranslateString.c
@@ -0,0 +1,1643 @@
+/* liblouis Braille Translation and Back-Translation Library
+
+ Based on the Linux screenreader BRLTTY, copyright (C) 1999-2006 by The
+ BRLTTY Team
+
+ Copyright (C) 2004, 2005, 2006 ViewPlus Technologies, Inc. www.viewplus.com
+ Copyright (C) 2004, 2005, 2006 JJB Software, Inc. www.jjb-software.com
+
+ This file is part of liblouis.
+
+ liblouis is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 2.1 of the License, or
+ (at your option) any later version.
+
+ liblouis is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file
+ * @brief Translate from braille
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "internal.h"
+
+typedef struct {
+ int size;
+ widechar **buffers;
+ int *inUse;
+ widechar *(*alloc)(int index, int length);
+ void (*free)(widechar *);
+} StringBufferPool;
+
+static widechar *
+allocStringBuffer(int index, int length) {
+ return _lou_allocMem(alloc_passbuf, index, 0, length);
+}
+
+static const StringBufferPool *stringBufferPool = NULL;
+
+static void
+initStringBufferPool() {
+ static widechar *stringBuffers[MAXPASSBUF] = { NULL };
+ static int stringBuffersInUse[MAXPASSBUF] = { 0 };
+ StringBufferPool *pool = malloc(sizeof(StringBufferPool));
+ pool->size = MAXPASSBUF;
+ pool->buffers = stringBuffers;
+ pool->inUse = stringBuffersInUse;
+ pool->alloc = &allocStringBuffer;
+ pool->free = NULL;
+ stringBufferPool = pool;
+}
+
+static int
+getStringBuffer(int length) {
+ int i;
+ for (i = 0; i < stringBufferPool->size; i++) {
+ if (!stringBufferPool->inUse[i]) {
+ stringBufferPool->buffers[i] = stringBufferPool->alloc(i, length);
+ stringBufferPool->inUse[i] = 1;
+ return i;
+ }
+ }
+ _lou_outOfMemory();
+ return -1;
+}
+
+static int
+releaseStringBuffer(int idx) {
+ if (idx >= 0 && idx < stringBufferPool->size) {
+ int inUse = stringBufferPool->inUse[idx];
+ if (inUse && stringBufferPool->free)
+ stringBufferPool->free(stringBufferPool->buffers[idx]);
+ stringBufferPool->inUse[idx] = 0;
+ return inUse;
+ }
+ return 0;
+}
+
+typedef struct {
+ int bufferIndex;
+ const widechar *chars;
+ int length;
+} InString;
+
+typedef struct {
+ int bufferIndex;
+ widechar *chars;
+ int maxlength;
+ int length;
+} OutString;
+
+typedef struct {
+ int startMatch;
+ int startReplace;
+ int endReplace;
+ int endMatch;
+} PassRuleMatch;
+
+static int
+backTranslateString(const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int mode, int currentPass,
+ const InString *input, OutString *output, char *spacebuf, int *posMapping,
+ int *realInlen, int *cursorPosition, int *cursorStatus,
+ const TranslationTableRule **appliedRules, int *appliedRulesCount,
+ int maxAppliedRules);
+static int
+makeCorrections(const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int mode, int currentPass,
+ const InString *input, OutString *output, int *posMapping, int *realInlen,
+ int *cursorPosition, int *cursorStatus, const TranslationTableRule **appliedRules,
+ int *appliedRulesCount, int maxAppliedRules);
+static int
+translatePass(const TranslationTableHeader *table, const DisplayTableHeader *displayTable,
+ int mode, int currentPass, const InString *input, OutString *output,
+ int *posMapping, int *realInlen, int *cursorPosition, int *cursorStatus,
+ const TranslationTableRule **appliedRules, int *appliedRulesCount,
+ int maxAppliedRules);
+static void
+passSelectRule(const TranslationTableHeader *table, int pos, int currentPass,
+ const InString *input, TranslationTableOpcode *currentOpcode,
+ const TranslationTableRule **currentRule, const widechar **passInstructions,
+ int *passIC, PassRuleMatch *match);
+
+int EXPORT_CALL
+lou_backTranslateString(const char *tableList, const widechar *inbuf, int *inlen,
+ widechar *outbuf, int *outlen, formtype *typeform, char *spacing, int modex) {
+ return lou_backTranslate(tableList, inbuf, inlen, outbuf, outlen, typeform, spacing,
+ NULL, NULL, NULL, modex);
+}
+
+int EXPORT_CALL
+lou_backTranslate(const char *tableList, const widechar *inbuf, int *inlen,
+ widechar *outbuf, int *outlen, formtype *typeform, char *spacing, int *outputPos,
+ int *inputPos, int *cursorPos, int modex) {
+ return _lou_backTranslate(tableList, tableList, inbuf, inlen, outbuf, outlen,
+ typeform, spacing, outputPos, inputPos, cursorPos, modex, NULL, NULL);
+}
+
+int EXPORT_CALL
+_lou_backTranslate(const char *tableList, const char *displayTableList,
+ const widechar *inbuf, int *inlen, widechar *outbuf, int *outlen,
+ formtype *typeform, char *spacing, int *outputPos, int *inputPos, int *cursorPos,
+ int mode, const TranslationTableRule **rules, int *rulesLen) {
+ const TranslationTableHeader *table;
+ const DisplayTableHeader *displayTable;
+ InString input;
+ OutString output;
+ unsigned char *typebuf = NULL;
+ char *spacebuf;
+ // posMapping contains position mapping info between the output of the current pass
+ // and the initial input. It is 1 longer than the input. The values are monotonically
+ // increasing and can range between -1 and the output length. At the end the position
+ // info is passed to the user as an inputPos and outputPos array. inputPos has the
+ // length of the final output and has values ranging from 0 to inlen-1. outputPos has
+ // the length of the initial input and has values ranging from 0 to outlen-1.
+ int *posMapping = NULL;
+ int *posMapping1;
+ int *posMapping2;
+ int *posMapping3;
+ int cursorPosition;
+ int cursorStatus;
+ const TranslationTableRule **appliedRules;
+ int maxAppliedRules;
+ int appliedRulesCount;
+ int k;
+ int goodTrans = 1;
+ int idx;
+ if (tableList == NULL || inbuf == NULL || inlen == NULL || outbuf == NULL ||
+ outlen == NULL)
+ return 0;
+ if (displayTableList == NULL) displayTableList = tableList;
+ _lou_getTable(tableList, displayTableList, &table, &displayTable);
+ if (table == NULL) return 0;
+
+ if (!_lou_isValidMode(mode))
+ _lou_logMessage(LOU_LOG_ERROR, "Invalid mode parameter: %d", mode);
+
+ if (!stringBufferPool) initStringBufferPool();
+ for (idx = 0; idx < stringBufferPool->size; idx++) releaseStringBuffer(idx);
+ {
+ widechar *passbuf1;
+ int srcmax;
+ k = 0;
+ while (k < *inlen && inbuf[k]) k++;
+ srcmax = k;
+ idx = getStringBuffer(srcmax);
+ passbuf1 = stringBufferPool->buffers[idx];
+ for (k = 0; k < srcmax; k++)
+ if ((mode & dotsIO))
+ passbuf1[k] = inbuf[k] | LOU_DOTS;
+ else
+ passbuf1[k] = _lou_getDotsForChar(inbuf[k], displayTable);
+ passbuf1[srcmax] = _lou_getDotsForChar(' ', displayTable);
+ input = (InString){ .chars = passbuf1, .length = srcmax, .bufferIndex = idx };
+ }
+ idx = getStringBuffer(*outlen);
+ output = (OutString){ .chars = stringBufferPool->buffers[idx],
+ .maxlength = *outlen,
+ .length = 0,
+ .bufferIndex = idx };
+ typebuf = (unsigned char *)typeform;
+ spacebuf = spacing;
+ if (outputPos != NULL)
+ for (k = 0; k < input.length; k++) outputPos[k] = -1;
+ if (cursorPos != NULL)
+ cursorPosition = *cursorPos;
+ else
+ cursorPosition = -1;
+ cursorStatus = 0;
+ if (typebuf != NULL) memset(typebuf, '0', *outlen);
+ if (spacebuf != NULL) memset(spacebuf, '*', *outlen);
+ if (!(posMapping1 = _lou_allocMem(alloc_posMapping1, 0, input.length, *outlen)))
+ return 0;
+ if (table->numPasses > 1 || table->corrections) {
+ if (!(posMapping2 = _lou_allocMem(alloc_posMapping2, 0, input.length, *outlen)))
+ return 0;
+ if (!(posMapping3 = _lou_allocMem(alloc_posMapping3, 0, input.length, *outlen)))
+ return 0;
+ }
+ appliedRulesCount = 0;
+ if (rules != NULL && rulesLen != NULL) {
+ appliedRules = rules;
+ maxAppliedRules = *rulesLen;
+ } else {
+ appliedRules = NULL;
+ maxAppliedRules = 0;
+ }
+
+ posMapping = posMapping1;
+ int currentPass = table->numPasses;
+ int lastPass = table->corrections ? 0 : 1;
+ int *passPosMapping = posMapping;
+ while (1) {
+ int realInlen;
+ switch (currentPass) {
+ case 1:
+ goodTrans = backTranslateString(table, displayTable, mode, currentPass,
+ &input, &output, spacebuf, passPosMapping, &realInlen,
+ &cursorPosition, &cursorStatus, appliedRules, &appliedRulesCount,
+ maxAppliedRules);
+ break;
+ case 0:
+ goodTrans = makeCorrections(table, displayTable, mode, currentPass, &input,
+ &output, passPosMapping, &realInlen, &cursorPosition, &cursorStatus,
+ appliedRules, &appliedRulesCount, maxAppliedRules);
+ break;
+ default:
+ goodTrans = translatePass(table, displayTable, mode, currentPass, &input,
+ &output, passPosMapping, &realInlen, &cursorPosition, &cursorStatus,
+ appliedRules, &appliedRulesCount, maxAppliedRules);
+ break;
+ }
+ passPosMapping[realInlen] = output.length;
+ if (passPosMapping == posMapping) {
+ passPosMapping = posMapping2;
+ } else {
+ int *prevPosMapping = posMapping3;
+ memcpy((int *)prevPosMapping, posMapping, (*inlen + 1) * sizeof(int));
+ for (k = 0; k <= *inlen; k++) {
+ if (prevPosMapping[k] > realInlen) {
+ *inlen = k;
+ posMapping[k] = output.length;
+ break;
+ } else if (prevPosMapping[k] < 0)
+ posMapping[k] = passPosMapping[0];
+ else
+ posMapping[k] = passPosMapping[prevPosMapping[k]];
+ }
+ }
+ currentPass--;
+ if (currentPass >= lastPass && goodTrans) {
+ releaseStringBuffer(input.bufferIndex);
+ input = (InString){ .chars = output.chars,
+ .length = output.length,
+ .bufferIndex = output.bufferIndex };
+ idx = getStringBuffer(*outlen);
+ output = (OutString){ .chars = stringBufferPool->buffers[idx],
+ .maxlength = *outlen,
+ .length = 0,
+ .bufferIndex = idx };
+ continue;
+ }
+ break;
+ }
+ if (goodTrans) {
+ for (k = 0; k < output.length; k++) outbuf[k] = output.chars[k];
+ *outlen = output.length;
+ if (inputPos != NULL) {
+ int inpos = -1;
+ int outpos = -1;
+ for (k = 0; k < *inlen; k++)
+ if (posMapping[k] > outpos) {
+ while (outpos < posMapping[k]) {
+ if (outpos >= 0 && outpos < *outlen)
+ inputPos[outpos] = inpos < 0 ? 0 : inpos;
+ outpos++;
+ }
+ inpos = k;
+ }
+ if (outpos < 0) outpos = 0;
+ while (outpos < *outlen) inputPos[outpos++] = inpos;
+ }
+ if (outputPos != NULL) {
+ for (k = 0; k < *inlen; k++)
+ if (posMapping[k] < 0)
+ outputPos[k] = 0;
+ else if (posMapping[k] > *outlen - 1)
+ outputPos[k] = *outlen - 1;
+ else
+ outputPos[k] = posMapping[k];
+ }
+ }
+ if (cursorPos != NULL && *cursorPos != -1) {
+ if (outputPos != NULL)
+ *cursorPos = outputPos[*cursorPos];
+ else
+ *cursorPos = cursorPosition;
+ }
+ if (rulesLen != NULL) *rulesLen = appliedRulesCount;
+ return goodTrans;
+}
+
+static TranslationTableCharacter *
+back_findCharOrDots(widechar c, int m, const TranslationTableHeader *table) {
+ /* Look up character or dot pattern in the appropriate
+ * table. */
+ static TranslationTableCharacter noChar = { 0, 0, 0, CTC_Space, 32, 32, 32 };
+ static TranslationTableCharacter noDots = { 0, 0, 0, CTC_Space, LOU_DOTS, LOU_DOTS,
+ LOU_DOTS };
+ TranslationTableCharacter *notFound;
+ TranslationTableCharacter *character;
+ TranslationTableOffset bucket;
+ unsigned long int makeHash = _lou_charHash(c);
+ if (m == 0) {
+ bucket = table->characters[makeHash];
+ notFound = &noChar;
+ } else {
+ bucket = table->dots[makeHash];
+ notFound = &noDots;
+ }
+ while (bucket) {
+ character = (TranslationTableCharacter *)&table->ruleArea[bucket];
+ if (character->realchar == c) return character;
+ bucket = character->next;
+ }
+ notFound->realchar = notFound->uppercase = notFound->lowercase = c;
+ return notFound;
+}
+
+static int
+checkAttr(const widechar c, const TranslationTableCharacterAttributes a, int m,
+ const TranslationTableHeader *table) {
+ static widechar prevc = 0;
+ static TranslationTableCharacterAttributes preva = 0;
+ if (c != prevc) {
+ preva = (back_findCharOrDots(c, m, table))->attributes;
+ prevc = c;
+ }
+ return ((preva & a) ? 1 : 0);
+}
+
+static int
+compareDots(const widechar *address1, const widechar *address2, int count) {
+ int k;
+ if (!count) return 0;
+ for (k = 0; k < count; k++)
+ if (address1[k] != address2[k]) return 0;
+ return 1;
+}
+
+static void
+back_setBefore(const TranslationTableHeader *table, OutString *output,
+ TranslationTableCharacterAttributes *beforeAttributes) {
+ widechar before = (output->length == 0) ? ' ' : output->chars[output->length - 1];
+ *beforeAttributes = (back_findCharOrDots(before, 0, table))->attributes;
+}
+
+static void
+back_setAfter(int length, const TranslationTableHeader *table, int pos,
+ const InString *input, TranslationTableCharacterAttributes *afterAttributes) {
+ widechar after = (pos + length < input->length) ? input->chars[pos + length] : ' ';
+ *afterAttributes = (back_findCharOrDots(after, 1, table))->attributes;
+}
+
+static int
+isBegWord(const TranslationTableHeader *table, OutString *output) {
+ /* See if this is really the beginning of a word. Look at what has
+ * already been translated. */
+ int k;
+ if (output->length == 0) return 1;
+ for (k = output->length - 1; k >= 0; k--) {
+ const TranslationTableCharacter *ch =
+ back_findCharOrDots(output->chars[k], 0, table);
+ if (ch->attributes & CTC_Space) break;
+ if (ch->attributes & (CTC_Letter | CTC_Digit | CTC_Math | CTC_Sign)) return 0;
+ }
+ return 1;
+}
+
+static int
+isEndWord(const TranslationTableHeader *table, int pos, int mode, const InString *input,
+ int currentDotslen) {
+ if (mode & partialTrans) return 0;
+ /* See if this is really the end of a word. */
+ int k;
+ const TranslationTableCharacter *dots;
+ TranslationTableOffset testRuleOffset;
+ TranslationTableRule *testRule;
+ for (k = pos + currentDotslen; k < input->length; k++) {
+ int postpuncFound = 0;
+ int TranslationFound = 0;
+ dots = back_findCharOrDots(input->chars[k], 1, table);
+ testRuleOffset = dots->otherRules;
+ if (dots->attributes & CTC_Space) break;
+ if (dots->attributes & CTC_Letter) return 0;
+ while (testRuleOffset) {
+ testRule = (TranslationTableRule *)&table->ruleArea[testRuleOffset];
+ /* #360: Don't treat begword/midword as definite translations here
+ * because we don't know whether they apply yet. Subsequent
+ * input will allow us to determine whether the word continues.
+ */
+ if (testRule->charslen > 1 && testRule->opcode != CTO_BegWord &&
+ testRule->opcode != CTO_MidWord)
+ TranslationFound = 1;
+ if (testRule->opcode == CTO_PostPunc) postpuncFound = 1;
+ if (testRule->opcode == CTO_Hyphen) return 1;
+ testRuleOffset = testRule->dotsnext;
+ }
+ if (TranslationFound && !postpuncFound) return 0;
+ }
+ return 1;
+}
+static int
+findBrailleIndicatorRule(TranslationTableOffset offset,
+ const TranslationTableHeader *table, int *currentDotslen,
+ TranslationTableOpcode *currentOpcode, const TranslationTableRule **currentRule) {
+ if (!offset) return 0;
+ *currentRule = (TranslationTableRule *)&table->ruleArea[offset];
+ *currentOpcode = (*currentRule)->opcode;
+ *currentDotslen = (*currentRule)->dotslen;
+ return 1;
+}
+
+static int
+handleMultind(const TranslationTableHeader *table, int *currentDotslen,
+ TranslationTableOpcode *currentOpcode, const TranslationTableRule **currentRule,
+ int *doingMultind, const TranslationTableRule *multindRule) {
+ /* Handle multille braille indicators */
+ int found = 0;
+ if (!*doingMultind) return 0;
+ switch (multindRule->charsdots[multindRule->charslen - *doingMultind]) {
+ case CTO_CapsLetterRule: // FIXME: make sure this works
+ found = findBrailleIndicatorRule(table->emphRules[capsRule][letterOffset], table,
+ currentDotslen, currentOpcode, currentRule);
+ break;
+ // NOTE: following fixme is based on the names at the time of
+ // commit f22f91eb510cb4eef33dfb4950a297235dd2f9f1.
+ // FIXME: the next two opcodes were begcaps/endcaps,
+ // and they were aliased to opcodes capsword/capswordstop.
+ // However, the table attributes they use are
+ // table->beginCapitalSign and table->endCapitalSign.
+ // These are actually compiled with firstlettercaps/lastlettercaps.
+ // Which to use here?
+ case CTO_BegCapsWordRule:
+ found = findBrailleIndicatorRule(table->emphRules[capsRule][begWordOffset], table,
+ currentDotslen, currentOpcode, currentRule);
+ break;
+ case CTO_EndCapsWordRule:
+ found = findBrailleIndicatorRule(table->emphRules[capsRule][endWordOffset], table,
+ currentDotslen, currentOpcode, currentRule);
+ break;
+ case CTO_LetterSign:
+ found = findBrailleIndicatorRule(
+ table->letterSign, table, currentDotslen, currentOpcode, currentRule);
+ break;
+ case CTO_NoContractSign:
+ found = findBrailleIndicatorRule(
+ table->noContractSign, table, currentDotslen, currentOpcode, currentRule);
+ break;
+ case CTO_NumberSign:
+ found = findBrailleIndicatorRule(
+ table->numberSign, table, currentDotslen, currentOpcode, currentRule);
+ break;
+ case CTO_EndEmph1PhraseBeforeRule:
+ found = findBrailleIndicatorRule(
+ table->emphRules[emph1Rule][endPhraseBeforeOffset], table, currentDotslen,
+ currentOpcode, currentRule);
+ break;
+ case CTO_BegEmph1Rule:
+ found = findBrailleIndicatorRule(table->emphRules[emph1Rule][begOffset], table,
+ currentDotslen, currentOpcode, currentRule);
+ break;
+ case CTO_EndEmph1Rule:
+ found = findBrailleIndicatorRule(table->emphRules[emph1Rule][endOffset], table,
+ currentDotslen, currentOpcode, currentRule);
+ break;
+ case CTO_EndEmph2PhraseBeforeRule:
+ found = findBrailleIndicatorRule(
+ table->emphRules[emph2Rule][endPhraseBeforeOffset], table, currentDotslen,
+ currentOpcode, currentRule);
+ break;
+ case CTO_BegEmph2Rule:
+ found = findBrailleIndicatorRule(table->emphRules[emph2Rule][begOffset], table,
+ currentDotslen, currentOpcode, currentRule);
+ break;
+ case CTO_EndEmph2Rule:
+ found = findBrailleIndicatorRule(table->emphRules[emph2Rule][endOffset], table,
+ currentDotslen, currentOpcode, currentRule);
+ break;
+ case CTO_EndEmph3PhraseBeforeRule:
+ found = findBrailleIndicatorRule(
+ table->emphRules[emph3Rule][endPhraseBeforeOffset], table, currentDotslen,
+ currentOpcode, currentRule);
+ break;
+ case CTO_BegEmph3Rule:
+ found = findBrailleIndicatorRule(table->emphRules[emph3Rule][begOffset], table,
+ currentDotslen, currentOpcode, currentRule);
+ break;
+ case CTO_EndEmph3Rule:
+ found = findBrailleIndicatorRule(table->emphRules[emph3Rule][endOffset], table,
+ currentDotslen, currentOpcode, currentRule);
+ break;
+ case CTO_BegComp:
+ found = findBrailleIndicatorRule(
+ table->begComp, table, currentDotslen, currentOpcode, currentRule);
+ break;
+ case CTO_EndComp:
+ found = findBrailleIndicatorRule(
+ table->endComp, table, currentDotslen, currentOpcode, currentRule);
+ break;
+ default:
+ found = 0;
+ break;
+ }
+ (*doingMultind)--;
+ return found;
+}
+
+static int
+back_passDoTest(const TranslationTableHeader *table, int pos, const InString *input,
+ TranslationTableOpcode currentOpcode, const TranslationTableRule *currentRule,
+ const widechar **passInstructions, int *passIC, PassRuleMatch *match);
+static int
+back_passDoAction(const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int *pos, int mode, const InString *input,
+ OutString *output, int *posMapping, int *cursorPosition, int *cursorStatus,
+ int *nextUpper, int allUpper, int allUpperPhrase,
+ TranslationTableOpcode currentOpcode, const TranslationTableRule *currentRule,
+ const widechar *passInstructions, int passIC, PassRuleMatch match);
+
+static int
+findBackPassRule(const TranslationTableHeader *table, int pos, int currentPass,
+ const InString *input, TranslationTableOpcode *currentOpcode,
+ const TranslationTableRule **currentRule, const widechar **passInstructions,
+ int *passIC, PassRuleMatch *match) {
+ TranslationTableOffset ruleOffset;
+ ruleOffset = table->backPassRules[currentPass];
+
+ while (ruleOffset) {
+ *currentRule = (TranslationTableRule *)&table->ruleArea[ruleOffset];
+ *currentOpcode = (*currentRule)->opcode;
+
+ switch (*currentOpcode) {
+ case CTO_Correct:
+ if (currentPass != 0) goto NEXT_RULE;
+ break;
+ case CTO_Context:
+ if (currentPass != 1) goto NEXT_RULE;
+ break;
+ case CTO_Pass2:
+ if (currentPass != 2) goto NEXT_RULE;
+ break;
+ case CTO_Pass3:
+ if (currentPass != 3) goto NEXT_RULE;
+ break;
+ case CTO_Pass4:
+ if (currentPass != 4) goto NEXT_RULE;
+ break;
+ default:
+ goto NEXT_RULE;
+ }
+
+ if (back_passDoTest(table, pos, input, *currentOpcode, *currentRule,
+ passInstructions, passIC, match))
+ return 1;
+
+ NEXT_RULE:
+ ruleOffset = (*currentRule)->dotsnext;
+ }
+
+ return 0;
+}
+
+static void
+back_selectRule(const TranslationTableHeader *table, int pos, int mode,
+ const InString *input, OutString *output, int itsANumber, int itsALetter,
+ int *currentDotslen, TranslationTableOpcode *currentOpcode,
+ const TranslationTableRule **currentRule, TranslationTableOpcode previousOpcode,
+ int *doingMultind, const TranslationTableRule **multindRule,
+ TranslationTableCharacterAttributes beforeAttributes,
+ const widechar **passInstructions, int *passIC, PassRuleMatch *patternMatch) {
+ /* check for valid back-translations */
+ int length = input->length - pos;
+ TranslationTableOffset ruleOffset = 0;
+ static TranslationTableRule pseudoRule = { 0 };
+ unsigned long int makeHash = 0;
+ const TranslationTableCharacter *dots =
+ back_findCharOrDots(input->chars[pos], 1, table);
+ int tryThis;
+ if (handleMultind(table, currentDotslen, currentOpcode, currentRule, doingMultind,
+ *multindRule))
+ return;
+ for (tryThis = 0; tryThis < 3; tryThis++) {
+ switch (tryThis) {
+ case 0:
+ if (length < 2 || (itsANumber && (dots->attributes & CTC_LitDigit))) break;
+ /* Hash function optimized for backward translation */
+ makeHash = (unsigned long int)dots->realchar << 8;
+ makeHash += (unsigned long int)(back_findCharOrDots(
+ input->chars[pos + 1], 1, table))
+ ->realchar;
+ makeHash %= HASHNUM;
+ ruleOffset = table->backRules[makeHash];
+ break;
+ case 1:
+ if (!(length >= 1)) break;
+ length = 1;
+ ruleOffset = dots->otherRules;
+ break;
+ case 2: /* No rule found */
+ *currentRule = &pseudoRule;
+ *currentOpcode = pseudoRule.opcode = CTO_None;
+ *currentDotslen = pseudoRule.dotslen = 1;
+ pseudoRule.charsdots[0] = input->chars[pos];
+ pseudoRule.charslen = 0;
+ return;
+ break;
+ }
+ while (ruleOffset) {
+ const widechar *currentDots;
+ *currentRule = (TranslationTableRule *)&table->ruleArea[ruleOffset];
+ *currentOpcode = (*currentRule)->opcode;
+ if (*currentOpcode == CTO_Context) {
+ currentDots = &(*currentRule)->charsdots[0];
+ *currentDotslen = (*currentRule)->charslen;
+ } else {
+ currentDots = &(*currentRule)->charsdots[(*currentRule)->charslen];
+ *currentDotslen = (*currentRule)->dotslen;
+ }
+ if (((*currentDotslen <= length) &&
+ compareDots(&input->chars[pos], currentDots, *currentDotslen))) {
+ TranslationTableCharacterAttributes afterAttributes;
+ /* check this rule */
+ back_setAfter(*currentDotslen, table, pos, input, &afterAttributes);
+ if ((!((*currentRule)->after & ~CTC_EmpMatch) ||
+ (beforeAttributes & (*currentRule)->after)) &&
+ (!((*currentRule)->before & ~CTC_EmpMatch) ||
+ (afterAttributes & (*currentRule)->before))) {
+ switch (*currentOpcode) { /* check validity of this Translation */
+ case CTO_Context:
+ if (back_passDoTest(table, pos, input, *currentOpcode,
+ *currentRule, passInstructions, passIC, patternMatch))
+ return;
+ break;
+ case CTO_Space:
+ case CTO_Digit:
+ case CTO_Letter:
+ case CTO_UpperCase:
+ case CTO_LowerCase:
+ case CTO_Punctuation:
+ case CTO_Math:
+ case CTO_Sign:
+ case CTO_ExactDots:
+ case CTO_NoCross:
+ case CTO_Repeated:
+ case CTO_Replace:
+ case CTO_Hyphen:
+ return;
+ case CTO_LitDigit:
+ if (itsANumber) return;
+ break;
+ case CTO_CapsLetterRule:
+ case CTO_BegCapsRule:
+ case CTO_EndCapsRule:
+ case CTO_BegCapsWordRule:
+ case CTO_EndCapsWordRule:
+ case CTO_BegEmph1Rule:
+ case CTO_EndEmph1Rule:
+ case CTO_BegEmph2Rule:
+ case CTO_EndEmph2Rule:
+ case CTO_BegEmph3Rule:
+ case CTO_EndEmph3Rule:
+ case CTO_NumberRule:
+ case CTO_BegCompRule:
+ case CTO_EndCompRule:
+ return;
+ case CTO_LetterRule:
+ case CTO_NoContractRule:
+ // BF: This is just a heuristic test. During forward translation,
+ // the
+ // nocontractsign is inserted either when in numeric mode and the
+ // next
+ // character is not numeric (CTC_Digit | CTC_LitDigit |
+ // CTC_NumericMode | CTC_MidEndNumericMode),
+ // or when a "contraction" rule is matched and the characters are
+ // preceded and followed by space or punctuation (CTC_Space |
+ // CTC_Punctuation).
+ if (!(beforeAttributes & CTC_Letter) &&
+ (afterAttributes & (CTC_Letter | CTC_Sign)))
+ return;
+ break;
+ case CTO_MultInd:
+ *doingMultind = *currentDotslen;
+ *multindRule = *currentRule;
+ if (handleMultind(table, currentDotslen, currentOpcode,
+ currentRule, doingMultind, *multindRule))
+ return;
+ break;
+ case CTO_LargeSign:
+ return;
+ case CTO_WholeWord:
+ if (mode & partialTrans) break;
+ if (itsALetter || itsANumber) break;
+ case CTO_Contraction:
+ if ((beforeAttributes & (CTC_Space | CTC_Punctuation)) &&
+ ((afterAttributes & CTC_Space) ||
+ isEndWord(table, pos, mode, input,
+ *currentDotslen)))
+ return;
+ break;
+ case CTO_LowWord:
+ if (mode & partialTrans) break;
+ if ((beforeAttributes & CTC_Space) &&
+ (afterAttributes & CTC_Space) &&
+ (previousOpcode != CTO_JoinableWord))
+ return;
+ break;
+ case CTO_JoinNum:
+ case CTO_JoinableWord:
+ if ((beforeAttributes & (CTC_Space | CTC_Punctuation)) &&
+ (!(afterAttributes & CTC_Space) || mode & partialTrans))
+ return;
+ break;
+ case CTO_SuffixableWord:
+ if (beforeAttributes & (CTC_Space | CTC_Punctuation)) return;
+ break;
+ case CTO_PrefixableWord:
+ if ((beforeAttributes &
+ (CTC_Space | CTC_Letter | CTC_Punctuation)) &&
+ isEndWord(table, pos, mode, input, *currentDotslen))
+ return;
+ break;
+ case CTO_BegWord:
+ if ((beforeAttributes & (CTC_Space | CTC_Punctuation)) &&
+ (!isEndWord(table, pos, mode, input, *currentDotslen)))
+ return;
+ break;
+ case CTO_BegMidWord:
+ if ((beforeAttributes &
+ (CTC_Letter | CTC_Space | CTC_Punctuation)) &&
+ (!isEndWord(table, pos, mode, input, *currentDotslen)))
+ return;
+ break;
+ case CTO_PartWord:
+ if (!(beforeAttributes & CTC_LitDigit) &&
+ (beforeAttributes & CTC_Letter ||
+ !isEndWord(table, pos, mode, input,
+ *currentDotslen)))
+ return;
+ break;
+ case CTO_MidWord:
+ if (beforeAttributes & CTC_Letter &&
+ !isEndWord(table, pos, mode, input, *currentDotslen))
+ return;
+ break;
+ case CTO_MidEndWord:
+ if ((beforeAttributes & CTC_Letter)) return;
+ break;
+ case CTO_EndWord:
+ if ((beforeAttributes & CTC_Letter) &&
+ isEndWord(table, pos, mode, input, *currentDotslen))
+ return;
+ break;
+ case CTO_BegNum:
+ if (beforeAttributes & (CTC_Space | CTC_Punctuation) &&
+ (afterAttributes & (CTC_LitDigit | CTC_Sign)))
+ return;
+ break;
+ case CTO_MidNum:
+ if (beforeAttributes & CTC_Digit &&
+ afterAttributes & CTC_LitDigit)
+ return;
+ break;
+ case CTO_EndNum:
+ if (itsANumber && !(afterAttributes & CTC_LitDigit)) return;
+ break;
+ case CTO_DecPoint:
+ if (afterAttributes & (CTC_Digit | CTC_LitDigit)) return;
+ break;
+ case CTO_PrePunc:
+ if (isBegWord(table, output)) return;
+ break;
+
+ case CTO_PostPunc:
+ if (isEndWord(table, pos, mode, input, *currentDotslen)) return;
+ break;
+ case CTO_Always:
+ if ((beforeAttributes & CTC_LitDigit) &&
+ (afterAttributes & CTC_LitDigit) &&
+ (*currentRule)->charslen > 1)
+ break;
+ return;
+
+ case CTO_BackMatch: {
+ widechar *patterns, *pattern;
+
+ // if(dontContract || (mode & noContractions))
+ // break;
+ // if(checkEmphasisChange(0))
+ // break;
+
+ patterns = (widechar *)&table->ruleArea[(*currentRule)->patterns];
+
+ /* check before pattern */
+ pattern = &patterns[1];
+ if (!_lou_pattern_check(
+ input->chars, pos - 1, -1, -1, pattern, table))
+ break;
+
+ /* check after pattern */
+ pattern = &patterns[patterns[0]];
+ if (!_lou_pattern_check(input->chars,
+ pos + (*currentRule)->dotslen, input->length, 1,
+ pattern, table))
+ break;
+
+ return;
+ }
+ default:
+ break;
+ }
+ }
+ } /* Done with checking this rule */
+ ruleOffset = (*currentRule)->dotsnext;
+ }
+ }
+}
+
+static int
+putchars(const widechar *chars, int count, const TranslationTableHeader *table,
+ OutString *output, int *nextUpper, int allUpper, int allUpperPhrase) {
+ int k = 0;
+ if (!count || (output->length + count) > output->maxlength) return 0;
+ if (*nextUpper) {
+ output->chars[(output->length)++] =
+ (back_findCharOrDots(chars[k++], 0, table))->uppercase;
+ *nextUpper = 0;
+ }
+ if (!allUpper && !allUpperPhrase) {
+ memcpy(&output->chars[output->length], &chars[k], CHARSIZE * (count - k));
+ output->length += count - k;
+ } else
+ for (; k < count; k++)
+ output->chars[(output->length)++] =
+ (back_findCharOrDots(chars[k], 0, table))->uppercase;
+ return 1;
+}
+
+static int
+back_updatePositions(const widechar *outChars, int inLength, int outLength,
+ const TranslationTableHeader *table, int pos, const InString *input,
+ OutString *output, int *posMapping, int *cursorPosition, int *cursorStatus,
+ int *nextUpper, int allUpper, int allUpperPhrase) {
+ int k;
+ if ((output->length + outLength) > output->maxlength ||
+ (pos + inLength) > input->length)
+ return 0;
+ if (!*cursorStatus && *cursorPosition >= pos && *cursorPosition < (pos + inLength)) {
+ *cursorPosition = output->length + outLength / 2;
+ *cursorStatus = 1;
+ }
+ for (k = 0; k < inLength; k++) posMapping[pos + k] = output->length;
+ return putchars(
+ outChars, outLength, table, output, nextUpper, allUpper, allUpperPhrase);
+}
+
+static int
+undefinedDots(widechar dots, int mode, OutString *output, int pos, int *posMapping) {
+ posMapping[pos] = output->length;
+ if (mode & noUndefined) return 1;
+
+ /* Print out dot numbers */
+ const char *buffer = _lou_unknownDots(dots);
+ size_t buflen = strlen(buffer);
+ if ((output->length + buflen) > output->maxlength) return 0;
+
+ for (unsigned int k = 0; k < buflen; k += 1) {
+ output->chars[output->length++] = buffer[k];
+ }
+
+ return 1;
+}
+
+static int
+putCharacter(widechar dots, const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int pos, int mode, const InString *input,
+ OutString *output, int *posMapping, int *cursorPosition, int *cursorStatus,
+ int *nextUpper, int allUpper, int allUpperPhrase) {
+ /* Output character(s) corresponding to a Unicode braille Character */
+ TranslationTableOffset offset = (back_findCharOrDots(dots, 1, table))->definitionRule;
+ if (offset) {
+ widechar c;
+ const TranslationTableRule *rule =
+ (TranslationTableRule *)&table->ruleArea[offset];
+ if (rule->charslen)
+ return back_updatePositions(&rule->charsdots[0], rule->dotslen,
+ rule->charslen, table, pos, input, output, posMapping, cursorPosition,
+ cursorStatus, nextUpper, allUpper, allUpperPhrase);
+ c = _lou_getCharFromDots(dots, displayTable);
+ if (c == '\0') c = ' ';
+ return back_updatePositions(&c, 1, 1, table, pos, input, output, posMapping,
+ cursorPosition, cursorStatus, nextUpper, allUpper, allUpperPhrase);
+ }
+ return undefinedDots(dots, mode, output, pos, posMapping);
+}
+
+static int
+putCharacters(const widechar *characters, int count, const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int pos, int mode, const InString *input,
+ OutString *output, int *posMapping, int *cursorPosition, int *cursorStatus,
+ int *nextUpper, int allUpper, int allUpperPhrase) {
+ int k;
+ for (k = 0; k < count; k++)
+ if (!putCharacter(characters[k], table, displayTable, pos, mode, input, output,
+ posMapping, cursorPosition, cursorStatus, nextUpper, allUpper,
+ allUpperPhrase))
+ return 0;
+ return 1;
+}
+
+static int
+insertSpace(const TranslationTableHeader *table, int pos, const InString *input,
+ OutString *output, char *spacebuf, int *posMapping, int *cursorPosition,
+ int *cursorStatus, int *nextUpper, int allUpper, int allUpperPhrase) {
+ widechar c = ' ';
+ if (!back_updatePositions(&c, 1, 1, table, pos, input, output, posMapping,
+ cursorPosition, cursorStatus, nextUpper, allUpper, allUpperPhrase))
+ return 0;
+ if (spacebuf) spacebuf[output->length - 1] = '1';
+ return 1;
+}
+
+static int
+compareChars(const widechar *address1, const widechar *address2, int count, int m,
+ const TranslationTableHeader *table) {
+ int k;
+ if (!count) return 0;
+ for (k = 0; k < count; k++)
+ if ((back_findCharOrDots(address1[k], m, table))->lowercase !=
+ (back_findCharOrDots(address2[k], m, table))->lowercase)
+ return 0;
+ return 1;
+}
+
+static int
+makeCorrections(const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int mode, int currentPass,
+ const InString *input, OutString *output, int *posMapping, int *realInlen,
+ int *cursorPosition, int *cursorStatus, const TranslationTableRule **appliedRules,
+ int *appliedRulesCount, int maxAppliedRules) {
+ int pos;
+ int nextUpper = 0;
+ int allUpper = 0;
+ int allUpperPhrase = 0;
+ if (!table->corrections) return 1;
+ pos = 0;
+ output->length = 0;
+ _lou_resetPassVariables();
+ while (pos < input->length) {
+ TranslationTableOpcode currentOpcode;
+ const TranslationTableRule *currentRule; /* pointer to current rule in table */
+ const widechar *passInstructions;
+ int passIC; /* Instruction counter */
+ PassRuleMatch patternMatch;
+ int length = input->length - pos;
+ const TranslationTableCharacter *character =
+ back_findCharOrDots(input->chars[pos], 0, table);
+ const TranslationTableCharacter *character2;
+ int tryThis = 0;
+ if (!findBackPassRule(table, pos, currentPass, input, ¤tOpcode,
+ ¤tRule, &passInstructions, &passIC, &patternMatch))
+ while (tryThis < 3) {
+ TranslationTableOffset ruleOffset = 0;
+ unsigned long int makeHash = 0;
+ switch (tryThis) {
+ case 0:
+ if (!(length >= 2)) break;
+ makeHash = (unsigned long int)character->lowercase << 8;
+ character2 = back_findCharOrDots(input->chars[pos + 1], 0, table);
+ makeHash += (unsigned long int)character2->lowercase;
+ makeHash %= HASHNUM;
+ ruleOffset = table->forRules[makeHash];
+ break;
+ case 1:
+ if (!(length >= 1)) break;
+ length = 1;
+ ruleOffset = character->otherRules;
+ break;
+ case 2: /* No rule found */
+ currentOpcode = CTO_Always;
+ ruleOffset = 0;
+ break;
+ }
+ while (ruleOffset) {
+ currentRule = (TranslationTableRule *)&table->ruleArea[ruleOffset];
+ currentOpcode = currentRule->opcode;
+ int currentCharslen = currentRule->charslen;
+ if (tryThis == 1 ||
+ (currentCharslen <= length &&
+ compareChars(¤tRule->charsdots[0],
+ &input->chars[pos], currentCharslen, 0,
+ table))) {
+ if (currentOpcode == CTO_Correct &&
+ back_passDoTest(table, pos, input, currentOpcode,
+ currentRule, &passInstructions, &passIC,
+ &patternMatch)) {
+ tryThis = 4;
+ break;
+ }
+ }
+ ruleOffset = currentRule->dotsnext;
+ }
+ tryThis++;
+ }
+ switch (currentOpcode) {
+ case CTO_Always:
+ if (output->length >= output->maxlength) goto failure;
+ posMapping[pos] = output->length;
+ output->chars[(output->length)++] = input->chars[pos++];
+ break;
+ case CTO_Correct:
+ if (appliedRules != NULL && *appliedRulesCount < maxAppliedRules)
+ appliedRules[(*appliedRulesCount)++] = currentRule;
+ if (!back_passDoAction(table, displayTable, &pos, mode, input, output,
+ posMapping, cursorPosition, cursorStatus, &nextUpper, allUpper,
+ allUpperPhrase, currentOpcode, currentRule, passInstructions,
+ passIC, patternMatch))
+ goto failure;
+ break;
+ default:
+ break;
+ }
+ }
+failure:
+ *realInlen = pos;
+ return 1;
+}
+
+static int
+backTranslateString(const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int mode, int currentPass,
+ const InString *input, OutString *output, char *spacebuf, int *posMapping,
+ int *realInlen, int *cursorPosition, int *cursorStatus,
+ const TranslationTableRule **appliedRules, int *appliedRulesCount,
+ int maxAppliedRules) {
+ int pos;
+ int nextUpper;
+ int allUpper;
+ int allUpperPhrase;
+ int itsANumber;
+ int itsALetter;
+ /* Back translation */
+ int srcword = 0;
+ int destword = 0; /* last word translated */
+ TranslationTableOpcode previousOpcode;
+ int doingMultind = 0;
+ const TranslationTableRule *multindRule;
+ _lou_resetPassVariables();
+ translation_direction = 0;
+ nextUpper = allUpper = allUpperPhrase = itsANumber = itsALetter = 0;
+ previousOpcode = CTO_None;
+ pos = output->length = 0;
+ while (pos < input->length) {
+ /* the main translation loop */
+ int currentDotslen; /* length of current find string */
+ TranslationTableOpcode currentOpcode;
+ const TranslationTableRule *currentRule; /* pointer to current rule in table */
+ TranslationTableCharacterAttributes beforeAttributes;
+ const widechar *passInstructions;
+ int passIC; /* Instruction counter */
+ PassRuleMatch patternMatch;
+ back_setBefore(table, output, &beforeAttributes);
+ if ((allUpper == 1) && (beforeAttributes & CTC_UpperCase))
+ // Capsword in progress
+ allUpper = 2;
+ else if ((allUpper == 2) && !(beforeAttributes & CTC_UpperCase) &&
+ !(beforeAttributes & CTC_CapsMode))
+ // terminate capsword
+ allUpper = 0;
+ if ((itsANumber == 2) && output->length > 0 &&
+ !(beforeAttributes & CTC_LitDigit) &&
+ !(beforeAttributes & CTC_NumericMode) &&
+ !(beforeAttributes & CTC_MidEndNumericMode))
+ itsANumber = 0;
+ back_selectRule(table, pos, mode, input, output, itsANumber, itsALetter,
+ ¤tDotslen, ¤tOpcode, ¤tRule, previousOpcode,
+ &doingMultind, &multindRule, beforeAttributes, &passInstructions, &passIC,
+ &patternMatch);
+ if (appliedRules != NULL && *appliedRulesCount < maxAppliedRules)
+ appliedRules[(*appliedRulesCount)++] = currentRule;
+ /* processing before replacement */
+ switch (currentOpcode) {
+ case CTO_LargeSign:
+ if (previousOpcode == CTO_LargeSign)
+ if (!insertSpace(table, pos, input, output, spacebuf, posMapping,
+ cursorPosition, cursorStatus, &nextUpper, allUpper,
+ allUpperPhrase))
+ goto failure;
+ break;
+ case CTO_CapsLetterRule:
+ nextUpper = 1;
+ allUpper = 0;
+ itsANumber = 0;
+ while (currentDotslen-- > 0) posMapping[pos++] = output->length;
+ continue;
+ break;
+ case CTO_BegCapsWordRule:
+ allUpper = 1;
+ itsANumber = 0;
+ while (currentDotslen-- > 0) posMapping[pos++] = output->length;
+ continue;
+ break;
+ case CTO_BegCapsRule:
+ allUpperPhrase = 1;
+ itsANumber = 0;
+ while (currentDotslen-- > 0) posMapping[pos++] = output->length;
+ continue;
+ break;
+ case CTO_EndCapsWordRule:
+ allUpper = 0;
+ itsANumber = 0;
+ while (currentDotslen-- > 0) posMapping[pos++] = output->length;
+ continue;
+ break;
+ case CTO_EndCapsRule:
+ allUpperPhrase = 0;
+ itsANumber = 0;
+ while (currentDotslen-- > 0) posMapping[pos++] = output->length;
+ continue;
+ break;
+ case CTO_LetterRule:
+ case CTO_NoContractRule:
+ itsALetter = 1;
+ itsANumber = 0;
+ while (currentDotslen-- > 0) posMapping[pos++] = output->length;
+ continue;
+ break;
+ case CTO_NumberRule:
+ itsANumber = 1; // Starting number
+ allUpper = 0;
+ while (currentDotslen-- > 0) posMapping[pos++] = output->length;
+ continue;
+ break;
+ case CTO_LitDigit:
+ itsANumber = 2; // In the middle of a number
+ break;
+ case CTO_BegCompRule:
+ itsANumber = 0;
+ case CTO_BegEmph1Rule:
+ case CTO_BegEmph2Rule:
+ case CTO_BegEmph3Rule:
+ case CTO_EndEmph1Rule:
+ case CTO_EndEmph2Rule:
+ case CTO_EndEmph3Rule:
+ case CTO_EndCompRule:
+ while (currentDotslen-- > 0) posMapping[pos++] = output->length;
+ continue;
+ break;
+
+ default:
+ break;
+ }
+
+ /* replacement processing */
+ switch (currentOpcode) {
+ case CTO_Context:
+ if (!back_passDoAction(table, displayTable, &pos, mode, input, output,
+ posMapping, cursorPosition, cursorStatus, &nextUpper, allUpper,
+ allUpperPhrase, currentOpcode, currentRule, passInstructions,
+ passIC, patternMatch))
+ return 0;
+ break;
+ case CTO_Replace:
+ while (currentDotslen-- > 0) posMapping[pos++] = output->length;
+ if (!putCharacters(¤tRule->charsdots[0], currentRule->charslen, table,
+ displayTable, pos, mode, input, output, posMapping,
+ cursorPosition, cursorStatus, &nextUpper, allUpper,
+ allUpperPhrase))
+ goto failure;
+ break;
+ case CTO_None:
+ if (!undefinedDots(input->chars[pos], mode, output, pos, posMapping))
+ goto failure;
+ pos++;
+ break;
+ case CTO_BegNum:
+ itsANumber = 1;
+ goto insertChars;
+ case CTO_EndNum:
+ itsANumber = 0;
+ goto insertChars;
+ case CTO_Space:
+ itsALetter = itsANumber = allUpper = nextUpper = 0;
+ goto insertChars;
+ default:
+ insertChars:
+ if (currentRule->charslen) {
+ if (!back_updatePositions(¤tRule->charsdots[0],
+ currentRule->dotslen, currentRule->charslen, table, pos,
+ input, output, posMapping, cursorPosition, cursorStatus,
+ &nextUpper, allUpper, allUpperPhrase))
+ goto failure;
+ pos += currentDotslen;
+ } else {
+ int srclim = pos + currentDotslen;
+ while (1) {
+ if (!putCharacter(input->chars[pos], table, displayTable, pos, mode,
+ input, output, posMapping, cursorPosition, cursorStatus,
+ &nextUpper, allUpper, allUpperPhrase))
+ goto failure;
+ if (++pos == srclim) break;
+ }
+ }
+ }
+
+ /* processing after replacement */
+ switch (currentOpcode) {
+ case CTO_JoinNum:
+ case CTO_JoinableWord:
+ if (!insertSpace(table, pos, input, output, spacebuf, posMapping,
+ cursorPosition, cursorStatus, &nextUpper, allUpper,
+ allUpperPhrase))
+ goto failure;
+ break;
+ default:
+ passSelectRule(table, pos, currentPass, input, ¤tOpcode, ¤tRule,
+ &passInstructions, &passIC, &patternMatch);
+ if (currentOpcode == CTO_Context) {
+ back_passDoAction(table, displayTable, &pos, mode, input, output,
+ posMapping, cursorPosition, cursorStatus, &nextUpper, allUpper,
+ allUpperPhrase, currentOpcode, currentRule, passInstructions,
+ passIC, patternMatch);
+ }
+ break;
+ }
+ if (((pos > 0) && checkAttr(input->chars[pos - 1], CTC_Space, 1, table) &&
+ (currentOpcode != CTO_JoinableWord))) {
+ srcword = pos;
+ destword = output->length;
+ }
+ if ((currentOpcode >= CTO_Always && currentOpcode <= CTO_None) ||
+ (currentOpcode >= CTO_Digit && currentOpcode <= CTO_LitDigit))
+ previousOpcode = currentOpcode;
+ } /* end of translation loop */
+failure:
+
+ if (destword != 0 && pos < input->length &&
+ !checkAttr(input->chars[pos], CTC_Space, 1, table)) {
+ pos = srcword;
+ output->length = destword;
+ }
+ if (pos < input->length) {
+ while (checkAttr(input->chars[pos], CTC_Space, 1, table))
+ if (++pos == input->length) break;
+ }
+ *realInlen = pos;
+ return 1;
+} /* translation completed */
+
+/* Multipass translation */
+
+static int
+matchCurrentInput(
+ const InString *input, int pos, const widechar *passInstructions, int passIC) {
+ int k;
+ int kk = pos;
+ for (k = passIC + 2; k < passIC + 2 + passInstructions[passIC + 1]; k++)
+ if (passInstructions[k] != input->chars[kk++]) return 0;
+ return 1;
+}
+
+static int
+back_swapTest(const TranslationTableHeader *table, const InString *input, int *pos,
+ const widechar *passInstructions, int passIC) {
+ int curLen;
+ int curTest;
+ int curSrc = *pos;
+ TranslationTableOffset swapRuleOffset;
+ TranslationTableRule *swapRule;
+ swapRuleOffset = (passInstructions[passIC + 1] << 16) | passInstructions[passIC + 2];
+ swapRule = (TranslationTableRule *)&table->ruleArea[swapRuleOffset];
+ for (curLen = 0; curLen < passInstructions[passIC] + 3; curLen++) {
+ for (curTest = 0; curTest < swapRule->charslen; curTest++) {
+ if (input->chars[curSrc] == swapRule->charsdots[curTest]) break;
+ }
+ if (curTest == swapRule->charslen) return 0;
+ curSrc++;
+ }
+ if (passInstructions[passIC + 2] == passInstructions[passIC + 3]) {
+ *pos = curSrc;
+ return 1;
+ }
+ while (curLen < passInstructions[passIC + 4]) {
+ for (curTest = 0; curTest < swapRule->charslen; curTest++) {
+ if (input->chars[curSrc] != swapRule->charsdots[curTest]) break;
+ }
+ if (curTest < swapRule->charslen)
+ if (curTest < swapRule->charslen) {
+ *pos = curSrc;
+ return 1;
+ }
+ curSrc++;
+ curLen++;
+ }
+ *pos = curSrc;
+ return 1;
+}
+
+static int
+back_swapReplace(int start, int end, const TranslationTableHeader *table,
+ const InString *input, OutString *output, int *posMapping,
+ const widechar *passInstructions, int passIC) {
+ TranslationTableOffset swapRuleOffset;
+ TranslationTableRule *swapRule;
+ widechar *replacements;
+ int p;
+ int lastPos = 0;
+ int lastRep = 0;
+ swapRuleOffset = (passInstructions[passIC + 1] << 16) | passInstructions[passIC + 2];
+ swapRule = (TranslationTableRule *)&table->ruleArea[swapRuleOffset];
+ replacements = &swapRule->charsdots[swapRule->charslen];
+ for (p = start; p < end; p++) {
+ int rep;
+ int test;
+ int k;
+ for (test = 0; test < swapRule->charslen; test++)
+ if (input->chars[p] == swapRule->charsdots[test]) break;
+ if (test == swapRule->charslen) return p;
+ if (test >= lastRep) {
+ k = lastPos;
+ rep = lastRep;
+ } else {
+ k = 0;
+ rep = 0;
+ }
+ while (k < swapRule->dotslen) {
+ if (rep == test) {
+ int l = replacements[k] - 1;
+ if (output->length + l >= output->maxlength) return 0;
+ posMapping[p] = output->length;
+ memcpy(&output->chars[output->length], &replacements[k + 1],
+ l * CHARSIZE);
+ output->length += l;
+ lastPos = k;
+ lastRep = rep;
+ break;
+ }
+ rep++;
+ k += replacements[k];
+ }
+ }
+ return p;
+}
+
+static int
+back_passDoTest(const TranslationTableHeader *table, int pos, const InString *input,
+ TranslationTableOpcode currentOpcode, const TranslationTableRule *currentRule,
+ const widechar **passInstructions, int *passIC, PassRuleMatch *match) {
+ int k;
+ int m;
+ int not = 0;
+ TranslationTableCharacterAttributes attributes;
+ *passInstructions = ¤tRule->charsdots[currentRule->charslen];
+ *passIC = 0;
+ match->startMatch = match->endMatch = pos;
+ match->startReplace = -1;
+ if (currentOpcode == CTO_Correct)
+ m = 0;
+ else
+ m = 1;
+ while (*passIC < currentRule->dotslen) {
+ int itsTrue = 1;
+ if (pos > input->length) return 0;
+ switch ((*passInstructions)[*passIC]) {
+ case pass_first:
+ if (pos != 0) itsTrue = 0;
+ (*passIC)++;
+ break;
+ case pass_last:
+ if (pos != input->length) itsTrue = 0;
+ (*passIC)++;
+ break;
+ case pass_lookback:
+ pos -= (*passInstructions)[*passIC + 1];
+ if (pos < 0) {
+ pos = 0;
+ itsTrue = 0;
+ }
+ *passIC += 2;
+ break;
+ case pass_not:
+ not = !not;
+ (*passIC)++;
+ continue;
+ case pass_string:
+ case pass_dots:
+ itsTrue = matchCurrentInput(input, pos, *passInstructions, *passIC);
+ pos += (*passInstructions)[*passIC + 1];
+ *passIC += (*passInstructions)[*passIC + 1] + 2;
+ break;
+ case pass_startReplace:
+ match->startReplace = pos;
+ (*passIC)++;
+ break;
+ case pass_endReplace:
+ match->endReplace = pos;
+ (*passIC)++;
+ break;
+ case pass_attributes:
+ attributes = ((*passInstructions)[*passIC + 1] << 16) |
+ (*passInstructions)[*passIC + 2];
+ for (k = 0; k < (*passInstructions)[*passIC + 3]; k++) {
+ if (pos >= input->length) {
+ itsTrue = 0;
+ break;
+ }
+ if (!(back_findCharOrDots(input->chars[pos], m, table)->attributes &
+ attributes)) {
+ itsTrue = 0;
+ break;
+ }
+ pos++;
+ }
+ if (itsTrue) {
+ for (k = (*passInstructions)[*passIC + 3];
+ k < (*passInstructions)[*passIC + 4] && pos < input->length;
+ k++) {
+ if (!(back_findCharOrDots(input->chars[pos], m, table)->attributes &
+ attributes))
+ break;
+ pos++;
+ }
+ }
+ *passIC += 5;
+ break;
+ case pass_swap:
+ itsTrue = back_swapTest(table, input, &pos, *passInstructions, *passIC);
+ *passIC += 5;
+ break;
+ case pass_endTest: {
+ (*passIC)++;
+ match->endMatch = pos;
+ if (match->startReplace == -1) {
+ match->startReplace = match->startMatch;
+ match->endReplace = match->endMatch;
+ }
+ return 1;
+ break;
+ }
+ default:
+ if (_lou_handlePassVariableTest(*passInstructions, passIC, &itsTrue)) break;
+ return 0;
+ }
+ if ((!not&&!itsTrue) || (not&&itsTrue)) return 0;
+ not = 0;
+ }
+ return 1;
+}
+
+static int
+copyCharacters(int from, int to, const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int mode, const InString *input,
+ OutString *output, int *posMapping, int *cursorPosition, int *cursorStatus,
+ int *nextUpper, int allUpper, int allUpperPhrase,
+ TranslationTableOpcode currentOpcode) {
+ if (currentOpcode == CTO_Context) {
+ while (from < to) {
+ if (!putCharacter(input->chars[from], table, displayTable, from, mode, input,
+ output, posMapping, cursorPosition, cursorStatus, nextUpper,
+ allUpper, allUpperPhrase))
+ return 0;
+ from++;
+ }
+ } else {
+ if (to > from) {
+ if ((output->length + to - from) > output->maxlength) return 0;
+ while (to > from) {
+ posMapping[from] = output->length;
+ output->chars[output->length] = input->chars[from];
+ output->length++;
+ from++;
+ }
+ }
+ }
+
+ return 1;
+}
+
+static int
+back_passDoAction(const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int *pos, int mode, const InString *input,
+ OutString *output, int *posMapping, int *cursorPosition, int *cursorStatus,
+ int *nextUpper, int allUpper, int allUpperPhrase,
+ TranslationTableOpcode currentOpcode, const TranslationTableRule *currentRule,
+ const widechar *passInstructions, int passIC, PassRuleMatch match) {
+ int k;
+ int destStartMatch = output->length;
+ int destStartReplace;
+ int newPos = match.endReplace;
+
+ if (!copyCharacters(match.startMatch, match.startReplace, table, displayTable, mode,
+ input, output, posMapping, cursorPosition, cursorStatus, nextUpper,
+ allUpper, allUpperPhrase, currentOpcode))
+ return 0;
+ destStartReplace = output->length;
+
+ for (k = match.startReplace; k < match.endReplace; k++)
+ posMapping[k] = output->length;
+ while (passIC < currentRule->dotslen) switch (passInstructions[passIC]) {
+ case pass_string:
+ case pass_dots:
+ if ((output->length + passInstructions[passIC + 1]) > output->maxlength)
+ return 0;
+ memcpy(&output->chars[output->length], &passInstructions[passIC + 2],
+ passInstructions[passIC + 1] * sizeof(*output->chars));
+ output->length += passInstructions[passIC + 1];
+ passIC += passInstructions[passIC + 1] + 2;
+ break;
+ case pass_swap:
+ if (!back_swapReplace(match.startReplace, match.endReplace, table, input,
+ output, posMapping, passInstructions, passIC))
+ return 0;
+ passIC += 3;
+ break;
+ case pass_omit:
+ passIC++;
+ break;
+ case pass_copy: {
+ int count = destStartReplace - destStartMatch;
+ if (count > 0) {
+ memmove(&output->chars[destStartMatch], &output->chars[destStartReplace],
+ count * sizeof(*output->chars));
+ output->length -= count;
+ destStartReplace = destStartMatch;
+ }
+ }
+
+ if (!copyCharacters(match.startReplace, match.endReplace, table, displayTable,
+ mode, input, output, posMapping, cursorPosition, cursorStatus,
+ nextUpper, allUpper, allUpperPhrase, currentOpcode))
+ return 0;
+ newPos = match.endMatch;
+ passIC++;
+ break;
+ default:
+ if (_lou_handlePassVariableAction(passInstructions, &passIC)) break;
+ return 0;
+ }
+ *pos = newPos;
+ return 1;
+}
+
+static void
+passSelectRule(const TranslationTableHeader *table, int pos, int currentPass,
+ const InString *input, TranslationTableOpcode *currentOpcode,
+ const TranslationTableRule **currentRule, const widechar **passInstructions,
+ int *passIC, PassRuleMatch *match) {
+ if (!findBackPassRule(table, pos, currentPass, input, currentOpcode, currentRule,
+ passInstructions, passIC, match)) {
+ *currentOpcode = CTO_Always;
+ }
+}
+
+static int
+translatePass(const TranslationTableHeader *table, const DisplayTableHeader *displayTable,
+ int mode, int currentPass, const InString *input, OutString *output,
+ int *posMapping, int *realInlen, int *cursorPosition, int *cursorStatus,
+ const TranslationTableRule **appliedRules, int *appliedRulesCount,
+ int maxAppliedRules) {
+ int pos;
+ int nextUpper = 0;
+ int allUpper = 0;
+ int allUpperPhrase = 0;
+ pos = output->length = 0;
+ _lou_resetPassVariables();
+ while (pos < input->length) { /* the main multipass translation loop */
+ TranslationTableOpcode currentOpcode;
+ const TranslationTableRule *currentRule; /* pointer to current rule in table */
+ const widechar *passInstructions;
+ int passIC; /* Instruction counter */
+ PassRuleMatch patternMatch;
+ passSelectRule(table, pos, currentPass, input, ¤tOpcode, ¤tRule,
+ &passInstructions, &passIC, &patternMatch);
+ switch (currentOpcode) {
+ case CTO_Pass2:
+ case CTO_Pass3:
+ case CTO_Pass4:
+ if (appliedRules != NULL && *appliedRulesCount < maxAppliedRules)
+ appliedRules[(*appliedRulesCount)++] = currentRule;
+ if (!back_passDoAction(table, displayTable, &pos, mode, input, output,
+ posMapping, cursorPosition, cursorStatus, &nextUpper, allUpper,
+ allUpperPhrase, currentOpcode, currentRule, passInstructions,
+ passIC, patternMatch))
+ goto failure;
+ break;
+ case CTO_Always:
+ if ((output->length + 1) > output->maxlength) goto failure;
+ posMapping[pos] = output->length;
+ output->chars[(output->length)++] = input->chars[pos++];
+ break;
+ default:
+ goto failure;
+ }
+ }
+failure:
+ if (pos < input->length) {
+ while (checkAttr(input->chars[pos], CTC_Space, 1, table))
+ if (++pos == input->length) break;
+ }
+ *realInlen = pos;
+ return 1;
+}
diff --git a/liblouis/lou_translateString.c b/liblouis/lou_translateString.c
new file mode 100644
index 0000000..4db361f
--- /dev/null
+++ b/liblouis/lou_translateString.c
@@ -0,0 +1,3877 @@
+/* liblouis Braille Translation and Back-Translation Library
+
+ Based on the Linux screenreader BRLTTY, copyright (C) 1999-2006 by The
+ BRLTTY Team
+
+ Copyright (C) 2004, 2005, 2006 ViewPlus Technologies, Inc. www.viewplus.com
+ Copyright (C) 2004, 2005, 2006 JJB Software, Inc. www.jjb-software.com
+ Copyright (C) 2016 Mike Gray, American Printing House for the Blind
+ Copyright (C) 2016 Davy Kager, Dedicon
+
+ This file is part of liblouis.
+
+ liblouis is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 2.1 of the License, or
+ (at your option) any later version.
+
+ liblouis is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file
+ * @brief Translate to braille
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "internal.h"
+
+/* additional bits in typebuf */
+#define SYLLABLE_MARKER_1 0x2000
+#define SYLLABLE_MARKER_2 0x4000
+#define CAPSEMPH 0x8000
+
+#define EMPHASIS 0x3fff // all typeform bits that can be used
+
+/* bits for wordBuffer */
+#define WORD_CHAR 0x00000001
+#define WORD_RESET 0x00000002
+#define WORD_STOP 0x00000004
+#define WORD_WHOLE 0x00000008
+
+typedef struct {
+ int size;
+ widechar **buffers;
+ int *inUse;
+ widechar *(*alloc)(int index, int length);
+ void (*free)(widechar *);
+} StringBufferPool;
+
+static widechar *
+allocStringBuffer(int index, int length) {
+ return _lou_allocMem(alloc_passbuf, index, 0, length);
+}
+
+static const StringBufferPool *stringBufferPool = NULL;
+
+static void
+initStringBufferPool() {
+ static widechar *stringBuffers[MAXPASSBUF] = { NULL };
+ static int stringBuffersInUse[MAXPASSBUF] = { 0 };
+ StringBufferPool *pool = malloc(sizeof(StringBufferPool));
+ pool->size = MAXPASSBUF;
+ pool->buffers = stringBuffers;
+ pool->inUse = stringBuffersInUse;
+ pool->alloc = &allocStringBuffer;
+ pool->free = NULL;
+ stringBufferPool = pool;
+}
+
+static int
+getStringBuffer(int length) {
+ int i;
+ for (i = 0; i < stringBufferPool->size; i++) {
+ if (!stringBufferPool->inUse[i]) {
+ stringBufferPool->buffers[i] = stringBufferPool->alloc(i, length);
+ stringBufferPool->inUse[i] = 1;
+ return i;
+ }
+ }
+ _lou_outOfMemory();
+ return -1;
+}
+
+static int
+releaseStringBuffer(int idx) {
+ if (idx >= 0 && idx < stringBufferPool->size) {
+ int inUse = stringBufferPool->inUse[idx];
+ if (inUse && stringBufferPool->free)
+ stringBufferPool->free(stringBufferPool->buffers[idx]);
+ stringBufferPool->inUse[idx] = 0;
+ return inUse;
+ }
+ return 0;
+}
+
+typedef struct {
+ int bufferIndex;
+ const widechar *chars;
+ int length;
+} InString;
+
+typedef struct {
+ int bufferIndex;
+ widechar *chars;
+ int maxlength;
+ int length;
+} OutString;
+
+typedef struct {
+ int startMatch;
+ int startReplace;
+ int endReplace;
+ int endMatch;
+} PassRuleMatch;
+
+static int
+putCharacter(widechar c, const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int pos, const InString *input,
+ OutString *output, int *posMapping, int *cursorPosition, int *cursorStatus,
+ int mode);
+static int
+passDoTest(const TranslationTableHeader *table, int pos, const InString *input,
+ int transOpcode, const TranslationTableRule *transRule, int *passCharDots,
+ const widechar **passInstructions, int *passIC, PassRuleMatch *match,
+ TranslationTableRule **groupingRule, widechar *groupingOp);
+static int
+passDoAction(const TranslationTableHeader *table, const DisplayTableHeader *displayTable,
+ const InString **input, OutString *output, int *posMapping, int transOpcode,
+ const TranslationTableRule **transRule, int passCharDots,
+ const widechar *passInstructions, int passIC, int *pos, PassRuleMatch match,
+ int *cursorPosition, int *cursorStatus, TranslationTableRule *groupingRule,
+ widechar groupingOp, int mode);
+
+static const TranslationTableRule **appliedRules;
+static int maxAppliedRules;
+static int appliedRulesCount;
+
+static TranslationTableCharacter *
+findCharOrDots(widechar c, int m, const TranslationTableHeader *table) {
+ /* Look up character or dot pattern in the appropriate
+ * table. */
+ static TranslationTableCharacter noChar = { 0, 0, 0, CTC_Space, 32, 32, 32 };
+ static TranslationTableCharacter noDots = { 0, 0, 0, CTC_Space, LOU_DOTS, LOU_DOTS,
+ LOU_DOTS };
+ TranslationTableCharacter *notFound;
+ TranslationTableCharacter *character;
+ TranslationTableOffset bucket;
+ unsigned long int makeHash = _lou_charHash(c);
+ if (m == 0) {
+ bucket = table->characters[makeHash];
+ notFound = &noChar;
+ } else {
+ bucket = table->dots[makeHash];
+ notFound = &noDots;
+ }
+ while (bucket) {
+ character = (TranslationTableCharacter *)&table->ruleArea[bucket];
+ if (character->realchar == c) return character;
+ bucket = character->next;
+ }
+ notFound->realchar = notFound->uppercase = notFound->lowercase = c;
+ return notFound;
+}
+
+static int
+checkAttr(const widechar c, const TranslationTableCharacterAttributes a, int m,
+ const TranslationTableHeader *table) {
+ return (((findCharOrDots(c, m, table))->attributes & a) ? 1 : 0);
+}
+
+static int
+checkAttr_safe(const InString *input, int pos,
+ const TranslationTableCharacterAttributes a, int m,
+ const TranslationTableHeader *table) {
+ return ((pos < input->length) ? checkAttr(input->chars[pos], a, m, table) : 0);
+}
+
+static int
+findForPassRule(const TranslationTableHeader *table, int pos, int currentPass,
+ const InString *input, int *transOpcode, const TranslationTableRule **transRule,
+ int *transCharslen, int *passCharDots, widechar const **passInstructions,
+ int *passIC, PassRuleMatch *match, TranslationTableRule **groupingRule,
+ widechar *groupingOp) {
+ int save_transCharslen = *transCharslen;
+ const TranslationTableRule *save_transRule = *transRule;
+ TranslationTableOpcode save_transOpcode = *transOpcode;
+ TranslationTableOffset ruleOffset;
+ ruleOffset = table->forPassRules[currentPass];
+ *transCharslen = 0;
+ while (ruleOffset) {
+ *transRule = (TranslationTableRule *)&table->ruleArea[ruleOffset];
+ *transOpcode = (*transRule)->opcode;
+ if (passDoTest(table, pos, input, *transOpcode, *transRule, passCharDots,
+ passInstructions, passIC, match, groupingRule, groupingOp))
+ return 1;
+ ruleOffset = (*transRule)->charsnext;
+ }
+ *transCharslen = save_transCharslen;
+ *transRule = save_transRule;
+ *transOpcode = save_transOpcode;
+ return 0;
+}
+
+static int
+compareChars(const widechar *address1, const widechar *address2, int count, int m,
+ const TranslationTableHeader *table) {
+ int k;
+ if (!count) return 0;
+ for (k = 0; k < count; k++)
+ if ((findCharOrDots(address1[k], m, table))->lowercase !=
+ (findCharOrDots(address2[k], m, table))->lowercase)
+ return 0;
+ return 1;
+}
+
+static int
+makeCorrections(const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, const InString *input, OutString *output,
+ int *posMapping, formtype *typebuf, int *realInlen, int *cursorPosition,
+ int *cursorStatus, int mode) {
+ int pos;
+ int transOpcode;
+ const TranslationTableRule *transRule;
+ int transCharslen;
+ int passCharDots;
+ const widechar *passInstructions;
+ int passIC; /* Instruction counter */
+ PassRuleMatch patternMatch;
+ TranslationTableRule *groupingRule;
+ widechar groupingOp;
+ const InString *origInput = input;
+ if (!table->corrections) return 1;
+ pos = 0;
+ output->length = 0;
+ int posIncremented = 1;
+ _lou_resetPassVariables();
+ while (pos < input->length) {
+ int length = input->length - pos;
+ int tryThis = 0;
+ // check posIncremented to avoid endless loop
+ if (!(posIncremented &&
+ findForPassRule(table, pos, 0, input, &transOpcode, &transRule,
+ &transCharslen, &passCharDots, &passInstructions, &passIC,
+ &patternMatch, &groupingRule, &groupingOp)))
+ while (tryThis < 3) {
+ TranslationTableOffset ruleOffset = 0;
+ switch (tryThis) {
+ case 0:
+ if (!(length >= 2)) break;
+ ruleOffset = table->forRules[_lou_stringHash(
+ &input->chars[pos], 1, table)];
+ break;
+ case 1:
+ if (!(length >= 1)) break;
+ length = 1;
+ ruleOffset = findCharOrDots(input->chars[pos], 0, table)->otherRules;
+ break;
+ case 2: /* No rule found */
+ transOpcode = CTO_Always;
+ ruleOffset = 0;
+ break;
+ }
+ while (ruleOffset) {
+ transRule = (TranslationTableRule *)&table->ruleArea[ruleOffset];
+ transOpcode = transRule->opcode;
+ transCharslen = transRule->charslen;
+ if (tryThis == 1 ||
+ (transCharslen <= length &&
+ compareChars(&transRule->charsdots[0],
+ &input->chars[pos], transCharslen, 0,
+ table))) {
+ if (posIncremented && transOpcode == CTO_Correct &&
+ passDoTest(table, pos, input, transOpcode, transRule,
+ &passCharDots, &passInstructions, &passIC,
+ &patternMatch, &groupingRule, &groupingOp)) {
+ tryThis = 4;
+ break;
+ }
+ }
+ ruleOffset = transRule->charsnext;
+ }
+ tryThis++;
+ }
+ posIncremented = 1;
+
+ switch (transOpcode) {
+ case CTO_Always:
+ if (output->length >= output->maxlength) goto failure;
+ posMapping[output->length] = pos;
+ output->chars[output->length++] = input->chars[pos++];
+ break;
+ case CTO_Correct: {
+ const InString *inputBefore = input;
+ int posBefore = pos;
+ if (appliedRules != NULL && appliedRulesCount < maxAppliedRules)
+ appliedRules[appliedRulesCount++] = transRule;
+ if (!passDoAction(table, displayTable, &input, output, posMapping,
+ transOpcode, &transRule, passCharDots, passInstructions, passIC,
+ &pos, patternMatch, cursorPosition, cursorStatus, groupingRule,
+ groupingOp, mode))
+ goto failure;
+ if (input->bufferIndex != inputBefore->bufferIndex &&
+ inputBefore->bufferIndex != origInput->bufferIndex)
+ releaseStringBuffer(inputBefore->bufferIndex);
+ if (pos == posBefore) posIncremented = 0;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ { // We have to transform typebuf accordingly
+ int k;
+ formtype *typebuf_temp;
+ if ((typebuf_temp = malloc(output->length * sizeof(formtype))) == NULL)
+ _lou_outOfMemory();
+ for (k = 0; k < output->length; k++)
+ // posMapping will never be < 0 but in theory it could
+ if (posMapping[k] < 0)
+ typebuf_temp[k] = typebuf[0]; // prepend to next
+ else if (posMapping[k] >= input->length)
+ typebuf_temp[k] = typebuf[input->length - 1]; // append to previous
+ else
+ typebuf_temp[k] = typebuf[posMapping[k]];
+ memcpy(typebuf, typebuf_temp, output->length * sizeof(formtype));
+ free(typebuf_temp);
+ }
+
+failure:
+ *realInlen = pos;
+ if (input->bufferIndex != origInput->bufferIndex)
+ releaseStringBuffer(input->bufferIndex);
+ return 1;
+}
+
+static int
+matchCurrentInput(
+ const InString *input, int pos, const widechar *passInstructions, int passIC) {
+ int k;
+ int kk = pos;
+ for (k = passIC + 2;
+ ((k < passIC + 2 + passInstructions[passIC + 1]) && (kk < input->length));
+ k++)
+ if (input->chars[kk] == LOU_ENDSEGMENT ||
+ passInstructions[k] != input->chars[kk++])
+ return 0;
+ return 1;
+}
+
+static int
+swapTest(int swapIC, int *pos, const TranslationTableHeader *table, const InString *input,
+ const widechar *passInstructions) {
+ int p = *pos;
+ TranslationTableOffset swapRuleOffset;
+ TranslationTableRule *swapRule;
+ swapRuleOffset = (passInstructions[swapIC + 1] << 16) | passInstructions[swapIC + 2];
+ swapRule = (TranslationTableRule *)&table->ruleArea[swapRuleOffset];
+ while (p - *pos < passInstructions[swapIC + 3]) {
+ int test;
+ if (swapRule->opcode == CTO_SwapDd) {
+ for (test = 1; test < swapRule->charslen; test += 2) {
+ if (input->chars[p] == swapRule->charsdots[test]) break;
+ }
+ } else {
+ for (test = 0; test < swapRule->charslen; test++) {
+ if (input->chars[p] == swapRule->charsdots[test]) break;
+ }
+ }
+ if (test >= swapRule->charslen) return 0;
+ p++;
+ }
+ if (passInstructions[swapIC + 3] == passInstructions[swapIC + 4]) {
+ *pos = p;
+ return 1;
+ }
+ while (p - *pos < passInstructions[swapIC + 4]) {
+ int test;
+ if (swapRule->opcode == CTO_SwapDd) {
+ for (test = 1; test < swapRule->charslen; test += 2) {
+ if (input->chars[p] == swapRule->charsdots[test]) break;
+ }
+ } else {
+ for (test = 0; test < swapRule->charslen; test++) {
+ if (input->chars[p] == swapRule->charsdots[test]) break;
+ }
+ }
+ if (test >= swapRule->charslen) {
+ *pos = p;
+ return 1;
+ }
+ p++;
+ }
+ *pos = p;
+ return 1;
+}
+
+static int
+swapReplace(int start, int end, const TranslationTableHeader *table,
+ const InString *input, OutString *output, int *posMapping,
+ const widechar *passInstructions, int passIC) {
+ TranslationTableOffset swapRuleOffset;
+ TranslationTableRule *swapRule;
+ widechar *replacements;
+ int p;
+ swapRuleOffset = (passInstructions[passIC + 1] << 16) | passInstructions[passIC + 2];
+ swapRule = (TranslationTableRule *)&table->ruleArea[swapRuleOffset];
+ replacements = &swapRule->charsdots[swapRule->charslen];
+ for (p = start; p < end; p++) {
+ int rep;
+ int test;
+ int k;
+ if (swapRule->opcode == CTO_SwapDd) {
+ // A sequence of dot patterns is encoded as the length of the first dot
+ // pattern (single widechar) followed by the contents of the first dot pattern
+ // (one widechar per cell) followed by the length of the second dot pattern,
+ // etc. See the function `compileSwapDots'. Because the third operand of a
+ // swapdd rule can only contain single-cell dot patterns, the elements at
+ // index 0, 2, ... are "1" and the elements at index 1, 3, ... are the dot
+ // patterns.
+ for (test = 0; test * 2 + 1 < swapRule->charslen; test++)
+ if (input->chars[p] == swapRule->charsdots[test * 2 + 1]) break;
+ if (test * 2 == swapRule->charslen) continue;
+ } else {
+ for (test = 0; test < swapRule->charslen; test++)
+ if (input->chars[p] == swapRule->charsdots[test]) break;
+ if (test == swapRule->charslen) continue;
+ }
+ k = 0;
+ for (rep = 0; rep < test; rep++)
+ if (swapRule->opcode == CTO_SwapCc)
+ k++;
+ else
+ k += replacements[k];
+ if (swapRule->opcode == CTO_SwapCc) {
+ if ((output->length + 1) > output->maxlength) return 0;
+ posMapping[output->length] = p;
+ output->chars[output->length++] = replacements[k];
+ } else {
+ int l = replacements[k] - 1;
+ int d = output->length + l;
+ if (d > output->maxlength) return 0;
+ while (--d >= output->length) posMapping[d] = p;
+ memcpy(&output->chars[output->length], &replacements[k + 1],
+ l * sizeof(*output->chars));
+ output->length += l;
+ }
+ }
+ return 1;
+}
+
+static int
+replaceGrouping(const TranslationTableHeader *table, const InString **input,
+ OutString *output, int transOpcode, int passCharDots,
+ const widechar *passInstructions, int passIC, int startReplace,
+ TranslationTableRule *groupingRule, widechar groupingOp) {
+ widechar startCharDots = groupingRule->charsdots[2 * passCharDots];
+ widechar endCharDots = groupingRule->charsdots[2 * passCharDots + 1];
+ int p;
+ int level = 0;
+ TranslationTableOffset replaceOffset =
+ passInstructions[passIC + 1] << 16 | (passInstructions[passIC + 2] & 0xff);
+ TranslationTableRule *replaceRule =
+ (TranslationTableRule *)&table->ruleArea[replaceOffset];
+ widechar replaceStart = replaceRule->charsdots[2 * passCharDots];
+ widechar replaceEnd = replaceRule->charsdots[2 * passCharDots + 1];
+ if (groupingOp == pass_groupstart) {
+ for (p = startReplace + 1; p < (*input)->length; p++) {
+ if ((*input)->chars[p] == startCharDots) level--;
+ if ((*input)->chars[p] == endCharDots) level++;
+ if (level == 1) break;
+ }
+ if (p == (*input)->length)
+ return 0;
+ else {
+ // Create a new string instead of modifying it. This is slightly less
+ // efficient, but makes the code more readable. Grouping is not a much used
+ // feature anyway.
+ int idx = getStringBuffer((*input)->length);
+ widechar *chars = stringBufferPool->buffers[idx];
+ memcpy(chars, (*input)->chars, (*input)->length * sizeof(widechar));
+ chars[startReplace] = replaceStart;
+ chars[p] = replaceEnd;
+ static InString stringStore;
+ stringStore = (InString){
+ .chars = chars, .length = (*input)->length, .bufferIndex = idx
+ };
+ *input = &stringStore;
+ }
+ } else {
+ if (transOpcode == CTO_Context) {
+ startCharDots = groupingRule->charsdots[2];
+ endCharDots = groupingRule->charsdots[3];
+ replaceStart = replaceRule->charsdots[2];
+ replaceEnd = replaceRule->charsdots[3];
+ }
+ output->chars[output->length] = replaceEnd;
+ for (p = output->length - 1; p >= 0; p--) {
+ if (output->chars[p] == endCharDots) level--;
+ if (output->chars[p] == startCharDots) level++;
+ if (level == 1) break;
+ }
+ if (p < 0) return 0;
+ output->chars[p] = replaceStart;
+ output->length++;
+ }
+ return 1;
+}
+
+static int
+removeGrouping(const InString **input, OutString *output, int passCharDots,
+ int startReplace, TranslationTableRule *groupingRule, widechar groupingOp) {
+ widechar startCharDots = groupingRule->charsdots[2 * passCharDots];
+ widechar endCharDots = groupingRule->charsdots[2 * passCharDots + 1];
+ int p;
+ int level = 0;
+ if (groupingOp == pass_groupstart) {
+ for (p = startReplace + 1; p < (*input)->length; p++) {
+ if ((*input)->chars[p] == startCharDots) level--;
+ if ((*input)->chars[p] == endCharDots) level++;
+ if (level == 1) break;
+ }
+ if (p == (*input)->length)
+ return 0;
+ else {
+ // Create a new string instead of modifying it. This is slightly less
+ // efficient, but makes the code more readable. Grouping is not a much used
+ // feature anyway.
+ int idx = getStringBuffer((*input)->length);
+ widechar *chars = stringBufferPool->buffers[idx];
+ int len = 0;
+ int k;
+ for (k = 0; k < (*input)->length; k++) {
+ if (k == p) continue;
+ chars[len++] = (*input)->chars[k];
+ }
+ static InString stringStore;
+ stringStore = (InString){ .chars = chars, .length = len, .bufferIndex = idx };
+ *input = &stringStore;
+ }
+ } else {
+ for (p = output->length - 1; p >= 0; p--) {
+ if (output->chars[p] == endCharDots) level--;
+ if (output->chars[p] == startCharDots) level++;
+ if (level == 1) break;
+ }
+ if (p < 0) return 0;
+ p++;
+ for (; p < output->length; p++) output->chars[p - 1] = output->chars[p];
+ output->length--;
+ }
+ return 1;
+}
+
+static int
+doPassSearch(const TranslationTableHeader *table, const InString *input,
+ const TranslationTableRule *transRule, int passCharDots, int pos,
+ const widechar *passInstructions, int passIC, int *searchIC, int *searchPos,
+ TranslationTableRule *groupingRule, widechar groupingOp) {
+ int level = 0;
+ int k, kk;
+ int not = 0; // whether next operand should be reversed
+ TranslationTableOffset ruleOffset;
+ TranslationTableRule *rule;
+ TranslationTableCharacterAttributes attributes;
+ while (pos < input->length) {
+ *searchIC = passIC + 1;
+ *searchPos = pos;
+ while (*searchIC < transRule->dotslen) {
+ int itsTrue = 1; // whether we have a match or not
+ if (*searchPos > input->length) return 0;
+ switch (passInstructions[*searchIC]) {
+ case pass_lookback:
+ *searchPos -= passInstructions[*searchIC + 1];
+ if (*searchPos < 0) {
+ *searchPos = 0;
+ itsTrue = 0;
+ }
+ *searchIC += 2;
+ break;
+ case pass_not:
+ not = !not;
+ (*searchIC)++;
+ continue;
+ case pass_string:
+ case pass_dots:
+ kk = *searchPos;
+ for (k = *searchIC + 2;
+ k < *searchIC + 2 + passInstructions[*searchIC + 1]; k++)
+ if (input->chars[kk] == LOU_ENDSEGMENT ||
+ passInstructions[k] != input->chars[kk++]) {
+ itsTrue = 0;
+ break;
+ }
+ *searchPos += passInstructions[*searchIC + 1];
+ *searchIC += passInstructions[*searchIC + 1] + 2;
+ break;
+ case pass_startReplace:
+ (*searchIC)++;
+ break;
+ case pass_endReplace:
+ (*searchIC)++;
+ break;
+ case pass_attributes:
+ attributes = (passInstructions[*searchIC + 1] << 16) |
+ passInstructions[*searchIC + 2];
+ for (k = 0; k < passInstructions[*searchIC + 3]; k++) {
+ if (input->chars[*searchPos] == LOU_ENDSEGMENT)
+ itsTrue = 0;
+ else {
+ itsTrue = ((findCharOrDots(input->chars[(*searchPos)++],
+ passCharDots, table)
+ ->attributes &
+ attributes)
+ ? 1
+ : 0);
+ if (not) itsTrue = !itsTrue;
+ }
+ if (!itsTrue) break;
+ }
+ if (itsTrue) {
+ for (k = passInstructions[*searchIC + 3];
+ k < passInstructions[*searchIC + 4]; k++) {
+ if (input->chars[*searchPos] == LOU_ENDSEGMENT) {
+ itsTrue = 0;
+ break;
+ }
+ if (!(findCharOrDots(
+ input->chars[*searchPos], passCharDots, table)
+ ->attributes &
+ attributes)) {
+ if (!not) break;
+ } else if (not)
+ break;
+ (*searchPos)++;
+ }
+ }
+ not = 0;
+ *searchIC += 5;
+ break;
+ case pass_groupstart:
+ case pass_groupend:
+ ruleOffset = (passInstructions[*searchIC + 1] << 16) |
+ passInstructions[*searchIC + 2];
+ rule = (TranslationTableRule *)&table->ruleArea[ruleOffset];
+ if (passInstructions[*searchIC] == pass_groupstart)
+ itsTrue = (input->chars[*searchPos] ==
+ rule->charsdots[2 * passCharDots])
+ ? 1
+ : 0;
+ else
+ itsTrue = (input->chars[*searchPos] ==
+ rule->charsdots[2 * passCharDots + 1])
+ ? 1
+ : 0;
+ if (groupingRule != NULL && groupingOp == pass_groupstart &&
+ rule == groupingRule) {
+ if (input->chars[*searchPos] == rule->charsdots[2 * passCharDots])
+ level--;
+ else if (input->chars[*searchPos] ==
+ rule->charsdots[2 * passCharDots + 1])
+ level++;
+ }
+ (*searchPos)++;
+ *searchIC += 3;
+ break;
+ case pass_swap:
+ itsTrue = swapTest(*searchIC, searchPos, table, input, passInstructions);
+ *searchIC += 5;
+ break;
+ case pass_endTest:
+ if (itsTrue) {
+ if ((groupingRule && level == 1) || !groupingRule) return 1;
+ }
+ *searchIC = transRule->dotslen;
+ break;
+ default:
+ if (_lou_handlePassVariableTest(passInstructions, searchIC, &itsTrue))
+ break;
+ break;
+ }
+ if ((!not&&!itsTrue) || (not&&itsTrue)) break;
+ not = 0;
+ }
+ pos++;
+ }
+ return 0;
+}
+
+static int
+passDoTest(const TranslationTableHeader *table, int pos, const InString *input,
+ int transOpcode, const TranslationTableRule *transRule, int *passCharDots,
+ widechar const **passInstructions, int *passIC, PassRuleMatch *match,
+ TranslationTableRule **groupingRule, widechar *groupingOp) {
+ int searchIC, searchPos;
+ int k;
+ int not = 0; // whether next operand should be reversed
+ TranslationTableOffset ruleOffset = 0;
+ TranslationTableRule *rule = NULL;
+ TranslationTableCharacterAttributes attributes = 0;
+ int startMatch = pos;
+ int endMatch = pos;
+ int startReplace = -1;
+ int endReplace = -1;
+ *groupingRule = NULL;
+ *passInstructions = &transRule->charsdots[transRule->charslen];
+ *passIC = 0;
+ if (transOpcode == CTO_Context || transOpcode == CTO_Correct)
+ *passCharDots = 0;
+ else
+ *passCharDots = 1;
+ while (*passIC < transRule->dotslen) {
+ int itsTrue = 1; // whether we have a match or not
+ if (pos > input->length) return 0;
+ switch ((*passInstructions)[*passIC]) {
+ case pass_first:
+ if (pos != 0) itsTrue = 0;
+ (*passIC)++;
+ break;
+ case pass_last:
+ if (pos != input->length) itsTrue = 0;
+ (*passIC)++;
+ break;
+ case pass_lookback:
+ pos -= (*passInstructions)[*passIC + 1];
+ if (pos < 0) {
+ searchPos = 0;
+ itsTrue = 0;
+ }
+ *passIC += 2;
+ break;
+ case pass_not:
+ not = !not;
+ (*passIC)++;
+ continue;
+ case pass_string:
+ case pass_dots:
+ itsTrue = matchCurrentInput(input, pos, *passInstructions, *passIC);
+ pos += (*passInstructions)[*passIC + 1];
+ *passIC += (*passInstructions)[*passIC + 1] + 2;
+ break;
+ case pass_startReplace:
+ startReplace = pos;
+ (*passIC)++;
+ break;
+ case pass_endReplace:
+ endReplace = pos;
+ (*passIC)++;
+ break;
+ case pass_attributes:
+ attributes = ((*passInstructions)[*passIC + 1] << 16) |
+ (*passInstructions)[*passIC + 2];
+ for (k = 0; k < (*passInstructions)[*passIC + 3]; k++) {
+ if (pos >= input->length) {
+ itsTrue = 0;
+ break;
+ }
+ if (input->chars[pos] == LOU_ENDSEGMENT) {
+ itsTrue = 0;
+ break;
+ }
+ if (!(findCharOrDots(input->chars[pos], *passCharDots, table)
+ ->attributes &
+ attributes)) {
+ if (!not) {
+ itsTrue = 0;
+ break;
+ }
+ } else if (not) {
+ itsTrue = 0;
+ break;
+ }
+ pos++;
+ }
+ if (itsTrue) {
+ for (k = (*passInstructions)[*passIC + 3];
+ k < (*passInstructions)[*passIC + 4] && pos < input->length;
+ k++) {
+ if (input->chars[pos] == LOU_ENDSEGMENT) {
+ itsTrue = 0;
+ break;
+ }
+ if (!(findCharOrDots(input->chars[pos], *passCharDots, table)
+ ->attributes &
+ attributes)) {
+ if (!not) break;
+ } else if (not)
+ break;
+ pos++;
+ }
+ }
+ not = 0;
+ *passIC += 5;
+ break;
+ case pass_groupstart:
+ case pass_groupend:
+ ruleOffset = ((*passInstructions)[*passIC + 1] << 16) |
+ (*passInstructions)[*passIC + 2];
+ rule = (TranslationTableRule *)&table->ruleArea[ruleOffset];
+ if (*passIC == 0 ||
+ (*passIC > 0 &&
+ (*passInstructions)[*passIC - 1] == pass_startReplace)) {
+ *groupingRule = rule;
+ *groupingOp = (*passInstructions)[*passIC];
+ }
+ if ((*passInstructions)[*passIC] == pass_groupstart)
+ itsTrue =
+ (input->chars[pos] == rule->charsdots[2 * *passCharDots]) ? 1 : 0;
+ else
+ itsTrue = (input->chars[pos] == rule->charsdots[2 * *passCharDots + 1])
+ ? 1
+ : 0;
+ pos++;
+ *passIC += 3;
+ break;
+ case pass_swap:
+ itsTrue = swapTest(*passIC, &pos, table, input, *passInstructions);
+ *passIC += 5;
+ break;
+ case pass_search:
+ itsTrue = doPassSearch(table, input, transRule, *passCharDots, pos,
+ *passInstructions, *passIC, &searchIC, &searchPos, *groupingRule,
+ *groupingOp);
+ if ((!not&&!itsTrue) || (not&&itsTrue)) return 0;
+ *passIC = searchIC;
+ pos = searchPos;
+ case pass_endTest:
+ (*passIC)++;
+ endMatch = pos;
+ if (startReplace == -1) {
+ startReplace = startMatch;
+ endReplace = endMatch;
+ }
+ if (startReplace < startMatch)
+ return 0;
+ else {
+ *match = (PassRuleMatch){ .startMatch = startMatch,
+ .startReplace = startReplace,
+ .endReplace = endReplace,
+ .endMatch = endMatch };
+ return 1;
+ }
+ break;
+ default:
+ if (_lou_handlePassVariableTest(*passInstructions, passIC, &itsTrue)) break;
+ return 0;
+ }
+ if ((!not&&!itsTrue) || (not&&itsTrue)) return 0;
+ not = 0;
+ }
+ return 0;
+}
+
+static int
+copyCharacters(int from, int to, const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, const InString *input, OutString *output,
+ int *posMapping, int transOpcode, int *cursorPosition, int *cursorStatus,
+ int mode) {
+ if (transOpcode == CTO_Context) {
+ while (from < to) {
+ if (!putCharacter(input->chars[from], table, displayTable, from, input,
+ output, posMapping, cursorPosition, cursorStatus, mode))
+ return 0;
+ from++;
+ }
+ } else {
+ if (to > from) {
+ if ((output->length + to - from) > output->maxlength) return 0;
+ while (to > from) {
+ posMapping[output->length] = from;
+ output->chars[output->length] = input->chars[from];
+ output->length++;
+ from++;
+ }
+ }
+ }
+
+ return 1;
+}
+
+static int
+passDoAction(const TranslationTableHeader *table, const DisplayTableHeader *displayTable,
+ const InString **input, OutString *output, int *posMapping, int transOpcode,
+ const TranslationTableRule **transRule, int passCharDots,
+ const widechar *passInstructions, int passIC, int *pos, PassRuleMatch match,
+ int *cursorPosition, int *cursorStatus, TranslationTableRule *groupingRule,
+ widechar groupingOp, int mode) {
+ int k;
+ TranslationTableOffset ruleOffset = 0;
+ TranslationTableRule *rule = NULL;
+ int destStartMatch = output->length;
+ int destStartReplace;
+ int newPos = match.endReplace;
+
+ if (!copyCharacters(match.startMatch, match.startReplace, table, displayTable, *input,
+ output, posMapping, transOpcode, cursorPosition, cursorStatus, mode))
+ return 0;
+ destStartReplace = output->length;
+
+ while (passIC < (*transRule)->dotslen) switch (passInstructions[passIC]) {
+ case pass_string:
+ case pass_dots:
+ if ((output->length + passInstructions[passIC + 1]) > output->maxlength)
+ return 0;
+ for (k = 0; k < passInstructions[passIC + 1]; ++k)
+ posMapping[output->length + k] = match.startReplace;
+ memcpy(&output->chars[output->length], &passInstructions[passIC + 2],
+ passInstructions[passIC + 1] * CHARSIZE);
+ output->length += passInstructions[passIC + 1];
+ passIC += passInstructions[passIC + 1] + 2;
+ break;
+ case pass_groupstart:
+ ruleOffset =
+ (passInstructions[passIC + 1] << 16) | passInstructions[passIC + 2];
+ rule = (TranslationTableRule *)&table->ruleArea[ruleOffset];
+ posMapping[output->length] = match.startMatch;
+ output->chars[output->length++] = rule->charsdots[2 * passCharDots];
+ passIC += 3;
+ break;
+ case pass_groupend:
+ ruleOffset =
+ (passInstructions[passIC + 1] << 16) | passInstructions[passIC + 2];
+ rule = (TranslationTableRule *)&table->ruleArea[ruleOffset];
+ posMapping[output->length] = match.startMatch;
+ output->chars[output->length++] = rule->charsdots[2 * passCharDots + 1];
+ passIC += 3;
+ break;
+ case pass_swap:
+ if (!swapReplace(match.startReplace, match.endReplace, table, *input, output,
+ posMapping, passInstructions, passIC))
+ return 0;
+ passIC += 3;
+ break;
+ case pass_groupreplace:
+ if (!groupingRule ||
+ !replaceGrouping(table, input, output, transOpcode, passCharDots,
+ passInstructions, passIC, match.startReplace, groupingRule,
+ groupingOp))
+ return 0;
+ passIC += 3;
+ break;
+ case pass_omit:
+ if (groupingRule)
+ removeGrouping(input, output, passCharDots, match.startReplace,
+ groupingRule, groupingOp);
+ passIC++;
+ break;
+ case pass_copy: {
+ int count = destStartReplace - destStartMatch;
+ if (count > 0) {
+ memmove(&output->chars[destStartMatch], &output->chars[destStartReplace],
+ count * sizeof(*output->chars));
+ output->length -= count;
+ destStartReplace = destStartMatch;
+ }
+ }
+
+ if (!copyCharacters(match.startReplace, match.endReplace, table, displayTable,
+ *input, output, posMapping, transOpcode, cursorPosition,
+ cursorStatus, mode))
+ return 0;
+ newPos = match.endMatch;
+ passIC++;
+ break;
+ default:
+ if (_lou_handlePassVariableAction(passInstructions, &passIC)) break;
+ return 0;
+ }
+ *pos = newPos;
+ return 1;
+}
+
+static void
+passSelectRule(const TranslationTableHeader *table, int pos, int currentPass,
+ const InString *input, int *transOpcode, const TranslationTableRule **transRule,
+ int *transCharslen, int *passCharDots, widechar const **passInstructions,
+ int *passIC, PassRuleMatch *match, TranslationTableRule **groupingRule,
+ widechar *groupingOp) {
+ if (!findForPassRule(table, pos, currentPass, input, transOpcode, transRule,
+ transCharslen, passCharDots, passInstructions, passIC, match,
+ groupingRule, groupingOp)) {
+ *transOpcode = CTO_Always;
+ }
+}
+
+static int
+translatePass(const TranslationTableHeader *table, const DisplayTableHeader *displayTable,
+ int currentPass, const InString *input, OutString *output, int *posMapping,
+ int *realInlen, int *cursorPosition, int *cursorStatus, int mode) {
+ int pos;
+ int transOpcode;
+ const TranslationTableRule *transRule;
+ int transCharslen;
+ int passCharDots;
+ const widechar *passInstructions;
+ int passIC; /* Instruction counter */
+ PassRuleMatch patternMatch;
+ TranslationTableRule *groupingRule;
+ widechar groupingOp;
+ const InString *origInput = input;
+ pos = output->length = 0;
+ int posIncremented = 1;
+ _lou_resetPassVariables();
+ while (pos < input->length) { /* the main multipass translation loop */
+ // check posIncremented to avoid endless loop
+ if (!posIncremented)
+ transOpcode = CTO_Always;
+ else
+ passSelectRule(table, pos, currentPass, input, &transOpcode, &transRule,
+ &transCharslen, &passCharDots, &passInstructions, &passIC,
+ &patternMatch, &groupingRule, &groupingOp);
+ posIncremented = 1;
+ switch (transOpcode) {
+ case CTO_Context:
+ case CTO_Pass2:
+ case CTO_Pass3:
+ case CTO_Pass4: {
+ const InString *inputBefore = input;
+ int posBefore = pos;
+ if (appliedRules != NULL && appliedRulesCount < maxAppliedRules)
+ appliedRules[appliedRulesCount++] = transRule;
+ if (!passDoAction(table, displayTable, &input, output, posMapping,
+ transOpcode, &transRule, passCharDots, passInstructions, passIC,
+ &pos, patternMatch, cursorPosition, cursorStatus, groupingRule,
+ groupingOp, mode))
+ goto failure;
+ if (input->bufferIndex != inputBefore->bufferIndex &&
+ inputBefore->bufferIndex != origInput->bufferIndex)
+ releaseStringBuffer(inputBefore->bufferIndex);
+ if (pos == posBefore) posIncremented = 0;
+ break;
+ }
+ case CTO_Always:
+ if ((output->length + 1) > output->maxlength) goto failure;
+ posMapping[output->length] = pos;
+ output->chars[output->length++] = input->chars[pos++];
+ break;
+ default:
+ goto failure;
+ }
+ }
+failure:
+ if (pos < input->length) {
+ while (checkAttr(input->chars[pos], CTC_Space, 1, table))
+ if (++pos == input->length) break;
+ }
+ *realInlen = pos;
+ if (input->bufferIndex != origInput->bufferIndex)
+ releaseStringBuffer(input->bufferIndex);
+ return 1;
+}
+
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+static int
+translateString(const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int mode, int currentPass,
+ const InString *input, OutString *output, int *posMapping, formtype *typebuf,
+ unsigned char *srcSpacing, unsigned char *destSpacing, unsigned int *wordBuffer,
+ EmphasisInfo *emphasisBuffer, int haveEmphasis, int *realInlen,
+ int *cursorPosition, int *cursorStatus, int compbrlStart, int compbrlEnd);
+
+int EXPORT_CALL
+lou_translateString(const char *tableList, const widechar *inbufx, int *inlen,
+ widechar *outbuf, int *outlen, formtype *typeform, char *spacing, int mode) {
+ return lou_translate(tableList, inbufx, inlen, outbuf, outlen, typeform, spacing,
+ NULL, NULL, NULL, mode);
+}
+
+int EXPORT_CALL
+lou_translate(const char *tableList, const widechar *inbufx, int *inlen, widechar *outbuf,
+ int *outlen, formtype *typeform, char *spacing, int *outputPos, int *inputPos,
+ int *cursorPos, int mode) {
+ return _lou_translate(tableList, tableList, inbufx, inlen, outbuf, outlen, typeform,
+ spacing, outputPos, inputPos, cursorPos, mode, NULL, NULL);
+}
+
+int EXPORT_CALL
+_lou_translate(const char *tableList, const char *displayTableList,
+ const widechar *inbufx, int *inlen, widechar *outbuf, int *outlen,
+ formtype *typeform, char *spacing, int *outputPos, int *inputPos, int *cursorPos,
+ int mode, const TranslationTableRule **rules, int *rulesLen) {
+ // int i;
+ // for(i = 0; i < *inlen; i++)
+ // {
+ // outbuf[i] = inbufx[i];
+ // if(inputPos)
+ // inputPos[i] = i;
+ // if(outputPos)
+ // outputPos[i] = i;
+ // }
+ // *inlen = i;
+ // *outlen = i;
+ // return 1;
+ const TranslationTableHeader *table;
+ const DisplayTableHeader *displayTable;
+ InString input;
+ OutString output;
+ // posMapping contains position mapping info between the initial input and the output
+ // of the current pass. It is 1 longer than the output. The values are monotonically
+ // increasing and can range between -1 and the input length. At the end the position
+ // info is passed to the user as an inputPos and outputPos array. inputPos has the
+ // length of the final output and has values ranging from 0 to inlen-1. outputPos has
+ // the length of the initial input and has values ranging from 0 to outlen-1.
+ int *posMapping;
+ int *posMapping1;
+ int *posMapping2;
+ int *posMapping3;
+ formtype *typebuf;
+ unsigned char *srcSpacing;
+ unsigned char *destSpacing;
+ unsigned int *wordBuffer;
+ EmphasisInfo *emphasisBuffer;
+ int cursorPosition;
+ int cursorStatus;
+ int haveEmphasis;
+ int compbrlStart = -1;
+ int compbrlEnd = -1;
+ int k;
+ int goodTrans = 1;
+ if (tableList == NULL || inbufx == NULL || inlen == NULL || outbuf == NULL ||
+ outlen == NULL)
+ return 0;
+ _lou_logMessage(LOU_LOG_ALL, "Performing translation: tableList=%s, inlen=%d",
+ tableList, *inlen);
+ _lou_logWidecharBuf(LOU_LOG_ALL, "Inbuf=", inbufx, *inlen);
+
+ if (!_lou_isValidMode(mode))
+ _lou_logMessage(LOU_LOG_ERROR, "Invalid mode parameter: %d", mode);
+
+ if (displayTableList == NULL) displayTableList = tableList;
+ _lou_getTable(tableList, displayTableList, &table, &displayTable);
+ if (table == NULL || *inlen < 0 || *outlen < 0) return 0;
+ k = 0;
+ while (k < *inlen && inbufx[k]) k++;
+ input = (InString){ .chars = inbufx, .length = k, .bufferIndex = -1 };
+ haveEmphasis = 0;
+ if (!(typebuf = _lou_allocMem(alloc_typebuf, 0, input.length, *outlen))) return 0;
+ if (typeform != NULL) {
+ for (k = 0; k < input.length; k++) {
+ typebuf[k] = typeform[k];
+ if (typebuf[k] & EMPHASIS) haveEmphasis = 1;
+ }
+ } else
+ memset(typebuf, 0, input.length * sizeof(formtype));
+
+ if ((wordBuffer = _lou_allocMem(alloc_wordBuffer, 0, input.length, *outlen)))
+ memset(wordBuffer, 0, (input.length + 4) * sizeof(unsigned int));
+ else
+ return 0;
+ if ((emphasisBuffer = _lou_allocMem(alloc_emphasisBuffer, 0, input.length, *outlen)))
+ memset(emphasisBuffer, 0, (input.length + 4) * sizeof(EmphasisInfo));
+ else
+ return 0;
+
+ if (!(spacing == NULL || *spacing == 'X'))
+ srcSpacing = (unsigned char *)spacing;
+ else
+ srcSpacing = NULL;
+ if (outputPos != NULL)
+ for (k = 0; k < input.length; k++) outputPos[k] = -1;
+ if (cursorPos != NULL && *cursorPos >= 0) {
+ cursorStatus = 0;
+ cursorPosition = *cursorPos;
+ if ((mode & (compbrlAtCursor | compbrlLeftCursor))) {
+ compbrlStart = cursorPosition;
+ if (checkAttr(input.chars[compbrlStart], CTC_Space, 0, table))
+ compbrlEnd = compbrlStart + 1;
+ else {
+ while (compbrlStart >= 0 &&
+ !checkAttr(input.chars[compbrlStart], CTC_Space, 0, table))
+ compbrlStart--;
+ compbrlStart++;
+ compbrlEnd = cursorPosition;
+ if (!(mode & compbrlLeftCursor))
+ while (compbrlEnd < input.length &&
+ !checkAttr(input.chars[compbrlEnd], CTC_Space, 0, table))
+ compbrlEnd++;
+ }
+ }
+ } else {
+ cursorPosition = -1;
+ cursorStatus = 1; /* so it won't check cursor position */
+ }
+ if (!(posMapping1 = _lou_allocMem(alloc_posMapping1, 0, input.length, *outlen)))
+ return 0;
+ if (table->numPasses > 1 || table->corrections) {
+ if (!(posMapping2 = _lou_allocMem(alloc_posMapping2, 0, input.length, *outlen)))
+ return 0;
+ if (!(posMapping3 = _lou_allocMem(alloc_posMapping3, 0, input.length, *outlen)))
+ return 0;
+ }
+ if (srcSpacing != NULL) {
+ if (!(destSpacing = _lou_allocMem(alloc_destSpacing, 0, input.length, *outlen)))
+ goodTrans = 0;
+ else
+ memset(destSpacing, '*', *outlen);
+ } else
+ destSpacing = NULL;
+ appliedRulesCount = 0;
+ if (rules != NULL && rulesLen != NULL) {
+ appliedRules = rules;
+ maxAppliedRules = *rulesLen;
+ } else {
+ appliedRules = NULL;
+ maxAppliedRules = 0;
+ }
+ {
+ int idx;
+ if (!stringBufferPool) initStringBufferPool();
+ for (idx = 0; idx < stringBufferPool->size; idx++) releaseStringBuffer(idx);
+ idx = getStringBuffer(*outlen);
+ output = (OutString){ .chars = stringBufferPool->buffers[idx],
+ .maxlength = *outlen,
+ .length = 0,
+ .bufferIndex = idx };
+ }
+ posMapping = posMapping1;
+
+ int currentPass = table->corrections ? 0 : 1;
+ int *passPosMapping = posMapping;
+ while (1) {
+ int realInlen;
+ switch (currentPass) {
+ case 0:
+ goodTrans =
+ makeCorrections(table, displayTable, &input, &output, passPosMapping,
+ typebuf, &realInlen, &cursorPosition, &cursorStatus, mode);
+ break;
+ case 1: {
+ goodTrans = translateString(table, displayTable, mode, currentPass, &input,
+ &output, passPosMapping, typebuf, srcSpacing, destSpacing, wordBuffer,
+ emphasisBuffer, haveEmphasis, &realInlen, &cursorPosition,
+ &cursorStatus, compbrlStart, compbrlEnd);
+ break;
+ }
+ default:
+ goodTrans = translatePass(table, displayTable, currentPass, &input, &output,
+ passPosMapping, &realInlen, &cursorPosition, &cursorStatus, mode);
+ break;
+ }
+ passPosMapping[output.length] = realInlen;
+ if (passPosMapping == posMapping) {
+ passPosMapping = posMapping2;
+ } else {
+ int *prevPosMapping = posMapping3;
+ memcpy((int *)prevPosMapping, posMapping, (*outlen + 1) * sizeof(int));
+ for (k = 0; k <= output.length; k++)
+ if (passPosMapping[k] < 0)
+ posMapping[k] = prevPosMapping[0];
+ else
+ posMapping[k] = prevPosMapping[passPosMapping[k]];
+ }
+ currentPass++;
+ if (currentPass <= table->numPasses && goodTrans) {
+ int idx;
+ releaseStringBuffer(input.bufferIndex);
+ input = (InString){ .chars = output.chars,
+ .length = output.length,
+ .bufferIndex = output.bufferIndex };
+ idx = getStringBuffer(*outlen);
+ output = (OutString){ .chars = stringBufferPool->buffers[idx],
+ .maxlength = *outlen,
+ .length = 0,
+ .bufferIndex = idx };
+ continue;
+ }
+ break;
+ }
+ if (goodTrans) {
+ for (k = 0; k < output.length; k++) {
+ if (typeform != NULL) {
+ if ((output.chars[k] & (LOU_DOT_7 | LOU_DOT_8)))
+ typeform[k] = '8';
+ else
+ typeform[k] = '0';
+ }
+ if ((mode & dotsIO)) {
+ if ((mode & ucBrl))
+ outbuf[k] = ((output.chars[k] & 0xff) | LOU_ROW_BRAILLE);
+ else
+ outbuf[k] = output.chars[k];
+ } else {
+ outbuf[k] = _lou_getCharFromDots(output.chars[k], displayTable);
+ if (!outbuf[k]) {
+ // assume that if NUL character is returned, it's because the display
+ // table has no mapping for the dot pattern (not because it maps to
+ // NUL)
+ _lou_logMessage(LOU_LOG_ERROR,
+ "%s: no mapping for dot pattern %s in display table",
+ displayTableList, _lou_showDots(&output.chars[k], 1));
+ return 0;
+ }
+ }
+ }
+ *inlen = posMapping[output.length];
+ *outlen = output.length;
+ // Compute inputPos and outputPos from posMapping. The value at the last index of
+ // posMapping is currectly not used.
+ if (inputPos != NULL) {
+ for (k = 0; k < *outlen; k++)
+ if (posMapping[k] < 0)
+ inputPos[k] = 0;
+ else if (posMapping[k] > *inlen - 1)
+ inputPos[k] = *inlen - 1;
+ else
+ inputPos[k] = posMapping[k];
+ }
+ if (outputPos != NULL) {
+ int inpos = -1;
+ int outpos = -1;
+ for (k = 0; k < *outlen; k++)
+ if (posMapping[k] > inpos) {
+ while (inpos < posMapping[k]) {
+ if (inpos >= 0 && inpos < *inlen)
+ outputPos[inpos] = outpos < 0 ? 0 : outpos;
+ inpos++;
+ }
+ outpos = k;
+ }
+ if (inpos < 0) inpos = 0;
+ while (inpos < *inlen) outputPos[inpos++] = outpos;
+ }
+ }
+ if (destSpacing != NULL) {
+ memcpy(srcSpacing, destSpacing, input.length);
+ srcSpacing[input.length] = 0;
+ }
+ if (cursorPos != NULL && *cursorPos != -1) {
+ if (outputPos != NULL)
+ *cursorPos = outputPos[*cursorPos];
+ else
+ *cursorPos = cursorPosition;
+ }
+ if (rulesLen != NULL) *rulesLen = appliedRulesCount;
+ _lou_logMessage(LOU_LOG_ALL, "Translation complete: outlen=%d", *outlen);
+ _lou_logWidecharBuf(LOU_LOG_ALL, "Outbuf=", (const widechar *)outbuf, *outlen);
+
+ return goodTrans;
+}
+
+int EXPORT_CALL
+lou_translatePrehyphenated(const char *tableList, const widechar *inbufx, int *inlen,
+ widechar *outbuf, int *outlen, formtype *typeform, char *spacing, int *outputPos,
+ int *inputPos, int *cursorPos, char *inputHyphens, char *outputHyphens,
+ int mode) {
+ int rv = 1;
+ int *alloc_inputPos = NULL;
+ if (inputHyphens != NULL) {
+ if (outputHyphens == NULL) return 0;
+ if (inputPos == NULL) {
+ if ((alloc_inputPos = malloc(*outlen * sizeof(int))) == NULL)
+ _lou_outOfMemory();
+ inputPos = alloc_inputPos;
+ }
+ }
+ if (lou_translate(tableList, inbufx, inlen, outbuf, outlen, typeform, spacing,
+ outputPos, inputPos, cursorPos, mode)) {
+ if (inputHyphens != NULL) {
+ int inpos = 0;
+ int outpos;
+ for (outpos = 0; outpos < *outlen; outpos++) {
+ int new_inpos = inputPos[outpos];
+ if (new_inpos < inpos) {
+ rv = 0;
+ break;
+ }
+ if (new_inpos > inpos)
+ outputHyphens[outpos] = inputHyphens[new_inpos];
+ else
+ outputHyphens[outpos] = '0';
+ inpos = new_inpos;
+ }
+ }
+ }
+ if (alloc_inputPos != NULL) free(alloc_inputPos);
+ return rv;
+}
+
+static int
+hyphenateWord(const widechar *word, int wordSize, char *hyphens,
+ const TranslationTableHeader *table) {
+ widechar *prepWord;
+ int i, k, limit;
+ int stateNum;
+ widechar ch;
+ HyphenationState *statesArray =
+ (HyphenationState *)&table->ruleArea[table->hyphenStatesArray];
+ HyphenationState *currentState;
+ HyphenationTrans *transitionsArray;
+ char *hyphenPattern;
+ int patternOffset;
+ if (!table->hyphenStatesArray || (wordSize + 3) > MAXSTRING) return 0;
+ prepWord = (widechar *)calloc(wordSize + 3, sizeof(widechar));
+ /* prepWord is of the format ".hello."
+ * hyphens is the length of the word "hello" "00000" */
+ prepWord[0] = '.';
+ for (i = 0; i < wordSize; i++) {
+ prepWord[i + 1] = (findCharOrDots(word[i], 0, table))->lowercase;
+ hyphens[i] = '0';
+ }
+ prepWord[wordSize + 1] = '.';
+
+ /* now, run the finite state machine */
+ stateNum = 0;
+
+ // we need to walk all of ".hello."
+ for (i = 0; i < wordSize + 2; i++) {
+ ch = prepWord[i];
+ while (1) {
+ if (stateNum == 0xffff) {
+ stateNum = 0;
+ goto nextLetter;
+ }
+ currentState = &statesArray[stateNum];
+ if (currentState->trans.offset) {
+ transitionsArray =
+ (HyphenationTrans *)&table->ruleArea[currentState->trans.offset];
+ for (k = 0; k < currentState->numTrans; k++) {
+ if (transitionsArray[k].ch == ch) {
+ stateNum = transitionsArray[k].newState;
+ goto stateFound;
+ }
+ }
+ }
+ stateNum = currentState->fallbackState;
+ }
+ stateFound:
+ currentState = &statesArray[stateNum];
+ if (currentState->hyphenPattern) {
+ hyphenPattern = (char *)&table->ruleArea[currentState->hyphenPattern];
+ patternOffset = i + 1 - (int)strlen(hyphenPattern);
+
+ /* Need to ensure that we don't overrun hyphens,
+ * in some cases hyphenPattern is longer than the remaining letters,
+ * and if we write out all of it we would have overshot our buffer. */
+ limit = MIN((int)strlen(hyphenPattern), wordSize - patternOffset);
+ for (k = 0; k < limit; k++) {
+ if (hyphens[patternOffset + k] < hyphenPattern[k])
+ hyphens[patternOffset + k] = hyphenPattern[k];
+ }
+ }
+ nextLetter:;
+ }
+ hyphens[wordSize] = 0;
+ free(prepWord);
+ return 1;
+}
+
+static int
+doCompTrans(int start, int end, const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int *pos, const InString *input,
+ OutString *output, int *posMapping, EmphasisInfo *emphasisBuffer,
+ const TranslationTableRule **transRule, int *cursorPosition, int *cursorStatus,
+ int mode);
+
+static int
+for_updatePositions(const widechar *outChars, int inLength, int outLength, int shift,
+ int pos, const InString *input, OutString *output, int *posMapping,
+ int *cursorPosition, int *cursorStatus) {
+ int k;
+ if ((output->length + outLength) > output->maxlength ||
+ (pos + inLength) > input->length)
+ return 0;
+ memcpy(&output->chars[output->length], outChars, outLength * CHARSIZE);
+ if (!*cursorStatus) {
+ if (*cursorPosition >= pos && *cursorPosition < (pos + inLength)) {
+ *cursorPosition = output->length;
+ *cursorStatus = 1;
+ } else if (input->chars[*cursorPosition] == 0 &&
+ *cursorPosition == (pos + inLength)) {
+ *cursorPosition = output->length + outLength / 2 + 1;
+ *cursorStatus = 1;
+ }
+ } else if (*cursorStatus == 2 && *cursorPosition == pos)
+ *cursorPosition = output->length;
+ for (k = 0; k < outLength; k++) posMapping[output->length + k] = pos + shift;
+ output->length += outLength;
+ return 1;
+}
+
+static int
+syllableBreak(const TranslationTableHeader *table, int pos, const InString *input,
+ int transCharslen) {
+ int wordStart = 0;
+ int wordEnd = 0;
+ int wordSize = 0;
+ int k = 0;
+ char *hyphens = NULL;
+ for (wordStart = pos; wordStart >= 0; wordStart--)
+ if (!((findCharOrDots(input->chars[wordStart], 0, table))->attributes &
+ CTC_Letter)) {
+ wordStart++;
+ break;
+ }
+ if (wordStart < 0) wordStart = 0;
+ for (wordEnd = pos; wordEnd < input->length; wordEnd++)
+ if (!((findCharOrDots(input->chars[wordEnd], 0, table))->attributes &
+ CTC_Letter)) {
+ wordEnd--;
+ break;
+ }
+ if (wordEnd == input->length) wordEnd--;
+ /* At this stage wordStart is the 0 based index of the first letter in the word,
+ * wordEnd is the 0 based index of the last letter in the word.
+ * example: "hello" wordstart=0, wordEnd=4. */
+ wordSize = wordEnd - wordStart + 1;
+ hyphens = (char *)calloc(wordSize + 1, sizeof(char));
+ if (!hyphenateWord(&input->chars[wordStart], wordSize, hyphens, table)) {
+ free(hyphens);
+ return 0;
+ }
+ for (k = pos - wordStart + 1; k < (pos - wordStart + transCharslen); k++)
+ if (hyphens[k] & 1) {
+ free(hyphens);
+ return 1;
+ }
+ free(hyphens);
+ return 0;
+}
+
+static void
+setBefore(const TranslationTableHeader *table, int pos, const InString *input,
+ TranslationTableCharacterAttributes *beforeAttributes) {
+ widechar before;
+ if (pos >= 2 && input->chars[pos - 1] == LOU_ENDSEGMENT)
+ before = input->chars[pos - 2];
+ else
+ before = (pos == 0) ? ' ' : input->chars[pos - 1];
+ *beforeAttributes = (findCharOrDots(before, 0, table))->attributes;
+}
+
+static void
+setAfter(int length, const TranslationTableHeader *table, int pos, const InString *input,
+ TranslationTableCharacterAttributes *afterAttributes) {
+ widechar after;
+ if ((pos + length + 2) < input->length && input->chars[pos + 1] == LOU_ENDSEGMENT)
+ after = input->chars[pos + 2];
+ else
+ after = (pos + length < input->length) ? input->chars[pos + length] : ' ';
+ *afterAttributes = (findCharOrDots(after, 0, table))->attributes;
+}
+
+static int
+brailleIndicatorDefined(TranslationTableOffset offset,
+ const TranslationTableHeader *table, const TranslationTableRule **indicRule) {
+ if (!offset) return 0;
+ *indicRule = (TranslationTableRule *)&table->ruleArea[offset];
+ return 1;
+}
+
+static int
+capsletterDefined(const TranslationTableHeader *table) {
+ return table->emphRules[capsRule][letterOffset];
+}
+
+static int
+validMatch(const TranslationTableHeader *table, int pos, const InString *input,
+ formtype *typebuf, const TranslationTableRule *transRule, int transCharslen) {
+ /* Analyze the typeform parameter and also check for capitalization */
+ TranslationTableCharacter *inputChar;
+ TranslationTableCharacter *ruleChar;
+ TranslationTableCharacterAttributes prevAttr = 0;
+ int k;
+ int kk = 0;
+ if (!transCharslen) return 0;
+ for (k = pos; k < pos + transCharslen; k++) {
+ if (input->chars[k] == LOU_ENDSEGMENT) {
+ if (k == pos && transCharslen == 1)
+ return 1;
+ else
+ return 0;
+ }
+ inputChar = findCharOrDots(input->chars[k], 0, table);
+ if (k == pos) prevAttr = inputChar->attributes;
+ ruleChar = findCharOrDots(transRule->charsdots[kk++], 0, table);
+ if ((inputChar->lowercase != ruleChar->lowercase)) return 0;
+ if (typebuf != NULL && (typebuf[pos] & CAPSEMPH) == 0 &&
+ (typebuf[k] | typebuf[pos]) != typebuf[pos])
+ return 0;
+ if (inputChar->attributes != CTC_Letter) {
+ if (k != (pos + 1) && (prevAttr & CTC_Letter) &&
+ (inputChar->attributes & CTC_Letter) &&
+ ((inputChar->attributes &
+ (CTC_LowerCase | CTC_UpperCase | CTC_Letter)) !=
+ (prevAttr & (CTC_LowerCase | CTC_UpperCase | CTC_Letter))))
+ return 0;
+ }
+ prevAttr = inputChar->attributes;
+ }
+ return 1;
+}
+
+static int
+insertBrailleIndicators(int finish, const TranslationTableHeader *table, int pos,
+ const InString *input, OutString *output, int *posMapping, formtype *typebuf,
+ int haveEmphasis, int transOpcode, int prevTransOpcode, int *cursorPosition,
+ int *cursorStatus, TranslationTableCharacterAttributes beforeAttributes,
+ int *prevType, int *curType, int *prevTypeform, int prevPos) {
+ /* Insert braille indicators such as letter, number, etc. */
+ typedef enum {
+ checkNothing,
+ checkBeginTypeform,
+ checkEndTypeform,
+ checkNumber,
+ checkLetter
+ } checkThis;
+ checkThis checkWhat = checkNothing;
+ int ok = 0;
+ int k;
+ {
+ if (pos == prevPos && !finish) return 1;
+ if (pos != prevPos) {
+ if (haveEmphasis && (typebuf[pos] & EMPHASIS) != *prevTypeform) {
+ *prevType = *prevTypeform & EMPHASIS;
+ *curType = typebuf[pos] & EMPHASIS;
+ checkWhat = checkEndTypeform;
+ } else if (!finish)
+ checkWhat = checkNothing;
+ else
+ checkWhat = checkNumber;
+ }
+ if (finish == 1) checkWhat = checkNumber;
+ }
+ do {
+ const TranslationTableRule *indicRule;
+ ok = 0;
+ switch (checkWhat) {
+ case checkNothing:
+ ok = 0;
+ break;
+ case checkBeginTypeform:
+ if (haveEmphasis) {
+ ok = 0;
+ *curType = 0;
+ }
+ if (*curType == plain_text) {
+ if (!finish)
+ checkWhat = checkNothing;
+ else
+ checkWhat = checkNumber;
+ }
+ break;
+ case checkEndTypeform:
+ if (haveEmphasis) {
+ ok = 0;
+ *prevType = plain_text;
+ }
+ if (*prevType == plain_text) {
+ checkWhat = checkBeginTypeform;
+ *prevTypeform = typebuf[pos] & EMPHASIS;
+ }
+ break;
+ case checkNumber:
+ if (brailleIndicatorDefined(table->numberSign, table, &indicRule) &&
+ checkAttr_safe(input, pos, CTC_Digit, 0, table) &&
+ (prevTransOpcode == CTO_ExactDots ||
+ !(beforeAttributes & CTC_Digit)) &&
+ prevTransOpcode != CTO_MidNum) {
+ ok = !table->usesNumericMode;
+ checkWhat = checkNothing;
+ } else
+ checkWhat = checkLetter;
+ break;
+ case checkLetter:
+ if (!brailleIndicatorDefined(table->letterSign, table, &indicRule)) {
+ ok = 0;
+ checkWhat = checkNothing;
+ break;
+ }
+ if (transOpcode == CTO_Contraction) {
+ ok = 1;
+ checkWhat = checkNothing;
+ break;
+ }
+ if ((checkAttr_safe(input, pos, CTC_Letter, 0, table) &&
+ !(beforeAttributes & CTC_Letter)) &&
+ (!checkAttr_safe(input, pos + 1, CTC_Letter, 0, table) ||
+ (beforeAttributes & CTC_Digit))) {
+ ok = 1;
+ if (pos > 0)
+ for (k = 0; k < table->noLetsignBeforeCount; k++)
+ if (input->chars[pos - 1] == table->noLetsignBefore[k]) {
+ ok = 0;
+ break;
+ }
+ for (k = 0; k < table->noLetsignCount; k++)
+ if (input->chars[pos] == table->noLetsign[k]) {
+ ok = 0;
+ break;
+ }
+ if (pos + 1 < input->length)
+ for (k = 0; k < table->noLetsignAfterCount; k++)
+ if (input->chars[pos + 1] == table->noLetsignAfter[k]) {
+ ok = 0;
+ break;
+ }
+ }
+ checkWhat = checkNothing;
+ break;
+
+ default:
+ ok = 0;
+ checkWhat = checkNothing;
+ break;
+ }
+ if (ok && indicRule != NULL) {
+ if (!for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen, 0,
+ pos, input, output, posMapping, cursorPosition, cursorStatus))
+ return 0;
+ }
+ } while (checkWhat != checkNothing);
+ return 1;
+}
+
+static int
+onlyLettersBehind(const TranslationTableHeader *table, int pos, const InString *input,
+ TranslationTableCharacterAttributes beforeAttributes) {
+ /* Actually, spaces, then letters */
+ int k;
+ if (!(beforeAttributes & CTC_Space)) return 0;
+ for (k = pos - 2; k >= 0; k--) {
+ TranslationTableCharacterAttributes attr =
+ (findCharOrDots(input->chars[k], 0, table))->attributes;
+ if ((attr & CTC_Space)) continue;
+ if ((attr & CTC_Letter))
+ return 1;
+ else
+ return 0;
+ }
+ return 1;
+}
+
+static int
+onlyLettersAhead(const TranslationTableHeader *table, int pos, const InString *input,
+ int transCharslen, TranslationTableCharacterAttributes afterAttributes) {
+ /* Actullly, spaces, then letters */
+ int k;
+ if (!(afterAttributes & CTC_Space)) return 0;
+ for (k = pos + transCharslen + 1; k < input->length; k++) {
+ TranslationTableCharacterAttributes attr =
+ (findCharOrDots(input->chars[k], 0, table))->attributes;
+ if ((attr & CTC_Space)) continue;
+ if ((attr & (CTC_Letter | CTC_LitDigit)))
+ return 1;
+ else
+ return 0;
+ }
+ return 0;
+}
+
+static int
+noCompbrlAhead(const TranslationTableHeader *table, int pos, int mode,
+ const InString *input, int transOpcode, int transCharslen, int cursorPosition) {
+ int start = pos + transCharslen;
+ int end;
+ int p;
+ if (start >= input->length) return 1;
+ while (start < input->length && checkAttr(input->chars[start], CTC_Space, 0, table))
+ start++;
+ if (start == input->length ||
+ (transOpcode == CTO_JoinableWord &&
+ (!checkAttr(input->chars[start], CTC_Letter | CTC_Digit, 0, table) ||
+ !checkAttr(input->chars[start - 1], CTC_Space, 0, table))))
+ return 1;
+ end = start;
+ while (end < input->length && !checkAttr(input->chars[end], CTC_Space, 0, table))
+ end++;
+ if ((mode & (compbrlAtCursor | compbrlLeftCursor)) && cursorPosition >= start &&
+ cursorPosition < end)
+ return 0;
+ /* Look ahead for rules with CTO_CompBrl */
+ for (p = start; p < end; p++) {
+ int length = input->length - p;
+ int tryThis;
+ int k;
+ for (tryThis = 0; tryThis < 2; tryThis++) {
+ TranslationTableOffset ruleOffset = 0;
+ TranslationTableRule *testRule;
+ switch (tryThis) {
+ case 0:
+ if (!(length >= 2)) break;
+ ruleOffset = table->forRules[_lou_stringHash(&input->chars[p], 1, table)];
+ break;
+ case 1:
+ if (!(length >= 1)) break;
+ length = 1;
+ ruleOffset = findCharOrDots(input->chars[p], 0, table)->otherRules;
+ break;
+ }
+ while (ruleOffset) {
+ const TranslationTableCharacter *character1;
+ const TranslationTableCharacter *character2;
+ testRule = (TranslationTableRule *)&table->ruleArea[ruleOffset];
+ for (k = 0; k < testRule->charslen; k++) {
+ character1 = findCharOrDots(testRule->charsdots[k], 0, table);
+ character2 = findCharOrDots(input->chars[p + k], 0, table);
+ if (character1->lowercase != character2->lowercase) break;
+ }
+ if (tryThis == 1 || k == testRule->charslen) {
+ if (testRule->opcode == CTO_CompBrl ||
+ testRule->opcode == CTO_Literal)
+ return 0;
+ }
+ ruleOffset = testRule->charsnext;
+ }
+ }
+ }
+ return 1;
+}
+
+static int
+isRepeatedWord(const TranslationTableHeader *table, int pos, const InString *input,
+ int transCharslen, const widechar **repwordStart, int *repwordLength) {
+ int start;
+ if (pos == 0 || !checkAttr(input->chars[pos - 1], CTC_Letter, 0, table)) return 0;
+ if ((pos + transCharslen) >= input->length ||
+ !checkAttr(input->chars[pos + transCharslen], CTC_Letter, 0, table))
+ return 0;
+ for (start = pos - 2;
+ start >= 0 && checkAttr(input->chars[start], CTC_Letter, 0, table); start--)
+ ;
+ start++;
+ *repwordStart = &input->chars[start];
+ *repwordLength = pos - start;
+ if (compareChars(*repwordStart, &input->chars[pos + transCharslen], *repwordLength, 0,
+ table))
+ return 1;
+ return 0;
+}
+
+static int
+checkEmphasisChange(const int skip, int pos, EmphasisInfo *emphasisBuffer,
+ const TranslationTableRule *transRule) {
+ int i;
+ for (i = pos + (skip + 1); i < pos + transRule->charslen; i++)
+ if (emphasisBuffer[i].begin || emphasisBuffer[i].end || emphasisBuffer[i].word ||
+ emphasisBuffer[i].symbol)
+ return 1;
+ return 0;
+}
+
+static int
+inSequence(const TranslationTableHeader *table, int pos, const InString *input,
+ const TranslationTableRule *transRule) {
+ int i, j, s, match;
+ // TODO: all caps words
+ // const TranslationTableCharacter *c = NULL;
+
+ /* check before sequence */
+ for (i = pos - 1; i >= 0; i--) {
+ if (checkAttr(input->chars[i], CTC_SeqBefore, 0, table)) continue;
+ if (!(checkAttr(input->chars[i], CTC_Space | CTC_SeqDelimiter, 0, table)))
+ return 0;
+ break;
+ }
+
+ /* check after sequence */
+ for (i = pos + transRule->charslen; i < input->length; i++) {
+ /* check sequence after patterns */
+ if (table->seqPatternsCount) {
+ match = 0;
+ for (j = i, s = 0; j <= input->length && s < table->seqPatternsCount;
+ j++, s++) {
+ /* matching */
+ if (match == 1) {
+ if (table->seqPatterns[s]) {
+ if (input->chars[j] == table->seqPatterns[s])
+ match = 1;
+ else {
+ match = -1;
+ j = i - 1;
+ }
+ }
+
+ /* found match */
+ else {
+ /* pattern at end of input */
+ if (j >= input->length) return 1;
+
+ i = j;
+ break;
+ }
+ }
+
+ /* looking for match */
+ else if (match == 0) {
+ if (table->seqPatterns[s]) {
+ if (input->chars[j] == table->seqPatterns[s])
+ match = 1;
+ else {
+ match = -1;
+ j = i - 1;
+ }
+ }
+ }
+
+ /* next pattarn */
+ else if (match == -1) {
+ if (!table->seqPatterns[s]) {
+ match = 0;
+ j = i - 1;
+ }
+ }
+ }
+ }
+
+ if (checkAttr(input->chars[i], CTC_SeqAfter, 0, table)) continue;
+ if (!(checkAttr(input->chars[i], CTC_Space | CTC_SeqDelimiter, 0, table)))
+ return 0;
+ break;
+ }
+
+ return 1;
+}
+
+static void
+for_selectRule(const TranslationTableHeader *table, int pos, OutString output, int mode,
+ const InString *input, formtype *typebuf, EmphasisInfo *emphasisBuffer,
+ int *transOpcode, int prevTransOpcode, const TranslationTableRule **transRule,
+ int *transCharslen, int *passCharDots, widechar const **passInstructions,
+ int *passIC, PassRuleMatch *patternMatch, int posIncremented, int cursorPosition,
+ const widechar **repwordStart, int *repwordLength, int dontContract,
+ int compbrlStart, int compbrlEnd,
+ TranslationTableCharacterAttributes beforeAttributes,
+ TranslationTableCharacter **curCharDef, TranslationTableRule **groupingRule,
+ widechar *groupingOp) {
+ /* check for valid Translations. Return value is in transRule. */
+ static TranslationTableRule pseudoRule = { 0 };
+ int length = ((pos < compbrlStart) ? compbrlStart : input->length) - pos;
+ int tryThis;
+ int k;
+ TranslationTableOffset ruleOffset = 0;
+ *curCharDef = findCharOrDots(input->chars[pos], 0, table);
+ for (tryThis = 0; tryThis < 3; tryThis++) {
+ switch (tryThis) {
+ case 0:
+ if (!(length >= 2)) break;
+ ruleOffset = table->forRules[_lou_stringHash(&input->chars[pos], 1, table)];
+ break;
+ case 1:
+ if (!(length >= 1)) break;
+ length = 1;
+ ruleOffset = (*curCharDef)->otherRules;
+ break;
+ case 2: /* No rule found */
+ *transRule = &pseudoRule;
+ *transOpcode = pseudoRule.opcode = CTO_None;
+ *transCharslen = pseudoRule.charslen = 1;
+ pseudoRule.charsdots[0] = input->chars[pos];
+ pseudoRule.dotslen = 0;
+ return;
+ break;
+ }
+ while (ruleOffset) {
+ *transRule = (TranslationTableRule *)&table->ruleArea[ruleOffset];
+ *transOpcode = (*transRule)->opcode;
+ *transCharslen = (*transRule)->charslen;
+ if (tryThis == 1 ||
+ ((*transCharslen <= length) &&
+ validMatch(table, pos, input, typebuf, *transRule,
+ *transCharslen))) {
+ TranslationTableCharacterAttributes afterAttributes;
+ /* check before emphasis match */
+ if ((*transRule)->before & CTC_EmpMatch) {
+ if (emphasisBuffer[pos].begin || emphasisBuffer[pos].end ||
+ emphasisBuffer[pos].word || emphasisBuffer[pos].symbol)
+ break;
+ }
+
+ /* check after emphasis match */
+ if ((*transRule)->after & CTC_EmpMatch) {
+ if (emphasisBuffer[pos + *transCharslen].begin ||
+ emphasisBuffer[pos + *transCharslen].end ||
+ emphasisBuffer[pos + *transCharslen].word ||
+ emphasisBuffer[pos + *transCharslen].symbol)
+ break;
+ }
+
+ /* check this rule */
+ setAfter(*transCharslen, table, pos, input, &afterAttributes);
+ if ((!((*transRule)->after & ~CTC_EmpMatch) ||
+ (beforeAttributes & (*transRule)->after)) &&
+ (!((*transRule)->before & ~CTC_EmpMatch) ||
+ (afterAttributes & (*transRule)->before)))
+ switch (*transOpcode) { /* check validity of this Translation */
+ case CTO_Space:
+ case CTO_Letter:
+ case CTO_UpperCase:
+ case CTO_LowerCase:
+ case CTO_Digit:
+ case CTO_LitDigit:
+ case CTO_Punctuation:
+ case CTO_Math:
+ case CTO_Sign:
+ case CTO_Hyphen:
+ case CTO_Replace:
+ case CTO_CompBrl:
+ case CTO_Literal:
+ return;
+ case CTO_Repeated:
+ if (dontContract || (mode & noContractions)) break;
+ if ((mode & (compbrlAtCursor | compbrlLeftCursor)) &&
+ pos >= compbrlStart && pos <= compbrlEnd)
+ break;
+ return;
+ case CTO_RepWord:
+ if (dontContract || (mode & noContractions)) break;
+ if (isRepeatedWord(table, pos, input, *transCharslen,
+ repwordStart, repwordLength))
+ return;
+ break;
+ case CTO_NoCont:
+ if (dontContract || (mode & noContractions)) break;
+ return;
+ case CTO_Syllable:
+ *transOpcode = CTO_Always;
+ case CTO_Always:
+ if (checkEmphasisChange(0, pos, emphasisBuffer, *transRule))
+ break;
+ if (dontContract || (mode & noContractions)) break;
+ return;
+ case CTO_ExactDots:
+ return;
+ case CTO_NoCross:
+ if (dontContract || (mode & noContractions)) break;
+ if (syllableBreak(table, pos, input, *transCharslen)) break;
+ return;
+ case CTO_Context:
+ // check posIncremented to avoid endless loop
+ if (!posIncremented ||
+ !passDoTest(table, pos, input, *transOpcode, *transRule,
+ passCharDots, passInstructions, passIC,
+ patternMatch, groupingRule, groupingOp))
+ break;
+ return;
+ case CTO_LargeSign:
+ if (dontContract || (mode & noContractions)) break;
+ if (!((beforeAttributes & (CTC_Space | CTC_Punctuation)) ||
+ onlyLettersBehind(
+ table, pos, input, beforeAttributes)) ||
+ !((afterAttributes & CTC_Space) ||
+ prevTransOpcode == CTO_LargeSign) ||
+ (afterAttributes & CTC_Letter) ||
+ !noCompbrlAhead(table, pos, mode, input, *transOpcode,
+ *transCharslen, cursorPosition))
+ *transOpcode = CTO_Always;
+ return;
+ case CTO_WholeWord:
+ if (dontContract || (mode & noContractions)) break;
+ if (checkEmphasisChange(0, pos, emphasisBuffer, *transRule))
+ break;
+ case CTO_Contraction:
+ if (table->usesSequences) {
+ if (inSequence(table, pos, input, *transRule)) return;
+ } else {
+ if ((beforeAttributes & (CTC_Space | CTC_Punctuation)) &&
+ (afterAttributes & (CTC_Space | CTC_Punctuation)))
+ return;
+ }
+ break;
+ case CTO_PartWord:
+ if (dontContract || (mode & noContractions)) break;
+ if ((beforeAttributes & CTC_Letter) ||
+ (afterAttributes & CTC_Letter))
+ return;
+ break;
+ case CTO_JoinNum:
+ if (dontContract || (mode & noContractions)) break;
+ if ((beforeAttributes & (CTC_Space | CTC_Punctuation)) &&
+ (afterAttributes & CTC_Space) &&
+ (output.length + (*transRule)->dotslen <
+ output.maxlength)) {
+ int p = pos + *transCharslen + 1;
+ while (p < input->length) {
+ if (!checkAttr(input->chars[p], CTC_Space, 0, table)) {
+ if (checkAttr(input->chars[p], CTC_Digit, 0, table))
+ return;
+ break;
+ }
+ p++;
+ }
+ }
+ break;
+ case CTO_LowWord:
+ if (dontContract || (mode & noContractions)) break;
+ if ((beforeAttributes & CTC_Space) &&
+ (afterAttributes & CTC_Space) &&
+ (prevTransOpcode != CTO_JoinableWord))
+ return;
+ break;
+ case CTO_JoinableWord:
+ if (dontContract || (mode & noContractions)) break;
+ if (beforeAttributes & (CTC_Space | CTC_Punctuation) &&
+ onlyLettersAhead(table, pos, input, *transCharslen,
+ afterAttributes) &&
+ noCompbrlAhead(table, pos, mode, input, *transOpcode,
+ *transCharslen, cursorPosition))
+ return;
+ break;
+ case CTO_SuffixableWord:
+ if (dontContract || (mode & noContractions)) break;
+ if ((beforeAttributes & (CTC_Space | CTC_Punctuation)) &&
+ (afterAttributes &
+ (CTC_Space | CTC_Letter | CTC_Punctuation)))
+ return;
+ break;
+ case CTO_PrefixableWord:
+ if (dontContract || (mode & noContractions)) break;
+ if ((beforeAttributes &
+ (CTC_Space | CTC_Letter | CTC_Punctuation)) &&
+ (afterAttributes & (CTC_Space | CTC_Punctuation)))
+ return;
+ break;
+ case CTO_BegWord:
+ if (dontContract || (mode & noContractions)) break;
+ if ((beforeAttributes & (CTC_Space | CTC_Punctuation)) &&
+ (afterAttributes & CTC_Letter))
+ return;
+ break;
+ case CTO_BegMidWord:
+ if (dontContract || (mode & noContractions)) break;
+ if ((beforeAttributes &
+ (CTC_Letter | CTC_Space | CTC_Punctuation)) &&
+ (afterAttributes & CTC_Letter))
+ return;
+ break;
+ case CTO_MidWord:
+ if (dontContract || (mode & noContractions)) break;
+ if (beforeAttributes & CTC_Letter && afterAttributes & CTC_Letter)
+ return;
+ break;
+ case CTO_MidEndWord:
+ if (dontContract || (mode & noContractions)) break;
+ if (beforeAttributes & CTC_Letter &&
+ afterAttributes &
+ (CTC_Letter | CTC_Space | CTC_Punctuation))
+ return;
+ break;
+ case CTO_EndWord:
+ if (dontContract || (mode & noContractions)) break;
+ if (beforeAttributes & CTC_Letter &&
+ afterAttributes & (CTC_Space | CTC_Punctuation))
+ return;
+ break;
+ case CTO_BegNum:
+ if (beforeAttributes & (CTC_Space | CTC_Punctuation) &&
+ afterAttributes & CTC_Digit)
+ return;
+ break;
+ case CTO_MidNum:
+ if (prevTransOpcode != CTO_ExactDots &&
+ beforeAttributes & CTC_Digit &&
+ afterAttributes & CTC_Digit)
+ return;
+ break;
+ case CTO_EndNum:
+ if (beforeAttributes & CTC_Digit &&
+ prevTransOpcode != CTO_ExactDots)
+ return;
+ break;
+ case CTO_DecPoint:
+ if (!(afterAttributes & CTC_Digit)) break;
+ if (beforeAttributes & CTC_Digit) *transOpcode = CTO_MidNum;
+ return;
+ case CTO_PrePunc:
+ if (!checkAttr(input->chars[pos], CTC_Punctuation, 0, table) ||
+ (pos > 0 &&
+ checkAttr(input->chars[pos - 1], CTC_Letter, 0,
+ table)))
+ break;
+ for (k = pos + *transCharslen; k < input->length; k++) {
+ if (checkAttr(input->chars[k], (CTC_Letter | CTC_Digit), 0,
+ table))
+ return;
+ if (checkAttr(input->chars[k], CTC_Space, 0, table)) break;
+ }
+ break;
+ case CTO_PostPunc:
+ if (!checkAttr(input->chars[pos], CTC_Punctuation, 0, table) ||
+ (pos < (input->length - 1) &&
+ checkAttr(input->chars[pos + 1], CTC_Letter, 0,
+ table)))
+ break;
+ for (k = pos; k >= 0; k--) {
+ if (checkAttr(input->chars[k], (CTC_Letter | CTC_Digit), 0,
+ table))
+ return;
+ if (checkAttr(input->chars[k], CTC_Space, 0, table)) break;
+ }
+ break;
+
+ case CTO_Match: {
+ widechar *patterns, *pattern;
+
+ if (dontContract || (mode & noContractions)) break;
+ if (checkEmphasisChange(0, pos, emphasisBuffer, *transRule))
+ break;
+
+ patterns = (widechar *)&table->ruleArea[(*transRule)->patterns];
+
+ /* check before pattern */
+ pattern = &patterns[1];
+ if (!_lou_pattern_check(
+ input->chars, pos - 1, -1, -1, pattern, table))
+ break;
+
+ /* check after pattern */
+ pattern = &patterns[patterns[0]];
+ if (!_lou_pattern_check(input->chars,
+ pos + (*transRule)->charslen, input->length, 1,
+ pattern, table))
+ break;
+
+ return;
+ }
+
+ default:
+ break;
+ }
+ }
+ /* Done with checking this rule */
+ ruleOffset = (*transRule)->charsnext;
+ }
+ }
+}
+
+static int
+undefinedCharacter(widechar c, const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int pos, const InString *input,
+ OutString *output, int *posMapping, int *cursorPosition, int *cursorStatus,
+ int mode) {
+ /* Display an undefined character in the output buffer */
+ if (table->undefined) {
+ TranslationTableRule *rule =
+ (TranslationTableRule *)&table->ruleArea[table->undefined];
+
+ return for_updatePositions(&rule->charsdots[rule->charslen], rule->charslen,
+ rule->dotslen, 0, pos, input, output, posMapping, cursorPosition,
+ cursorStatus);
+ }
+
+ const char *text = (mode & noUndefined) ? "" : _lou_showString(&c, 1, 1);
+ size_t length = strlen(text);
+ widechar dots[length];
+
+ for (unsigned int k = 0; k < length; k += 1) {
+ widechar c = text[k];
+ widechar d = _lou_getDotsForChar(c, displayTable);
+ // assume that if d is blank, it's because the display table does not have a
+ // mapping to c (not because blank maps to c)
+ if (d == LOU_DOTS) d = _lou_charToFallbackDots(c);
+ dots[k] = d;
+ }
+
+ return for_updatePositions(dots, 1, length, 0, pos, input, output, posMapping,
+ cursorPosition, cursorStatus);
+}
+
+static int
+putCharacter(widechar character, const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int pos, const InString *input,
+ OutString *output, int *posMapping, int *cursorPosition, int *cursorStatus,
+ int mode) {
+ /* Insert the dots equivalent of a character into the output buffer */
+ const TranslationTableRule *rule = NULL;
+ TranslationTableCharacter *chardef = NULL;
+ TranslationTableOffset offset;
+ widechar d;
+ chardef = findCharOrDots(character, 0, table);
+ // If capsletter is defined, replace uppercase with lowercase letters. If capsletter
+ // is not defined, uppercase letters should be preserved because otherwise case info
+ // is lost.
+ if ((chardef->attributes & CTC_UpperCase) && capsletterDefined(table))
+ chardef = findCharOrDots(chardef->lowercase, 0, table);
+ offset = chardef->definitionRule;
+ if (offset) {
+ rule = (TranslationTableRule *)&table->ruleArea[offset];
+ if (rule->dotslen)
+ return for_updatePositions(&rule->charsdots[1], 1, rule->dotslen, 0, pos,
+ input, output, posMapping, cursorPosition, cursorStatus);
+ d = _lou_getDotsForChar(character, displayTable);
+ return for_updatePositions(&d, 1, 1, 0, pos, input, output, posMapping,
+ cursorPosition, cursorStatus);
+ }
+ return undefinedCharacter(character, table, displayTable, pos, input, output,
+ posMapping, cursorPosition, cursorStatus, mode);
+}
+
+static int
+putCharacters(const widechar *characters, int count, const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int pos, const InString *input,
+ OutString *output, int *posMapping, int *cursorPosition, int *cursorStatus,
+ int mode) {
+ /* Insert the dot equivalents of a series of characters in the output
+ * buffer */
+ int k;
+ for (k = 0; k < count; k++)
+ if (!putCharacter(characters[k], table, displayTable, pos, input, output,
+ posMapping, cursorPosition, cursorStatus, mode))
+ return 0;
+ return 1;
+}
+
+// state at the beginning of the current word, used for back-tracking and also for the
+// nocont and compbrl rules
+typedef struct {
+ int inPos; // begin position of the current word in the input
+ int outPos; // begin position of the current word in the output
+ int emphasisInPos; // position of the next character in the input for which to insert
+ // emphasis marks
+} LastWord;
+
+static int
+doCompbrl(const TranslationTableHeader *table, const DisplayTableHeader *displayTable,
+ int *pos, const InString *input, OutString *output, int *posMapping,
+ EmphasisInfo *emphasisBuffer, const TranslationTableRule **transRule,
+ int *cursorPosition, int *cursorStatus, const LastWord *lastWord,
+ int *insertEmphasesFrom, int mode) {
+ /* Handle strings containing substrings defined by the compbrl opcode */
+ int stringStart, stringEnd;
+ if (checkAttr(input->chars[*pos], CTC_Space, 0, table)) return 1;
+ if (lastWord->outPos) {
+ *pos = lastWord->inPos;
+ output->length = lastWord->outPos;
+ } else {
+ *pos = 0;
+ output->length = 0;
+ }
+ *insertEmphasesFrom = lastWord->emphasisInPos;
+ for (stringStart = *pos; stringStart >= 0; stringStart--)
+ if (checkAttr(input->chars[stringStart], CTC_Space, 0, table)) break;
+ stringStart++;
+ for (stringEnd = *pos; stringEnd < input->length; stringEnd++)
+ if (checkAttr(input->chars[stringEnd], CTC_Space, 0, table)) break;
+ return doCompTrans(stringStart, stringEnd, table, displayTable, pos, input, output,
+ posMapping, emphasisBuffer, transRule, cursorPosition, cursorStatus, mode);
+}
+
+static int
+putCompChar(widechar character, const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int pos, const InString *input,
+ OutString *output, int *posMapping, int *cursorPosition, int *cursorStatus,
+ int mode) {
+ /* Insert the dots equivalent of a character into the output buffer */
+ widechar d;
+ TranslationTableOffset offset = (findCharOrDots(character, 0, table))->definitionRule;
+ if (offset) {
+ const TranslationTableRule *rule =
+ (TranslationTableRule *)&table->ruleArea[offset];
+ if (rule->dotslen)
+ return for_updatePositions(&rule->charsdots[1], 1, rule->dotslen, 0, pos,
+ input, output, posMapping, cursorPosition, cursorStatus);
+ d = _lou_getDotsForChar(character, displayTable);
+ return for_updatePositions(&d, 1, 1, 0, pos, input, output, posMapping,
+ cursorPosition, cursorStatus);
+ }
+ return undefinedCharacter(character, table, displayTable, pos, input, output,
+ posMapping, cursorPosition, cursorStatus, mode);
+}
+
+static int
+doCompTrans(int start, int end, const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int *pos, const InString *input,
+ OutString *output, int *posMapping, EmphasisInfo *emphasisBuffer,
+ const TranslationTableRule **transRule, int *cursorPosition, int *cursorStatus,
+ int mode) {
+ const TranslationTableRule *indicRule;
+ int k;
+ int haveEndsegment = 0;
+ if (*cursorStatus != 2 && brailleIndicatorDefined(table->begComp, table, &indicRule))
+ if (!for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen, 0, *pos,
+ input, output, posMapping, cursorPosition, cursorStatus))
+ return 0;
+ for (k = start; k < end; k++) {
+ TranslationTableOffset compdots = 0;
+ /* HACK: computer braille is one-to-one so it
+ * can't have any emphasis indicators.
+ * A better solution is to treat computer braille as its own mode. */
+ emphasisBuffer[k] = (EmphasisInfo){ 0 };
+ if (input->chars[k] == LOU_ENDSEGMENT) {
+ haveEndsegment = 1;
+ continue;
+ }
+ *pos = k;
+ if (input->chars[k] < 256) compdots = table->compdotsPattern[input->chars[k]];
+ if (compdots != 0) {
+ *transRule = (TranslationTableRule *)&table->ruleArea[compdots];
+ if (!for_updatePositions(&(*transRule)->charsdots[(*transRule)->charslen],
+ (*transRule)->charslen, (*transRule)->dotslen, 0, *pos, input,
+ output, posMapping, cursorPosition, cursorStatus))
+ return 0;
+ } else if (!putCompChar(input->chars[k], table, displayTable, *pos, input, output,
+ posMapping, cursorPosition, cursorStatus, mode))
+ return 0;
+ }
+ if (*cursorStatus != 2 && brailleIndicatorDefined(table->endComp, table, &indicRule))
+ if (!for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen, 0, *pos,
+ input, output, posMapping, cursorPosition, cursorStatus))
+ return 0;
+ *pos = end;
+ if (haveEndsegment) {
+ widechar endSegment = LOU_ENDSEGMENT;
+ if (!for_updatePositions(&endSegment, 0, 1, 0, *pos, input, output, posMapping,
+ cursorPosition, cursorStatus))
+ return 0;
+ }
+ return 1;
+}
+
+static int
+doNocont(const TranslationTableHeader *table, int *pos, OutString *output, int mode,
+ const InString *input, const LastWord *lastWord, int *dontContract,
+ int *insertEmphasesFrom) {
+ /* Handle strings containing substrings defined by the nocont opcode */
+ if (checkAttr(input->chars[*pos], CTC_Space, 0, table) || *dontContract ||
+ (mode & noContractions))
+ return 1;
+ if (lastWord->outPos) {
+ *pos = lastWord->inPos;
+ output->length = lastWord->outPos;
+ } else {
+ *pos = 0;
+ output->length = 0;
+ }
+ *insertEmphasesFrom = lastWord->emphasisInPos;
+ *dontContract = 1;
+ return 1;
+}
+
+static int
+markSyllables(const TranslationTableHeader *table, const InString *input,
+ formtype *typebuf, int *transOpcode, const TranslationTableRule **transRule,
+ int *transCharslen) {
+ int pos;
+ int k;
+ int currentMark = 0;
+ int const syllable_marks[] = { SYLLABLE_MARKER_1, SYLLABLE_MARKER_2 };
+ int syllable_mark_selector = 0;
+
+ if (typebuf == NULL || !table->syllables) return 1;
+ pos = 0;
+ while (pos < input->length) { /* the main multipass translation loop */
+ int length = input->length - pos;
+ int tryThis = 0;
+ while (tryThis < 3) {
+ TranslationTableOffset ruleOffset = 0;
+ switch (tryThis) {
+ case 0:
+ if (!(length >= 2)) break;
+ // memory overflow when pos == input->length - 1
+ ruleOffset =
+ table->forRules[_lou_stringHash(&input->chars[pos], 1, table)];
+ break;
+ case 1:
+ if (!(length >= 1)) break;
+ length = 1;
+ ruleOffset = findCharOrDots(input->chars[pos], 0, table)->otherRules;
+ break;
+ case 2: /* No rule found */
+ *transOpcode = CTO_Always;
+ ruleOffset = 0;
+ break;
+ }
+ while (ruleOffset) {
+ *transRule = (TranslationTableRule *)&table->ruleArea[ruleOffset];
+ *transOpcode = (*transRule)->opcode;
+ *transCharslen = (*transRule)->charslen;
+ if (tryThis == 1 ||
+ (*transCharslen <= length &&
+ compareChars(&(*transRule)->charsdots[0],
+ &input->chars[pos], *transCharslen, 0, table))) {
+ if (*transOpcode == CTO_Syllable) {
+ tryThis = 4;
+ break;
+ }
+ }
+ ruleOffset = (*transRule)->charsnext;
+ }
+ tryThis++;
+ }
+ switch (*transOpcode) {
+ case CTO_Always:
+ if (pos >= input->length) return 0;
+ typebuf[pos++] |= currentMark;
+ break;
+ case CTO_Syllable:
+ /* cycle between SYLLABLE_MARKER_1 and SYLLABLE_MARKER_2 so
+ * we can distinguinsh two consequtive syllables */
+ currentMark = syllable_marks[syllable_mark_selector];
+ syllable_mark_selector = (syllable_mark_selector + 1) % 2;
+
+ if ((pos + *transCharslen) > input->length) return 0;
+ for (k = 0; k < *transCharslen; k++) typebuf[pos++] |= currentMark;
+ break;
+ default:
+ break;
+ }
+ }
+ return 1;
+}
+
+static const EmphasisClass capsEmphClass = 0x1;
+static const EmphasisClass *emphClasses = NULL;
+
+/* An emphasis class is a bit field that contains a single "1" */
+static void
+initEmphClasses(void) {
+ EmphasisClass *classes = malloc(10 * sizeof(EmphasisClass));
+ int j;
+ if (!classes) _lou_outOfMemory();
+ for (j = 0; j < 10; j++) {
+ classes[j] = 0x1 << (j + 1);
+ }
+ emphClasses = classes;
+}
+
+static void
+resolveEmphasisWords(EmphasisInfo *buffer, const EmphasisClass class,
+ const InString *input, unsigned int *wordBuffer) {
+ int in_word = 0, in_emp = 0, word_stop; // booleans
+ int word_start = -1; // input position
+ unsigned int word_whole = 0; // wordBuffer value
+ int i;
+
+ for (i = 0; i < input->length; i++) {
+ // TODO: give each emphasis its own whole word bit?
+ /* clear out previous whole word markings */
+ wordBuffer[i] &= ~WORD_WHOLE;
+
+ /* check if at beginning of emphasis */
+ if (!in_emp)
+ if (buffer[i].begin & class) {
+ in_emp = 1;
+ buffer[i].begin &= ~class;
+
+ /* emphasis started inside word (and is therefore not a whole word) */
+ if (in_word) {
+ word_start = i;
+ word_whole = 0;
+ }
+
+ /* emphasis started on space */
+ if (!(wordBuffer[i] & WORD_CHAR)) word_start = -1;
+ }
+
+ /* check if at end of emphasis */
+ if (in_emp)
+ if (buffer[i].end & class) {
+ in_emp = 0;
+ buffer[i].end &= ~class;
+
+ if (in_word && word_start >= 0) {
+ /* check if emphasis ended inside a word (and is therefore not a whole
+ * word) */
+ word_stop = 1;
+ if (wordBuffer[i] & WORD_CHAR)
+ word_whole = 0;
+ else
+ word_stop = 0;
+
+ /* if whole word is one symbol, turn it into a symbol */
+ if (word_start + 1 == i)
+ buffer[word_start].symbol |= class;
+ else {
+ /* else mark the word start point and, if emphasis ended inside a
+ * word, also mark the end point */
+ buffer[word_start].word |= class;
+ if (word_stop) {
+ buffer[i].end |= class;
+ buffer[i].word |= class;
+ }
+ }
+ /* mark it as a whole word or not */
+ wordBuffer[word_start] |= word_whole;
+ }
+ }
+
+ /* check if at beginning of word (first character that is not a space) */
+ if (!in_word)
+ if (wordBuffer[i] & WORD_CHAR) {
+ in_word = 1;
+ if (in_emp) {
+ word_whole = WORD_WHOLE;
+ word_start = i;
+ }
+ }
+
+ /* check if at end of word (last character that is not a space) */
+ if (in_word)
+ if (!(wordBuffer[i] & WORD_CHAR)) {
+ /* made it through whole word */
+ if (in_emp && word_start >= 0) {
+ /* if word is one symbol, turn it into a symbol */
+ if (word_start + 1 == i)
+ buffer[word_start].symbol |= class;
+ else
+ /* else mark it as a word */
+ buffer[word_start].word |= class;
+ /* mark it as a whole word or not */
+ wordBuffer[word_start] |= word_whole;
+ }
+
+ in_word = 0;
+ word_whole = 0;
+ word_start = -1;
+ }
+ }
+
+ /* clean up end */
+ if (in_emp) {
+ buffer[i].end &= ~class;
+
+ if (in_word)
+ if (word_start >= 0) {
+ /* if word is one symbol, turn it into a symbol */
+ if (word_start + 1 == i)
+ buffer[word_start].symbol |= class;
+ else
+ /* else mark it as a word */
+ buffer[word_start].word |= class;
+ /* mark it as a whole word or not */
+ wordBuffer[word_start] |= word_whole;
+ }
+ }
+}
+
+static void
+convertToPassage(const int pass_start, const int pass_end, const int word_start,
+ EmphasisInfo *buffer, const EmphRuleNumber emphRule, const EmphasisClass class,
+ const TranslationTableHeader *table, unsigned int *wordBuffer) {
+ int i;
+ const TranslationTableRule *indicRule;
+
+ for (i = pass_start; i <= pass_end; i++)
+ if (wordBuffer[i] & WORD_WHOLE) {
+ buffer[i].symbol &= ~class;
+ buffer[i].word &= ~class;
+ wordBuffer[i] &= ~WORD_WHOLE;
+ }
+
+ buffer[pass_start].begin |= class;
+ if (brailleIndicatorDefined(
+ table->emphRules[emphRule][endOffset], table, &indicRule) ||
+ brailleIndicatorDefined(
+ table->emphRules[emphRule][endPhraseAfterOffset], table, &indicRule))
+ buffer[pass_end].end |= class;
+ else if (brailleIndicatorDefined(table->emphRules[emphRule][endPhraseBeforeOffset],
+ table, &indicRule)) {
+ /* if the phrase end indicator is the same as the word indicator, mark it as a
+ * word so that the resolveEmphasisResets code applies */
+ const TranslationTableRule *begwordRule;
+ if (brailleIndicatorDefined(
+ table->emphRules[emphRule][begWordOffset], table, &begwordRule) &&
+ indicRule->dotslen == begwordRule->dotslen &&
+ !memcmp(&indicRule->charsdots[0], &begwordRule->charsdots[0],
+ begwordRule->dotslen * CHARSIZE)) {
+ buffer[word_start].word |= class;
+ /* a passage has only whole emphasized words */
+ wordBuffer[word_start] |= WORD_WHOLE;
+ } else {
+ buffer[word_start].end |= class;
+ }
+ }
+}
+
+static void
+resolveEmphasisPassages(EmphasisInfo *buffer, const EmphRuleNumber emphRule,
+ const EmphasisClass class, const TranslationTableHeader *table,
+ const InString *input, unsigned int *wordBuffer) {
+ unsigned int word_cnt = 0;
+ int pass_start = -1, pass_end = -1, word_start = -1, in_word = 0, in_pass = 0;
+ int i;
+
+ for (i = 0; i < input->length; i++) {
+ /* check if at beginning of word (first character that is not a space) */
+ if (!in_word)
+ if (wordBuffer[i] & WORD_CHAR) {
+ in_word = 1;
+ /* only whole emphasized words can be part of a passage (in case of caps,
+ * this also includes words without letters, but only if the next word
+ * with letters is a whole word) */
+ if (wordBuffer[i] & WORD_WHOLE) {
+ if (!in_pass) {
+ in_pass = 1;
+ pass_start = i;
+ pass_end = -1;
+ word_cnt = 1;
+ } else
+ word_cnt++;
+ word_start = i;
+ continue;
+ } else if (in_pass) {
+ /* it is a passage only if the number of words is greater than or
+ * equal to the minimum length (lencapsphrase / lenemphphrase) */
+ if (word_cnt >= table->emphRules[emphRule][lenPhraseOffset])
+ if (pass_end >= 0) {
+ convertToPassage(pass_start, pass_end, word_start, buffer,
+ emphRule, class, table, wordBuffer);
+ }
+ in_pass = 0;
+ }
+ }
+
+ /* check if at end of word */
+ if (in_word)
+ if (!(wordBuffer[i] & WORD_CHAR)) {
+ in_word = 0;
+ if (in_pass) pass_end = i;
+ }
+
+ if (in_pass)
+ if ((buffer[i].begin | buffer[i].end | buffer[i].word | buffer[i].symbol) &
+ class) {
+ if (word_cnt >= table->emphRules[emphRule][lenPhraseOffset])
+ if (pass_end >= 0) {
+ convertToPassage(pass_start, pass_end, word_start, buffer,
+ emphRule, class, table, wordBuffer);
+ }
+ in_pass = 0;
+ }
+ }
+
+ if (in_pass) {
+ if (word_cnt >= table->emphRules[emphRule][lenPhraseOffset]) {
+ if (pass_end >= 0) {
+ if (in_word) {
+ convertToPassage(pass_start, i, word_start, buffer, emphRule, class,
+ table, wordBuffer);
+ } else {
+ convertToPassage(pass_start, pass_end, word_start, buffer, emphRule,
+ class, table, wordBuffer);
+ }
+ }
+ }
+ }
+}
+
+static void
+resolveEmphasisSingleSymbols(
+ EmphasisInfo *buffer, const EmphasisClass class, const InString *input) {
+ int i;
+
+ for (i = 0; i < input->length; i++) {
+ if (buffer[i].begin & class)
+ if (buffer[i + 1].end & class) {
+ buffer[i].begin &= ~class;
+ buffer[i + 1].end &= ~class;
+ buffer[i].symbol |= class;
+ }
+ }
+}
+
+static void
+resolveEmphasisAllCapsSymbols(
+ EmphasisInfo *buffer, formtype *typebuf, const InString *input) {
+ /* Marks every caps letter with capsEmphClass symbol.
+ * Used in the special case where capsnocont has been defined and capsword has not
+ * been defined. */
+
+ int inEmphasis = 0, i;
+
+ for (i = 0; i < input->length; i++) {
+ if (buffer[i].end & capsEmphClass) {
+ inEmphasis = 0;
+ buffer[i].end &= ~capsEmphClass;
+ } else {
+ if (buffer[i].begin & capsEmphClass) {
+ buffer[i].begin &= ~capsEmphClass;
+ inEmphasis = 1;
+ }
+ if (inEmphasis) {
+ if (typebuf[i] & CAPSEMPH)
+ /* Only mark if actually a capital letter (don't mark spaces or
+ * punctuation). */
+ buffer[i].symbol |= capsEmphClass;
+ } /* In emphasis */
+ } /* Not caps end */
+ }
+}
+
+static void
+resolveEmphasisResets(EmphasisInfo *buffer, const EmphasisClass class,
+ const TranslationTableCharacterAttribute emphModeCharsAttr,
+ const TranslationTableHeader *table, const InString *input,
+ unsigned int *wordBuffer) {
+ int in_word = 0, in_pass = 0, word_start = -1, word_reset = 0, letter_cnt = 0,
+ pass_end = -1;
+ int i;
+
+ for (i = 0; i < input->length; i++) {
+ if (in_pass) {
+ if (buffer[i].end & class)
+ in_pass = 0;
+ else if (buffer[i].word & class) {
+ /* the passage is ended with a "begphrase before" indicator and this
+ * indicator is the same as the "begword" indicator */
+ in_pass = 0;
+ /* remember this position so that if there is a reset later in this word,
+ * we can remove this indicator */
+ pass_end = i;
+ }
+ }
+ if (!in_pass) {
+ if (buffer[i].begin & class)
+ in_pass = 1;
+ else {
+ if (!in_word) {
+ if (buffer[i].word & class) {
+ /* deal with case when reset was at beginning of word */
+ if (wordBuffer[i] & WORD_RESET ||
+ !checkAttr(input->chars[i], CTC_Letter, 0, table)) {
+ /* if the reset is a letter and marks the end of a passage,
+ * use the word indicator */
+ /* note that there must be at least one word reset on a letter
+ * because a passage can not end on a word without uppercase
+ * letters */
+ if (!(pass_end == i &&
+ checkAttr(
+ input->chars[i], CTC_Letter, 0, table))) {
+
+ /* move the word marker to the next character or remove it
+ * altogether if the next character is a space */
+ if (wordBuffer[i + 1] & WORD_CHAR) {
+ buffer[i + 1].word |= class;
+ if (wordBuffer[i] & WORD_WHOLE)
+ wordBuffer[i + 1] |= WORD_WHOLE;
+ if (pass_end == i) pass_end++;
+ }
+ buffer[i].word &= ~class;
+ wordBuffer[i] &= ~WORD_WHOLE;
+
+ /* if reset is a letter, make it a symbol */
+ if (checkAttr(input->chars[i], CTC_Letter, 0, table))
+ buffer[i].symbol |= class;
+
+ continue;
+ }
+ }
+
+ in_word = 1;
+ word_start = i;
+ letter_cnt = 0;
+ word_reset = 0;
+ }
+
+ /* it is possible for a character to have been
+ * marked as a symbol when it should not be one */
+ else if (buffer[i].symbol & class) {
+ if (wordBuffer[i] & WORD_RESET ||
+ !checkAttr(input->chars[i], CTC_Letter, 0, table))
+ buffer[i].symbol &= ~class;
+ }
+ }
+
+ if (in_word) {
+
+ /* at end of word */
+ if (!(wordBuffer[i] & WORD_CHAR) ||
+ (buffer[i].word & class && buffer[i].end & class)) {
+ in_word = 0;
+
+ /* check if symbol */
+ if (letter_cnt == 1 && word_start != pass_end) {
+ buffer[word_start].symbol |= class;
+ buffer[word_start].word &= ~class;
+ wordBuffer[word_start] &= ~WORD_WHOLE;
+ buffer[i].end &= ~class;
+ buffer[i].word &= ~class;
+ }
+
+ /* if word ended on a reset or last char was a reset,
+ * get rid of end bits */
+ if (word_reset || wordBuffer[i] & WORD_RESET ||
+ !checkAttr(input->chars[i], CTC_Letter, 0, table)) {
+ buffer[i].end &= ~class;
+ buffer[i].word &= ~class;
+ }
+
+ /* if word ended when it began, get rid of all bits */
+ if (i == word_start) {
+ wordBuffer[word_start] &= ~WORD_WHOLE;
+ buffer[i].end &= ~class;
+ buffer[i].word &= ~class;
+ }
+ } else {
+ /* hit reset */
+ if (wordBuffer[i] & WORD_RESET ||
+ !checkAttr(input->chars[i], CTC_Letter, 0, table)) {
+ /* characters that are not letters are resetting */
+ if (!checkAttr(input->chars[i], CTC_Letter, 0, table)) {
+ /* ... unless they are marked as not resetting
+ * (capsmodechars / emphmodechars) */
+ if (checkAttr(
+ input->chars[i], emphModeCharsAttr, 0, table))
+ continue;
+ }
+
+ /* check if symbol is not already resetting */
+ if (letter_cnt == 1 && word_start != pass_end) {
+ buffer[word_start].symbol |= class;
+ buffer[word_start].word &= ~class;
+ wordBuffer[word_start] &= ~WORD_WHOLE;
+ }
+
+ /* if reset is a letter, make it the new word_start */
+ if (checkAttr(input->chars[i], CTC_Letter, 0, table)) {
+ if (word_start == pass_end)
+ /* move the word marker that ends the passage to the
+ * current position */
+ buffer[pass_end].word &= ~class;
+ pass_end = -1;
+ word_reset = 0;
+ word_start = i;
+ letter_cnt = 1;
+ buffer[i].word |= class;
+ } else
+ word_reset = 1;
+
+ continue;
+ }
+
+ if (word_reset) {
+ if (word_start == pass_end)
+ /* move the word marker that ends the passage to the
+ * current position */
+ buffer[pass_end].word &= ~class;
+ pass_end = -1;
+ word_reset = 0;
+ word_start = i;
+ letter_cnt = 0;
+ buffer[i].word |= class;
+ }
+
+ letter_cnt++;
+ }
+ }
+ }
+ }
+ }
+
+ /* clean up end */
+ if (in_word) {
+ /* check if symbol */
+ if (letter_cnt == 1 && word_start != pass_end) {
+ buffer[word_start].symbol |= class;
+ buffer[word_start].word &= ~class;
+ wordBuffer[word_start] &= ~WORD_WHOLE;
+ buffer[i].end &= ~class;
+ buffer[i].word &= ~class;
+ }
+
+ if (word_reset) {
+ buffer[i].end &= ~class;
+ buffer[i].word &= ~class;
+ }
+ }
+}
+
+static void
+markEmphases(const TranslationTableHeader *table, const InString *input,
+ formtype *typebuf, unsigned int *wordBuffer, EmphasisInfo *emphasisBuffer,
+ int haveEmphasis) {
+ /* Relies on the order of typeforms emph_1..emph_10. */
+ int last_space = -1; // position of the last encountered space
+ int caps_start = -1; // position of the first uppercase after which no lowercase was
+ // encountered
+ int last_caps = -1; // position of the first space following the last encountered
+ // letter if that letter was an uppercase
+ int caps = 0; // whether or not the last encountered letter was an uppercase and
+ // happened in the current word
+ int caps_cnt = 0; // number of consecutive characters ending with the current that
+ // are uppercase letters
+ int emph_start[10] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
+ int caps_phrase_enabled = table->emphRules[capsRule][begWordOffset] &&
+ table->emphRules[capsRule][lenPhraseOffset];
+ int i, j;
+
+ // initialize static variable emphClasses
+ if (haveEmphasis && !emphClasses) {
+ initEmphClasses();
+ }
+
+ for (i = 0; i < input->length; i++) {
+ /* WORD_CHAR means character is not a space */
+ if (!checkAttr(input->chars[i], CTC_Space, 0, table)) {
+ wordBuffer[i] |= WORD_CHAR;
+ } else {
+ last_space = i;
+ if (caps) {
+ last_caps = i;
+ caps = 0;
+ }
+ }
+
+ /* if character is uppercase, caps begins or continues */
+ if (checkAttr(input->chars[i], CTC_UpperCase, 0, table)) {
+ if (caps_start < 0) caps_start = i;
+ caps = 1;
+ /* handle capsnocont */
+ /* mark two or more consecutive caps with nocont */
+ caps_cnt++;
+ if (table->capsNoCont && caps_cnt >= 2) {
+ typebuf[i] |= no_contract;
+ /* also mark the previous one */
+ if (caps_cnt == 2) typebuf[i - 1] |= no_contract;
+ }
+ } else {
+ caps_cnt = 0;
+ if (caps_start >= 0) {
+ /* else if caps has begun, it should continue if there are no lowercase
+ * before the next uppercase */
+ /* characters that cancel caps mode are handled later in
+ * resolveEmphasisResets (note that letters that are neither uppercase nor
+ * lowercase do not cancel caps mode) */
+ if (checkAttr(input->chars[i], CTC_Letter, 0, table) &&
+ checkAttr(input->chars[i], CTC_LowerCase, 0, table)) {
+ emphasisBuffer[caps_start].begin |= capsEmphClass;
+ if (caps) {
+ /* a passage can not end on a word without uppercase letters, so
+ * if caps did not start inside the current word, end it after the
+ * last word that contained a uppercase, and start over from the
+ * beginning of the current word */
+ if (caps_phrase_enabled && caps_start < last_space) {
+ emphasisBuffer[last_caps].end |= capsEmphClass;
+ caps_start = -1;
+ last_caps = -1;
+ caps = 0;
+ i = last_space;
+ continue;
+ }
+ emphasisBuffer[i].end |= capsEmphClass;
+ } else
+ emphasisBuffer[last_caps].end |= capsEmphClass;
+ caps_start = -1;
+ last_caps = -1;
+ caps = 0;
+ }
+ }
+ }
+
+ if (!haveEmphasis) continue;
+
+ for (j = 0; j < 10; j++) {
+ if (typebuf[i] & (emph_1 << j)) {
+ if (emph_start[j] < 0) emph_start[j] = i;
+ } else if (emph_start[j] >= 0) {
+ emphasisBuffer[emph_start[j]].begin |= emphClasses[j];
+ emphasisBuffer[i].end |= emphClasses[j];
+ emph_start[j] = -1;
+ }
+ }
+ }
+
+ /* clean up input->length */
+ if (caps_start >= 0) {
+ emphasisBuffer[caps_start].begin |= capsEmphClass;
+ if (caps)
+ emphasisBuffer[input->length].end |= capsEmphClass;
+ else
+ emphasisBuffer[last_caps].end |= capsEmphClass;
+ }
+
+ if (haveEmphasis) {
+ for (j = 0; j < 10; j++) {
+ if (emph_start[j] >= 0) {
+ emphasisBuffer[emph_start[j]].begin |= emphClasses[j];
+ emphasisBuffer[input->length].end |= emphClasses[j];
+ }
+ }
+ }
+
+ if (table->emphRules[capsRule][begWordOffset]) {
+ /* mark word beginning and end points, whole words, and symbols (single
+ * characters) */
+ resolveEmphasisWords(emphasisBuffer, capsEmphClass, input, wordBuffer);
+ if (table->emphRules[capsRule][lenPhraseOffset])
+ /* remove markings of words that form a passage, and mark the begin and
+ * end of these passages instead */
+ resolveEmphasisPassages(
+ emphasisBuffer, capsRule, capsEmphClass, table, input, wordBuffer);
+ /* mark where emphasis in a word needs to be retriggered after it was reset */
+ resolveEmphasisResets(
+ emphasisBuffer, capsEmphClass, CTC_CapsMode, table, input, wordBuffer);
+ } else if (capsletterDefined(table)) {
+ if (table->capsNoCont) /* capsnocont and no capsword */
+ resolveEmphasisAllCapsSymbols(emphasisBuffer, typebuf, input);
+ else
+ resolveEmphasisSingleSymbols(emphasisBuffer, capsEmphClass, input);
+ }
+ if (!haveEmphasis) return;
+
+ for (j = 0; j < 10; j++) {
+ if (table->emphRules[emph1Rule + j][begWordOffset]) {
+ resolveEmphasisWords(emphasisBuffer, emphClasses[j], input, wordBuffer);
+ if (table->emphRules[emph1Rule + j][lenPhraseOffset])
+ resolveEmphasisPassages(emphasisBuffer, emph1Rule + j, emphClasses[j],
+ table, input, wordBuffer);
+ if (table->usesEmphMode)
+ resolveEmphasisResets(emphasisBuffer, emphClasses[j], CTC_EmphMode, table,
+ input, wordBuffer);
+ } else if (table->emphRules[emph1Rule + j][letterOffset])
+ resolveEmphasisSingleSymbols(emphasisBuffer, emphClasses[j], input);
+ }
+}
+
+static void
+insertEmphasisSymbol(const EmphasisInfo *buffer, const int at,
+ const EmphRuleNumber emphRule, const EmphasisClass class,
+ const TranslationTableHeader *table, int pos, const InString *input,
+ OutString *output, int *posMapping, int *cursorPosition, int *cursorStatus) {
+ if (buffer[at].symbol & class) {
+ const TranslationTableRule *indicRule;
+ if (brailleIndicatorDefined(
+ table->emphRules[emphRule][letterOffset], table, &indicRule))
+ for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen, 0, pos,
+ input, output, posMapping, cursorPosition, cursorStatus);
+ }
+}
+
+static void
+insertEmphasisBegin(const EmphasisInfo *buffer, const int at,
+ const EmphRuleNumber emphRule, const EmphasisClass class,
+ const TranslationTableHeader *table, int pos, const InString *input,
+ OutString *output, int *posMapping, int *cursorPosition, int *cursorStatus) {
+ const TranslationTableRule *indicRule;
+ if (buffer[at].begin & class) {
+ if (brailleIndicatorDefined(
+ table->emphRules[emphRule][begPhraseOffset], table, &indicRule))
+ for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen, 0, pos,
+ input, output, posMapping, cursorPosition, cursorStatus);
+ else if (brailleIndicatorDefined(
+ table->emphRules[emphRule][begOffset], table, &indicRule))
+ for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen, 0, pos,
+ input, output, posMapping, cursorPosition, cursorStatus);
+ }
+
+ if (buffer[at].word & class
+ // && !(buffer[at].begin & class)
+ && !(buffer[at].end & class)) {
+ if (brailleIndicatorDefined(
+ table->emphRules[emphRule][begWordOffset], table, &indicRule))
+ for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen, 0, pos,
+ input, output, posMapping, cursorPosition, cursorStatus);
+ }
+}
+
+static void
+insertEmphasisEnd(const EmphasisInfo *buffer, const int at, const EmphRuleNumber emphRule,
+ const EmphasisClass class, const TranslationTableHeader *table, int pos,
+ const InString *input, OutString *output, int *posMapping, int *cursorPosition,
+ int *cursorStatus) {
+ if (buffer[at].end & class) {
+ const TranslationTableRule *indicRule;
+ if (buffer[at].word & class) {
+ if (brailleIndicatorDefined(
+ table->emphRules[emphRule][endWordOffset], table, &indicRule))
+ for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen, -1,
+ pos, input, output, posMapping, cursorPosition, cursorStatus);
+ } else {
+ if (brailleIndicatorDefined(
+ table->emphRules[emphRule][endOffset], table, &indicRule))
+ for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen, -1,
+ pos, input, output, posMapping, cursorPosition, cursorStatus);
+ else if (brailleIndicatorDefined(
+ table->emphRules[emphRule][endPhraseAfterOffset], table,
+ &indicRule))
+ for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen, -1,
+ pos, input, output, posMapping, cursorPosition, cursorStatus);
+ else if (brailleIndicatorDefined(
+ table->emphRules[emphRule][endPhraseBeforeOffset], table,
+ &indicRule))
+ for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen, 0,
+ pos, input, output, posMapping, cursorPosition, cursorStatus);
+ }
+ }
+}
+
+static int
+endCount(const EmphasisInfo *buffer, const int at, const EmphasisClass class) {
+ int i, cnt = 1;
+ if (!(buffer[at].end & class)) return 0;
+ for (i = at - 1; i >= 0; i--)
+ if (buffer[i].begin & class || buffer[i].word & class)
+ break;
+ else
+ cnt++;
+ return cnt;
+}
+
+static int
+beginCount(const EmphasisInfo *buffer, const int at, const EmphasisClass class,
+ const TranslationTableHeader *table, const InString *input) {
+ if (buffer[at].begin & class) {
+ int i, cnt = 1;
+ for (i = at + 1; i < input->length; i++)
+ if (buffer[i].end & class)
+ break;
+ else
+ cnt++;
+ return cnt;
+ } else if (buffer[at].word & class) {
+ int i, cnt = 1;
+ for (i = at + 1; i < input->length; i++)
+ if (buffer[i].end & class) break;
+ // TODO: WORD_RESET?
+ else if (checkAttr(input->chars[i], CTC_SeqDelimiter | CTC_Space, 0, table))
+ break;
+ else
+ cnt++;
+ return cnt;
+ }
+ return 0;
+}
+
+static void
+insertEmphasesAt(const int at, const TranslationTableHeader *table, int pos,
+ const InString *input, OutString *output, int *posMapping,
+ const EmphasisInfo *emphasisBuffer, int haveEmphasis, int transOpcode,
+ int *cursorPosition, int *cursorStatus) {
+ int type_counts[10];
+ int i, j, min, max;
+
+ /* simple case */
+ if (!haveEmphasis) {
+ /* insert graded 1 mode indicator */
+ if (transOpcode == CTO_Contraction) {
+ const TranslationTableRule *indicRule;
+ if (brailleIndicatorDefined(table->noContractSign, table, &indicRule))
+ for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen, 0,
+ pos, input, output, posMapping, cursorPosition, cursorStatus);
+ }
+
+ if ((emphasisBuffer[at].begin | emphasisBuffer[at].end | emphasisBuffer[at].word |
+ emphasisBuffer[at].symbol) &
+ capsEmphClass) {
+ insertEmphasisEnd(emphasisBuffer, at, capsRule, capsEmphClass, table, pos,
+ input, output, posMapping, cursorPosition, cursorStatus);
+ insertEmphasisBegin(emphasisBuffer, at, capsRule, capsEmphClass, table, pos,
+ input, output, posMapping, cursorPosition, cursorStatus);
+ insertEmphasisSymbol(emphasisBuffer, at, capsRule, capsEmphClass, table, pos,
+ input, output, posMapping, cursorPosition, cursorStatus);
+ }
+ return;
+ }
+
+ /* The order of inserting the end symbols must be the reverse
+ * of the insertions of the begin symbols so that they will
+ * nest properly when multiple emphases start and end at
+ * the same place */
+ // TODO: ordering with partial word
+
+ if ((emphasisBuffer[at].begin | emphasisBuffer[at].end | emphasisBuffer[at].word |
+ emphasisBuffer[at].symbol) &
+ capsEmphClass)
+ insertEmphasisEnd(emphasisBuffer, at, capsRule, capsEmphClass, table, pos, input,
+ output, posMapping, cursorPosition, cursorStatus);
+
+ /* end bits */
+ for (i = 0; i < 10; i++)
+ type_counts[i] = endCount(emphasisBuffer, at, emphClasses[i]);
+
+ for (i = 0; i < 10; i++) {
+ min = -1;
+ for (j = 0; j < 10; j++)
+ if (type_counts[j] > 0)
+ if (min < 0 || type_counts[j] < type_counts[min]) min = j;
+ if (min < 0) break;
+ type_counts[min] = 0;
+ insertEmphasisEnd(emphasisBuffer, at, emph1Rule + min, emphClasses[min], table,
+ pos, input, output, posMapping, cursorPosition, cursorStatus);
+ }
+
+ /* begin and word bits */
+ for (i = 0; i < 10; i++)
+ type_counts[i] = beginCount(emphasisBuffer, at, emphClasses[i], table, input);
+
+ for (i = 9; i >= 0; i--) {
+ max = 9;
+ for (j = 9; j >= 0; j--)
+ if (type_counts[max] < type_counts[j]) max = j;
+ if (!type_counts[max]) break;
+ type_counts[max] = 0;
+ insertEmphasisBegin(emphasisBuffer, at, emph1Rule + max, emphClasses[max], table,
+ pos, input, output, posMapping, cursorPosition, cursorStatus);
+ }
+
+ /* symbol bits */
+ for (i = 9; i >= 0; i--)
+ if ((emphasisBuffer[at].begin | emphasisBuffer[at].end | emphasisBuffer[at].word |
+ emphasisBuffer[at].symbol) &
+ emphClasses[i])
+ insertEmphasisSymbol(emphasisBuffer, at, emph1Rule + i, emphClasses[i], table,
+ pos, input, output, posMapping, cursorPosition, cursorStatus);
+
+ /* insert graded 1 mode indicator */
+ if (transOpcode == CTO_Contraction) {
+ const TranslationTableRule *indicRule;
+ if (brailleIndicatorDefined(table->noContractSign, table, &indicRule))
+ for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen, 0, pos,
+ input, output, posMapping, cursorPosition, cursorStatus);
+ }
+
+ /* insert capitalization last so it will be closest to word */
+ if ((emphasisBuffer[at].begin | emphasisBuffer[at].end | emphasisBuffer[at].word |
+ emphasisBuffer[at].symbol) &
+ capsEmphClass) {
+ insertEmphasisBegin(emphasisBuffer, at, capsRule, capsEmphClass, table, pos,
+ input, output, posMapping, cursorPosition, cursorStatus);
+ insertEmphasisSymbol(emphasisBuffer, at, capsRule, capsEmphClass, table, pos,
+ input, output, posMapping, cursorPosition, cursorStatus);
+ }
+}
+
+static void
+insertEmphases(const TranslationTableHeader *table, int from, int to,
+ const InString *input, OutString *output, int *posMapping,
+ const EmphasisInfo *emphasisBuffer, int haveEmphasis, int transOpcode,
+ int *cursorPosition, int *cursorStatus) {
+ int at;
+ for (at = from; at <= to; at++)
+ insertEmphasesAt(at, table, to, input, output, posMapping, emphasisBuffer,
+ haveEmphasis, transOpcode, cursorPosition, cursorStatus);
+}
+
+static void
+checkNumericMode(const TranslationTableHeader *table, int pos, const InString *input,
+ OutString *output, int *posMapping, int *cursorPosition, int *cursorStatus,
+ int *dontContract, int *numericMode) {
+ int i;
+ const TranslationTableRule *indicRule;
+ if (!brailleIndicatorDefined(table->numberSign, table, &indicRule)) return;
+
+ /* not in numeric mode */
+ if (!*numericMode) {
+ if (checkAttr(input->chars[pos], CTC_Digit | CTC_LitDigit, 0, table)) {
+ *numericMode = 1;
+ *dontContract = 1;
+ for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen, 0, pos,
+ input, output, posMapping, cursorPosition, cursorStatus);
+ } else if (checkAttr(input->chars[pos], CTC_NumericMode, 0, table)) {
+ for (i = pos + 1; i < input->length; i++) {
+ if (checkAttr(input->chars[i], CTC_Digit | CTC_LitDigit, 0, table)) {
+ *numericMode = 1;
+ for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen,
+ 0, pos, input, output, posMapping, cursorPosition,
+ cursorStatus);
+ break;
+ } else if (!checkAttr(input->chars[i], CTC_NumericMode, 0, table))
+ break;
+ }
+ }
+ }
+
+ /* in numeric mode */
+ else {
+ if (!checkAttr(input->chars[pos],
+ CTC_Digit | CTC_LitDigit | CTC_NumericMode | CTC_MidEndNumericMode, 0,
+ table)) {
+ *numericMode = 0;
+ if (brailleIndicatorDefined(table->noContractSign, table, &indicRule))
+ if (checkAttr(input->chars[pos], CTC_NumericNoContract, 0, table))
+ for_updatePositions(&indicRule->charsdots[0], 0, indicRule->dotslen,
+ 0, pos, input, output, posMapping, cursorPosition,
+ cursorStatus);
+ }
+ }
+}
+
+static int
+translateString(const TranslationTableHeader *table,
+ const DisplayTableHeader *displayTable, int mode, int currentPass,
+ const InString *input, OutString *output, int *posMapping, formtype *typebuf,
+ unsigned char *srcSpacing, unsigned char *destSpacing, unsigned int *wordBuffer,
+ EmphasisInfo *emphasisBuffer, int haveEmphasis, int *realInlen,
+ int *cursorPosition, int *cursorStatus, int compbrlStart, int compbrlEnd) {
+ int pos;
+ int transOpcode;
+ int prevTransOpcode;
+ const TranslationTableRule *transRule;
+ int transCharslen;
+ int passCharDots;
+ const widechar *passInstructions;
+ int passIC; /* Instruction counter */
+ PassRuleMatch patternMatch;
+ TranslationTableRule *groupingRule;
+ widechar groupingOp;
+ int numericMode;
+ int dontContract;
+ LastWord lastWord;
+ int insertEmphasesFrom;
+ TranslationTableCharacter *curCharDef;
+ const widechar *repwordStart;
+ int repwordLength;
+ int curType;
+ int prevType;
+ int prevTypeform;
+ int prevPos;
+ const InString *origInput = input;
+ /* Main translation routine */
+ int k;
+ translation_direction = 1;
+ markSyllables(table, input, typebuf, &transOpcode, &transRule, &transCharslen);
+ numericMode = 0;
+ lastWord = (LastWord){ 0, 0, 0 };
+ dontContract = 0;
+ prevTransOpcode = CTO_None;
+ prevType = curType = prevTypeform = plain_text;
+ prevPos = -1;
+ pos = output->length = 0;
+ int posIncremented = 1;
+ insertEmphasesFrom = 0;
+ _lou_resetPassVariables();
+ if (typebuf && capsletterDefined(table))
+ for (k = 0; k < input->length; k++)
+ if (checkAttr(input->chars[k], CTC_UpperCase, 0, table))
+ typebuf[k] |= CAPSEMPH;
+
+ markEmphases(table, input, typebuf, wordBuffer, emphasisBuffer, haveEmphasis);
+
+ while (pos < input->length) { /* the main translation loop */
+ if ((pos >= compbrlStart) && (pos < compbrlEnd)) {
+ int cs = 2; // cursor status for this call
+ if (!doCompTrans(pos, compbrlEnd, table, displayTable, &pos, input, output,
+ posMapping, emphasisBuffer, &transRule, cursorPosition, &cs,
+ mode))
+ goto failure;
+ continue;
+ }
+ TranslationTableCharacterAttributes beforeAttributes;
+ setBefore(table, pos, input, &beforeAttributes);
+ if (!insertBrailleIndicators(0, table, pos, input, output, posMapping, typebuf,
+ haveEmphasis, transOpcode, prevTransOpcode, cursorPosition,
+ cursorStatus, beforeAttributes, &prevType, &curType, &prevTypeform,
+ prevPos))
+ goto failure;
+ if (pos >= input->length) break;
+
+ // insertEmphases();
+ if (!dontContract) dontContract = typebuf[pos] & no_contract;
+ if (typebuf[pos] & no_translate) {
+ widechar c = _lou_getDotsForChar(input->chars[pos], displayTable);
+ if (input->chars[pos] < 32 || input->chars[pos] > 126) goto failure;
+ if (!for_updatePositions(&c, 1, 1, 0, pos, input, output, posMapping,
+ cursorPosition, cursorStatus))
+ goto failure;
+ pos++;
+ posIncremented = 1;
+ insertEmphasesFrom = pos;
+ continue;
+ }
+ for_selectRule(table, pos, *output, mode, input, typebuf, emphasisBuffer,
+ &transOpcode, prevTransOpcode, &transRule, &transCharslen, &passCharDots,
+ &passInstructions, &passIC, &patternMatch, posIncremented,
+ *cursorPosition, &repwordStart, &repwordLength, dontContract,
+ compbrlStart, compbrlEnd, beforeAttributes, &curCharDef, &groupingRule,
+ &groupingOp);
+
+ if (transOpcode != CTO_Context)
+ if (appliedRules != NULL && appliedRulesCount < maxAppliedRules)
+ appliedRules[appliedRulesCount++] = transRule;
+ prevPos = pos;
+ switch (transOpcode) /* Rules that pre-empt context and swap */
+ {
+ case CTO_CompBrl:
+ case CTO_Literal:
+ if (!doCompbrl(table, displayTable, &pos, input, output, posMapping,
+ emphasisBuffer, &transRule, cursorPosition, cursorStatus,
+ &lastWord, &insertEmphasesFrom, mode))
+ goto failure;
+ continue;
+ default:
+ break;
+ }
+ if (!insertBrailleIndicators(1, table, pos, input, output, posMapping, typebuf,
+ haveEmphasis, transOpcode, prevTransOpcode, cursorPosition,
+ cursorStatus, beforeAttributes, &prevType, &curType, &prevTypeform,
+ prevPos))
+ goto failure;
+
+ // if(transOpcode == CTO_Contraction)
+ // if(brailleIndicatorDefined(table->noContractSign))
+ // if(!for_updatePositions(
+ // &indicRule->charsdots[0], 0, indicRule->dotslen, 0))
+ // goto failure;
+ insertEmphases(table, insertEmphasesFrom, pos, input, output, posMapping,
+ emphasisBuffer, haveEmphasis, transOpcode, cursorPosition, cursorStatus);
+ insertEmphasesFrom = pos + 1;
+ if (table->usesNumericMode)
+ checkNumericMode(table, pos, input, output, posMapping, cursorPosition,
+ cursorStatus, &dontContract, &numericMode);
+
+ if (transOpcode == CTO_Context ||
+ (posIncremented &&
+ findForPassRule(table, pos, currentPass, input, &transOpcode,
+ &transRule, &transCharslen, &passCharDots,
+ &passInstructions, &passIC, &patternMatch, &groupingRule,
+ &groupingOp))) {
+ posIncremented = 1;
+ switch (transOpcode) {
+ case CTO_Context: {
+ const InString *inputBefore = input;
+ int posBefore = pos;
+ if (appliedRules != NULL && appliedRulesCount < maxAppliedRules)
+ appliedRules[appliedRulesCount++] = transRule;
+ if (!passDoAction(table, displayTable, &input, output, posMapping,
+ transOpcode, &transRule, passCharDots, passInstructions,
+ passIC, &pos, patternMatch, cursorPosition, cursorStatus,
+ groupingRule, groupingOp, mode))
+ goto failure;
+ if (input->bufferIndex != inputBefore->bufferIndex &&
+ inputBefore->bufferIndex != origInput->bufferIndex)
+ releaseStringBuffer(inputBefore->bufferIndex);
+ if (pos == posBefore) posIncremented = 0;
+ continue;
+ }
+ default:
+ break;
+ }
+ } else
+ posIncremented = 1;
+
+ /* Processing before replacement */
+
+ /* check if leaving no contraction (grade 1) mode */
+ if (checkAttr(input->chars[pos], CTC_SeqDelimiter | CTC_Space, 0, table))
+ dontContract = 0;
+
+ switch (transOpcode) {
+ case CTO_EndNum:
+ if (table->letterSign && checkAttr(input->chars[pos], CTC_Letter, 0, table))
+ output->length--;
+ break;
+ case CTO_Repeated:
+ case CTO_Space:
+ dontContract = 0;
+ break;
+ case CTO_LargeSign:
+ if (prevTransOpcode == CTO_LargeSign) {
+ int hasEndSegment = 0;
+ while (output->length > 0 &&
+ checkAttr(
+ output->chars[output->length - 1], CTC_Space, 1, table)) {
+ if (output->chars[output->length - 1] == LOU_ENDSEGMENT) {
+ hasEndSegment = 1;
+ }
+ output->length--;
+ }
+ if (hasEndSegment != 0) {
+ output->chars[output->length] = 0xffff;
+ output->length++;
+ }
+ }
+ break;
+ case CTO_DecPoint:
+ if (!table->usesNumericMode && table->numberSign) {
+ TranslationTableRule *numRule =
+ (TranslationTableRule *)&table->ruleArea[table->numberSign];
+ if (!for_updatePositions(&numRule->charsdots[numRule->charslen],
+ numRule->charslen, numRule->dotslen, 0, pos, input, output,
+ posMapping, cursorPosition, cursorStatus))
+ goto failure;
+ }
+ transOpcode = CTO_MidNum;
+ break;
+ case CTO_NoCont:
+ if (!dontContract)
+ doNocont(table, &pos, output, mode, input, &lastWord, &dontContract,
+ &insertEmphasesFrom);
+ continue;
+ default:
+ break;
+ } /* end of action */
+
+ /* replacement processing */
+ switch (transOpcode) {
+ case CTO_Replace:
+ pos += transCharslen;
+ if (!putCharacters(&transRule->charsdots[transCharslen], transRule->dotslen,
+ table, displayTable, pos, input, output, posMapping,
+ cursorPosition, cursorStatus, mode))
+ goto failure;
+ break;
+ case CTO_None:
+ if (!undefinedCharacter(input->chars[pos], table, displayTable, pos, input,
+ output, posMapping, cursorPosition, cursorStatus, mode))
+ goto failure;
+ pos++;
+ break;
+ case CTO_UpperCase:
+ /* Only needs special handling if not within compbrl and
+ * the table defines a capital sign. */
+ if (!(mode & (compbrlAtCursor | compbrlLeftCursor)) &&
+ (transRule->dotslen == 1 && capsletterDefined(table))) {
+ if (!putCharacter(curCharDef->lowercase, table, displayTable, pos, input,
+ output, posMapping, cursorPosition, cursorStatus, mode))
+ goto failure;
+ pos++;
+ break;
+ }
+ // case CTO_Contraction:
+ //
+ // if(brailleIndicatorDefined(table->noContractSign))
+ // if(!for_updatePositions(
+ // &indicRule->charsdots[0], 0, indicRule->dotslen, 0))
+ // goto failure;
+
+ default:
+ if (transRule->dotslen) {
+ if (!for_updatePositions(&transRule->charsdots[transCharslen],
+ transCharslen, transRule->dotslen, 0, pos, input, output,
+ posMapping, cursorPosition, cursorStatus))
+ goto failure;
+ pos += transCharslen;
+ } else {
+ for (k = 0; k < transCharslen; k++) {
+ if (!putCharacter(input->chars[pos], table, displayTable, pos, input,
+ output, posMapping, cursorPosition, cursorStatus, mode))
+ goto failure;
+ pos++;
+ }
+ }
+ break;
+ }
+
+ /* processing after replacement */
+ switch (transOpcode) {
+ case CTO_Repeated: {
+ /* Skip repeated characters. */
+ int srclim = input->length - transCharslen;
+ if (mode & (compbrlAtCursor | compbrlLeftCursor) && compbrlStart < srclim)
+ /* Don't skip characters from compbrlStart onwards. */
+ srclim = compbrlStart - 1;
+ while ((pos <= srclim) &&
+ compareChars(&transRule->charsdots[0], &input->chars[pos],
+ transCharslen, 0, table)) {
+ /* Map skipped input positions to the previous output position. */
+ /* if (posMapping.outputPositions != NULL) { */
+ /* int tcc; */
+ /* for (tcc = 0; tcc < transCharslen; tcc++) */
+ /* posMapping.outputPositions[posMapping.prev[pos + tcc]] = */
+ /* output->length - 1; */
+ /* } */
+ if (!*cursorStatus && pos <= *cursorPosition &&
+ *cursorPosition < pos + transCharslen) {
+ *cursorStatus = 1;
+ *cursorPosition = output->length - 1;
+ }
+ pos += transCharslen;
+ }
+ break;
+ }
+ case CTO_RepWord: {
+ /* Skip repeated characters. */
+ int srclim = input->length - transCharslen;
+ if (mode & (compbrlAtCursor | compbrlLeftCursor) && compbrlStart < srclim)
+ /* Don't skip characters from compbrlStart onwards. */
+ srclim = compbrlStart - 1;
+ while ((pos <= srclim) &&
+ compareChars(
+ repwordStart, &input->chars[pos], repwordLength, 0, table)) {
+ /* Map skipped input positions to the previous output position. */
+ /* if (posMapping.outputPositions != NULL) { */
+ /* int tcc; */
+ /* for (tcc = 0; tcc < transCharslen; tcc++) */
+ /* posMapping.outputPositions[posMapping.prev[pos + tcc]] = */
+ /* output->length - 1; */
+ /* } */
+ if (!*cursorStatus && pos <= *cursorPosition &&
+ *cursorPosition < pos + transCharslen) {
+ *cursorStatus = 1;
+ *cursorPosition = output->length - 1;
+ }
+ pos += repwordLength + transCharslen;
+ }
+ pos -= transCharslen;
+ break;
+ }
+ case CTO_JoinNum:
+ case CTO_JoinableWord:
+ while (pos < input->length &&
+ checkAttr(input->chars[pos], CTC_Space, 0, table) &&
+ input->chars[pos] != LOU_ENDSEGMENT)
+ pos++;
+ break;
+ default:
+ break;
+ }
+ if (((pos > 0) && checkAttr(input->chars[pos - 1], CTC_Space, 0, table) &&
+ (transOpcode != CTO_JoinableWord))) {
+ lastWord = (LastWord){ pos, output->length, insertEmphasesFrom };
+ }
+ if (srcSpacing != NULL && srcSpacing[pos] >= '0' && srcSpacing[pos] <= '9')
+ destSpacing[output->length] = srcSpacing[pos];
+ if ((transOpcode >= CTO_Always && transOpcode <= CTO_None) ||
+ (transOpcode >= CTO_Digit && transOpcode <= CTO_LitDigit))
+ prevTransOpcode = transOpcode;
+ }
+
+ transOpcode = CTO_Space;
+ insertEmphases(table, insertEmphasesFrom, pos, input, output, posMapping,
+ emphasisBuffer, haveEmphasis, transOpcode, cursorPosition, cursorStatus);
+
+failure:
+ if (lastWord.outPos != 0 && pos < input->length &&
+ !checkAttr(input->chars[pos], CTC_Space, 0, table)) {
+ pos = lastWord.inPos;
+ output->length = lastWord.outPos;
+ }
+ if (pos < input->length) {
+ while (checkAttr(input->chars[pos], CTC_Space, 0, table))
+ if (++pos == input->length) break;
+ }
+ *realInlen = pos;
+ if (input->bufferIndex != origInput->bufferIndex)
+ releaseStringBuffer(input->bufferIndex);
+ return 1;
+} /* first pass translation completed */
+
+static int
+isHyphen(const TranslationTableHeader *table, widechar c) {
+ TranslationTableRule *rule;
+ TranslationTableOffset offset = findCharOrDots(c, 0, table)->otherRules;
+ while (offset) {
+ rule = (TranslationTableRule *)&table->ruleArea[offset];
+ if (rule->opcode == CTO_Hyphen) return 1;
+ offset = rule->dotsnext;
+ }
+ return 0;
+}
+
+/**
+ * Hyphenate an input string which can either be text (mode = 0) or braille (mode = 1). If
+ * the input is braille, back-translation will be performed with `tableList'. The input
+ * string can contain any character (even space), but only break points within words
+ * (between letters) are considered. If the string can not be broken before the character
+ * at index k, the value of `hyphens[k]' is '0'. If it can be broken by inserting a hyphen
+ * at the break point, the value is '1'. If it can be broken without adding a hyphen, the
+ * value is '2'.
+ */
+int EXPORT_CALL
+lou_hyphenate(const char *tableList, const widechar *inbuf, int inlen, char *hyphens,
+ int mode) {
+#define HYPHSTRING 100
+ const TranslationTableHeader *table;
+ widechar textBuffer[HYPHSTRING];
+ char *textHyphens;
+ int *inputPos;
+ int k;
+ int textLen;
+ int wordStart;
+ table = lou_getTable(tableList);
+ if (table == NULL || inbuf == NULL || hyphens == NULL ||
+ table->hyphenStatesArray == 0 || inlen >= HYPHSTRING)
+ return 0;
+ if (mode != 0) {
+ int brailleLen = inlen;
+ textLen = HYPHSTRING;
+ inputPos = malloc(textLen * sizeof(int));
+ if (!lou_backTranslate(tableList, inbuf, &brailleLen, textBuffer, &textLen, NULL,
+ NULL, NULL, inputPos, NULL, 0)) {
+ free(inputPos);
+ return 0;
+ }
+ textHyphens = malloc((textLen + 1) * sizeof(char));
+ } else {
+ memcpy(textBuffer, inbuf, CHARSIZE * inlen);
+ textLen = inlen;
+ textHyphens = hyphens;
+ }
+
+ // initialize hyphens array
+ for (k = 0; k < textLen; k++) textHyphens[k] = '0';
+ textHyphens[k] = 0;
+
+ // for every word part
+ for (wordStart = 0;;) {
+ int wordEnd;
+ // find start of word
+ for (; wordStart < textLen; wordStart++)
+ if ((findCharOrDots(textBuffer[wordStart], 0, table))->attributes &
+ CTC_Letter)
+ break;
+ if (wordStart == textLen) break;
+ // find end of word
+ for (wordEnd = wordStart + 1; wordEnd < textLen; wordEnd++)
+ if (!((findCharOrDots(textBuffer[wordEnd], 0, table))->attributes &
+ CTC_Letter))
+ break;
+ // hyphenate
+ if (!hyphenateWord(&textBuffer[wordStart], wordEnd - wordStart,
+ &textHyphens[wordStart], table))
+ return 0;
+ // normalize to '0', '1' or '2'
+ if (wordStart >= 2 && isHyphen(table, textBuffer[wordStart - 1]) &&
+ ((findCharOrDots(textBuffer[wordStart - 2], 0, table))->attributes &
+ CTC_Letter))
+ textHyphens[wordStart] = '2';
+ else
+ textHyphens[wordStart] = '0';
+ for (k = wordStart + 1; k < wordEnd; k++)
+ if (textHyphens[k] & 1)
+ textHyphens[k] = '1';
+ else
+ textHyphens[k] = '0';
+ if (wordEnd == textLen) break;
+ textHyphens[wordEnd] = '0'; // because hyphenateWord sets it to 0
+ wordStart = wordEnd + 1;
+ }
+
+ // map hyphen positions if the input was braille
+ if (mode != 0) {
+ for (k = 0; k < inlen; k++) hyphens[k] = '0';
+ hyphens[k] = 0;
+ int prevPos = -1;
+ for (k = 0; k < textLen; k++) {
+ int braillePos = inputPos[k];
+ if (braillePos > inlen || braillePos < 0) break;
+ if (braillePos > prevPos) {
+ hyphens[braillePos] = textHyphens[k];
+ prevPos = braillePos;
+ }
+ }
+ free(textHyphens);
+ free(inputPos);
+ }
+ return 1;
+}
+
+int EXPORT_CALL
+lou_dotsToChar(
+ const char *tableList, widechar *inbuf, widechar *outbuf, int length, int mode) {
+ const DisplayTableHeader *table;
+ int k;
+ widechar dots;
+ if (tableList == NULL || inbuf == NULL || outbuf == NULL) return 0;
+
+ table = _lou_getDisplayTable(tableList);
+ if (table == NULL || length <= 0) return 0;
+ for (k = 0; k < length; k++) {
+ dots = inbuf[k];
+ if (!(dots & LOU_DOTS) &&
+ (dots & 0xff00) == LOU_ROW_BRAILLE) /* Unicode braille */
+ dots = (dots & 0x00ff) | LOU_DOTS;
+ outbuf[k] = _lou_getCharFromDots(dots, table);
+ // assume that if NUL character is returned, it's because the display table has no
+ // mapping for the dot pattern (not because it maps to NUL)
+ if (outbuf[k] == '\0') outbuf[k] = ' ';
+ }
+ return 1;
+}
+
+int EXPORT_CALL
+lou_charToDots(const char *tableList, const widechar *inbuf, widechar *outbuf, int length,
+ int mode) {
+ const DisplayTableHeader *table;
+ int k;
+ if (tableList == NULL || inbuf == NULL || outbuf == NULL) return 0;
+
+ table = _lou_getDisplayTable(tableList);
+ if (table == NULL || length <= 0) return 0;
+ for (k = 0; k < length; k++)
+ if ((mode & ucBrl))
+ outbuf[k] = ((_lou_getDotsForChar(inbuf[k], table) & 0xff) | LOU_ROW_BRAILLE);
+ else
+ outbuf[k] = _lou_getDotsForChar(inbuf[k], table);
+ return 1;
+}
diff --git a/liblouis/maketable.c b/liblouis/maketable.c
new file mode 100644
index 0000000..e1b200f
--- /dev/null
+++ b/liblouis/maketable.c
@@ -0,0 +1,458 @@
+/* liblouis Braille Translation and Back-Translation Library
+
+ Copyright (C) 2017 Bert Frees
+
+ This file is part of liblouis.
+
+ liblouis is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 2.1 of the License, or
+ (at your option) any later version.
+
+ liblouis is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "internal.h"
+
+static const TranslationTableHeader *table;
+static const DisplayTableHeader *displayTable;
+
+extern void
+loadTable(const char *tableList) {
+ _lou_getTable(tableList, tableList, &table, &displayTable);
+}
+
+extern int
+hyphenationEnabled() {
+ return table->hyphenStatesArray;
+}
+
+extern int
+isLetter(widechar c) {
+ static unsigned long int hash;
+ static TranslationTableOffset offset;
+ static TranslationTableCharacter *character;
+ hash = _lou_charHash(c);
+ offset = table->characters[hash];
+ while (offset) {
+ character = (TranslationTableCharacter *)&table->ruleArea[offset];
+ if (character->realchar == c) return character->attributes & CTC_Letter;
+ offset = character->next;
+ }
+ return 0;
+}
+
+extern widechar
+toLowercase(widechar c) {
+ static TranslationTableOffset offset;
+ static TranslationTableCharacter *character;
+ offset = table->characters[_lou_charHash(c)];
+ while (offset) {
+ character = (TranslationTableCharacter *)&table->ruleArea[offset];
+ if (character->realchar == c) return character->lowercase;
+ offset = character->next;
+ }
+ return c;
+}
+
+extern void
+toDotPattern(widechar *braille, char *pattern) {
+ int length;
+ widechar *dots;
+ int i;
+ for (length = 0; braille[length]; length++)
+ ;
+ dots = (widechar *)malloc((length + 1) * sizeof(widechar));
+ for (i = 0; i < length; i++) dots[i] = _lou_getDotsForChar(braille[i], displayTable);
+ strcpy(pattern, _lou_showDots(dots, length));
+ free(dots);
+}
+
+extern int
+printRule(TranslationTableRule *rule, widechar *rule_string) {
+ switch (rule->opcode) {
+ case CTO_Context:
+ case CTO_Correct:
+ case CTO_SwapCd:
+ case CTO_SwapDd:
+ case CTO_Pass2:
+ case CTO_Pass3:
+ case CTO_Pass4:
+ return 0;
+ default: {
+ int l = 0;
+ const char *opcode = _lou_findOpcodeName(rule->opcode);
+ for (size_t k = 0; k < strlen(opcode); k++) rule_string[l++] = opcode[k];
+ rule_string[l++] = ' ';
+ for (int k = 0; k < rule->charslen; k++) rule_string[l++] = rule->charsdots[k];
+ rule_string[l++] = ' ';
+ for (int k = 0; k < rule->dotslen; k++) {
+ rule_string[l] = _lou_getCharFromDots(
+ rule->charsdots[rule->charslen + k], displayTable);
+ if (rule_string[l] == '\0') {
+ // if a dot pattern can not be displayed, print an error message
+ char *message = (char *)malloc(50 * sizeof(char));
+ sprintf(message, "ERROR: provide a display rule for %s",
+ _lou_showDots(&rule->charsdots[rule->charslen + k], 1));
+ l = 0;
+ while (message[l]) {
+ rule_string[l] = message[l];
+ l++;
+ }
+ rule_string[l++] = '\0';
+ free(message);
+ return 1;
+ }
+ l++;
+ }
+ rule_string[l++] = '\0';
+ return 1;
+ }
+ }
+}
+
+#define DEBUG 0
+
+#if DEBUG
+#define debug(fmt, ...) \
+ do { \
+ if (DEBUG) printf("%*s" fmt "\n", debug_indent, "", ##__VA_ARGS__); \
+ } while (0)
+#else
+#define debug(fmt, ...)
+#endif
+
+static int
+find_matching_rules(widechar *text, int text_len, widechar *braille, int braille_len,
+ char *data, int clear_data) {
+ TranslationTableOffset offset;
+ TranslationTableRule *rule;
+ TranslationTableCharacter *character;
+ char *data_save;
+ int hash_len, k;
+#if DEBUG
+ static int initial_text_len = 0;
+ int debug_indent = 0;
+ if (data[-1] == '^') {
+ initial_text_len = text_len;
+ for (k = 0; k < text_len; k++) printf("%c", text[k]);
+ printf(" <=> ");
+ for (k = 0; k < braille_len; k++) printf("%c", braille[k]);
+ printf("\n");
+ } else
+ debug_indent = initial_text_len - text_len;
+#endif
+
+ /* finish */
+ if (text_len == 0 && braille_len == 0) {
+ data[-1] = '$';
+ return 1;
+ }
+
+ /* save data */
+ data_save = (char *)malloc(text_len * sizeof(char));
+ memcpy(data_save, data, text_len);
+
+ for (k = 0; k < text_len; k++)
+ if (data[k] == ')')
+ data[k] = '>';
+ else if (clear_data)
+ data[k] = '-';
+ debug("%s", data);
+
+ /* iterate over rules */
+ for (hash_len = 2; hash_len >= 1; hash_len--) {
+ offset = 0;
+ switch (hash_len) {
+ case 2:
+ if (text_len < 2) break;
+ offset = table->forRules[_lou_stringHash(text, 1, table)];
+ break;
+ case 1:
+ offset = table->characters[_lou_charHash(text[0])];
+ while (offset) {
+ character = (TranslationTableCharacter *)&table->ruleArea[offset];
+ if (character->realchar == text[0]) {
+ offset = character->otherRules;
+ break;
+ } else
+ offset = character->next;
+ }
+ }
+ while (offset) {
+ rule = (TranslationTableRule *)&table->ruleArea[offset];
+#if DEBUG
+ widechar print_string[128];
+ printRule(rule, print_string);
+ printf("%*s=> ", debug_indent, "");
+ for (k = 0; print_string[k]; k++) printf("%c", print_string[k]);
+ printf("\n");
+#endif
+
+ /* select rule */
+ if (rule->charslen == 0 || rule->dotslen == 0) goto next_rule;
+ if (rule->charslen > text_len) goto next_rule;
+ switch (rule->opcode) {
+ case CTO_WholeWord:
+ if (data[-1] == '^' && rule->charslen == text_len) break;
+ goto next_rule;
+ case CTO_SuffixableWord:
+ if (data[-1] == '^') break;
+ goto next_rule;
+ case CTO_PrefixableWord:
+ if (rule->charslen == text_len) break;
+ goto next_rule;
+ case CTO_BegWord:
+ if (data[-1] == '^' && rule->charslen < text_len) break;
+ goto next_rule;
+ case CTO_BegMidWord:
+ if (rule->charslen < text_len) break;
+ goto next_rule;
+ case CTO_MidWord:
+ if (data[-1] != '^' && rule->charslen < text_len) break;
+ goto next_rule;
+ case CTO_MidEndWord:
+ if (data[-1] != '^') break;
+ goto next_rule;
+ case CTO_EndWord:
+ if (data[-1] != '^' && rule->charslen == text_len) break;
+ goto next_rule;
+ case CTO_NoCross:
+ break;
+ case CTO_Letter:
+ case CTO_UpperCase:
+ case CTO_LowerCase:
+ case CTO_Punctuation:
+ case CTO_Always:
+ break;
+ default:
+ goto next_rule;
+ }
+ for (k = 0; k < rule->charslen; k++)
+ if (rule->charsdots[k] != text[k]) goto next_rule;
+ debug("** rule selected **");
+
+ /* inhibit rule */
+ if (rule->dotslen > braille_len ||
+ (rule->charslen == text_len && rule->dotslen < braille_len) ||
+ (rule->dotslen == braille_len && rule->charslen < text_len))
+ goto inhibit;
+ for (k = 0; k < rule->dotslen; k++)
+ if (_lou_getCharFromDots(rule->charsdots[rule->charslen + k],
+ displayTable) != braille[k])
+ goto inhibit;
+
+ /* don't let this rule be inhibited by an earlier rule */
+ int inhibit_all = 0;
+ if (rule->opcode == CTO_NoCross)
+ for (k = 0; k < rule->charslen - 1; k++)
+ if (data[k + 1] == '>') {
+ if (data[-1] == 'x')
+ inhibit_all = 1;
+ else
+ goto next_rule;
+ }
+
+ /* fill data */
+ switch (rule->opcode) {
+ case CTO_NoCross: // deferred: see success
+ break;
+ default:
+ k = 0;
+ while (k < rule->charslen - 1) {
+ if (data[k + 1] == '>') {
+ data[k++] = '1';
+ memset(&data[k], '-', text_len - k);
+ } else
+ data[k++] = 'x';
+ }
+ }
+ if (data[rule->charslen] == '>' || data[rule->charslen] == ')') {
+ data[rule->charslen - 1] = '1';
+ memset(&data[rule->charslen], '-', text_len - rule->charslen);
+ } else
+ data[rule->charslen - 1] = 'x';
+ debug("%s", data);
+
+ /* recur */
+ if (find_matching_rules(&text[rule->charslen], text_len - rule->charslen,
+ &braille[rule->dotslen], braille_len - rule->dotslen,
+ &data[rule->charslen], inhibit_all))
+ goto success;
+
+ inhibit:
+ debug("** rule inhibited **");
+ switch (rule->opcode) {
+ case CTO_NoCross:
+ if (rule->charslen < 2) goto abort;
+ /* inhibited by earlier rule */
+ for (k = 0; k < rule->charslen - 1; k++)
+ if (data[k + 1] == '>' && data[-1] != 'x') goto next_rule;
+ data[rule->charslen - 1] = ')';
+ debug("%s", data);
+ goto next_rule;
+ default:
+ goto abort;
+ }
+
+ success:
+ /* fill data (deferred) */
+ if (inhibit_all) data[-1] = '1';
+ switch (rule->opcode) {
+ case CTO_NoCross:
+ memset(data, '0', rule->charslen - 1);
+ debug("%s", data);
+ default:
+ break;
+ }
+ free(data_save);
+ return 1;
+
+ next_rule:
+ offset = rule->charsnext;
+ }
+ }
+
+abort:
+ /* restore data */
+ memcpy(data, data_save, text_len);
+ free(data_save);
+ debug("** abort **");
+ return 0;
+}
+
+/*
+ * - begin with all -
+ * - set cursor position right before the word
+ * - put a ^
+ * - match rules
+ * - when a rule has been selected
+ * - if the braille does not match: try inhibiting the rule
+ * - if it's a nocross rule (longer than a single character)
+ * - if there's a > within or right after the rule and there's no x right before
+ * the rule
+ * - already inhibited
+ * - else: put a ) at the position right after the rule
+ * - else: abort this match
+ * - else (the braille does match)
+ * - if it's a nocross rule
+ * - if there's a > within or right after the rule
+ * - if there's a x at the position right before the rule
+ * - put a 1 at that position
+ * - reset all >
+ * - else
+ * - continue with next matched rule
+ * - put a 0 at each position within the rule
+ * - else
+ * - for each position within the rule
+ * - if there's a > at the next position
+ * - put a 1
+ * - reset all >
+ * - else put a x
+ * - move cursor to the position right after the rule
+ * - put a $ if we're at the end of the word
+ * - change all ) to >
+ * - else if there's a > or a ) at the next position
+ * - put a 1
+ * - reset all >
+ * - match rules at the new cursor position
+ * - if match was aborted
+ * - revert changes
+ * - try inhibiting the last rule
+ * - go back to the position before the rule
+ * - continue with next matched rule
+ * - else put a x
+ */
+extern int
+suggestChunks(widechar *text, widechar *braille, char *hyphen_string) {
+ int text_len, braille_len;
+ for (text_len = 0; text[text_len]; text_len++)
+ ;
+ for (braille_len = 0; braille[braille_len]; braille_len++)
+ ;
+ if (text_len == 0 || braille_len == 0) return 0;
+ hyphen_string[0] = '^';
+ hyphen_string[text_len + 1] = '\0';
+ memset(&hyphen_string[1], '-', text_len);
+ return find_matching_rules(
+ text, text_len, braille, braille_len, &hyphen_string[1], 0);
+}
+
+extern void
+findRelevantRules(widechar *text, widechar **rules_str) {
+ int text_len, rules_len;
+ TranslationTableOffset offset;
+ TranslationTableCharacter *character;
+ TranslationTableRule *rule;
+ TranslationTableRule **rules;
+ int hash_len, k, m, n;
+ for (text_len = 0; text[text_len]; text_len++)
+ ;
+ for (rules_len = 0; rules_str[rules_len]; rules_len++)
+ ;
+ rules = (TranslationTableRule **)malloc(
+ (rules_len + 1) * sizeof(TranslationTableRule *));
+ m = n = 0;
+ while (text[n]) {
+ for (hash_len = 2; hash_len >= 1; hash_len--) {
+ offset = 0;
+ switch (hash_len) {
+ case 2:
+ if (text_len - n < 2) break;
+ offset = table->forRules[_lou_stringHash(&text[n], 1, table)];
+ break;
+ case 1:
+ offset = table->characters[_lou_charHash(text[n])];
+ while (offset) {
+ character = (TranslationTableCharacter *)&table->ruleArea[offset];
+ if (character->realchar == text[0]) {
+ offset = character->otherRules;
+ break;
+ } else
+ offset = character->next;
+ }
+ }
+ while (offset) {
+ rule = (TranslationTableRule *)&table->ruleArea[offset];
+ switch (rule->opcode) {
+ case CTO_Always:
+ case CTO_WholeWord:
+ case CTO_SuffixableWord:
+ case CTO_PrefixableWord:
+ case CTO_BegWord:
+ case CTO_BegMidWord:
+ case CTO_MidWord:
+ case CTO_MidEndWord:
+ case CTO_EndWord:
+ case CTO_NoCross:
+ break;
+ default:
+ goto next_rule;
+ }
+ if (rule->charslen == 0 || rule->dotslen == 0 ||
+ rule->charslen > text_len - n)
+ goto next_rule;
+ for (k = 0; k < rule->charslen; k++)
+ if (rule->charsdots[k] != text[n + k]) goto next_rule;
+ rules[m++] = rule;
+ if (m == rules_len) goto finish;
+ next_rule:
+ offset = rule->charsnext;
+ }
+ }
+ n++;
+ }
+finish:
+ rules_str[m--] = NULL;
+ for (; m >= 0; m--) printRule(rules[m], rules_str[m]);
+ free(rules);
+}
diff --git a/liblouis/metadata.c b/liblouis/metadata.c
new file mode 100644
index 0000000..0af6554
--- /dev/null
+++ b/liblouis/metadata.c
@@ -0,0 +1,721 @@
+/* liblouis Braille Translation and Back-Translation Library
+
+ Copyright (C) 2015 Bert Frees <bertfrees@gmail.com>
+
+ This file is part of liblouis.
+
+ liblouis is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 2.1 of the License, or
+ (at your option) any later version.
+
+ liblouis is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file
+ * @brief Find translation tables
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#ifdef _MSC_VER
+#include <windows.h>
+#else
+#include <dirent.h>
+#endif
+#include <sys/stat.h>
+#include "internal.h"
+#include "config.h"
+
+/* =============================== LIST =================================== */
+
+typedef struct List {
+ void *head;
+ void (*free)(void *);
+ struct List *tail;
+} List;
+
+/**
+ * Returns a list with the element `x' added to `list'. Returns a sorted list
+ * if `cmp' is not NULL and if `list' is also sorted. New elements replace
+ * existing ones if they are equal according to `cmp'. If `cmp' is NULL,
+ * elements are simply prepended to the list. The function `dup' is used to
+ * duplicate elements before they are added to the list. The `free' function
+ * is used to free elements when they are removed from the list. The returned
+ * list must be freed by the caller.
+ */
+static List *
+list_conj(List *list, void *x, int (*cmp)(void *, void *), void *(*dup)(void *),
+ void (*free)(void *)) {
+ if (!list) {
+ list = malloc(sizeof(List));
+ list->head = dup ? dup(x) : x;
+ list->free = free;
+ list->tail = NULL;
+ return list;
+ } else if (!cmp) {
+ List *l = malloc(sizeof(List));
+ l->head = dup ? dup(x) : x;
+ l->free = free;
+ l->tail = list;
+ return l;
+ } else {
+ List *l1 = list;
+ List *l2 = NULL;
+ while (l1) {
+ int c = cmp(l1->head, x);
+ if (c > 0)
+ break;
+ else if (c < 0) {
+ l2 = l1;
+ l1 = l2->tail;
+ } else {
+ if (x != l1->head && !dup && free) free(x);
+ return list;
+ }
+ }
+ List *l3 = malloc(sizeof(List));
+ l3->head = dup ? dup(x) : x;
+ l3->free = free;
+ l3->tail = l1;
+ if (!l2)
+ list = l3;
+ else
+ l2->tail = l3;
+ return list;
+ }
+}
+
+/**
+ * Free an instance of type List.
+ */
+static void
+list_free(List *list) {
+ if (list) {
+ if (list->free) list->free(list->head);
+ list_free(list->tail);
+ free(list);
+ }
+}
+
+/**
+ * Sort a list based on a comparison function.
+ */
+static List *
+list_sort(List *list, int (*cmp)(void *, void *)) {
+ List *newList = NULL;
+ List *l;
+ for (l = list; l; l = l->tail) {
+ newList = list_conj(newList, l->head, cmp, NULL, l->free);
+ l->free = NULL;
+ }
+ list_free(list);
+ return newList;
+}
+
+/**
+ * Get the size of a list.
+ */
+static int
+list_size(List *list) {
+ int len = 0;
+ List *l;
+ for (l = list; l; l = l->tail) len++;
+ return len;
+}
+
+/**
+ * Convert a list into a NULL terminated array.
+ */
+static void **
+list_toArray(List *list, void *(*dup)(void *)) {
+ void **array;
+ List *l;
+ int i;
+ array = malloc((1 + list_size(list)) * sizeof(void *));
+ i = 0;
+ for (l = list; l; l = l->tail) array[i++] = dup ? dup(l->head) : l->head;
+ array[i] = NULL;
+ return array;
+}
+
+/* ============================== FEATURE ================================= */
+
+typedef struct {
+ char *key;
+ char *val;
+} Feature;
+
+typedef struct {
+ Feature feature;
+ int importance;
+} FeatureWithImportance;
+
+typedef struct {
+ char *name;
+ List *features;
+} TableMeta;
+
+/**
+ * Create an instance of type Feature.
+ * The `key' and `val' strings are duplicated. Leaving out the `val'
+ * argument results in a value of "yes".
+ */
+static Feature
+feature_new(const char *key, const char *val) {
+ static const char *YES = "yes";
+ Feature f;
+ f.key = strdup(key);
+ f.val = strdup(val ? val : YES);
+ return f;
+}
+
+/**
+ * Free an instance of type Feature
+ */
+static void
+feature_free(Feature *f) {
+ if (f) {
+ free(f->key);
+ free(f->val);
+ free(f);
+ }
+}
+
+/* ======================================================================== */
+
+/**
+ * Sort features based on their keys.
+ */
+static int
+cmpKeys(Feature *f1, Feature *f2) {
+ return strcasecmp(f1->key, f2->key);
+}
+
+/**
+ * Compute the match quotient of the features in a query against the features in a table's
+ * metadata.
+ *
+ * The features are assumed to be sorted and to have no duplicate
+ * keys. The query's features must be of type FeatureWithImportance.
+ * How a feature contributes to the match quotient depends on its
+ * importance, on whether the feature is undefined, defined with the
+ * same value (positive match), or defined with a different value
+ * (negative match), and on the `fuzzy' argument. If the `fuzzy'
+ * argument evaluates to true, negative matches and undefined features
+ * get a lower penalty.
+ */
+static int
+matchFeatureLists(const List *query, const List *tableFeatures, int fuzzy) {
+ static const int POS_MATCH = 10;
+ static const int NEG_MATCH = -100;
+ static const int UNDEFINED = -20;
+ static const int EXTRA = -1;
+ static const int POS_MATCH_FUZZY = 10;
+ static const int NEG_MATCH_FUZZY = -25;
+ static const int UNDEFINED_FUZZY = -5;
+ static const int EXTRA_FUZZY = -1;
+ int posMatch, negMatch, undefined, extra;
+ if (!fuzzy) {
+ posMatch = POS_MATCH;
+ negMatch = NEG_MATCH;
+ undefined = UNDEFINED;
+ extra = EXTRA;
+ } else {
+ posMatch = POS_MATCH_FUZZY;
+ negMatch = NEG_MATCH_FUZZY;
+ undefined = UNDEFINED_FUZZY;
+ extra = EXTRA_FUZZY;
+ }
+ int quotient = 0;
+ const List *l1 = query;
+ const List *l2 = tableFeatures;
+ while (1) {
+ if (!l1) {
+ if (!l2) break;
+ quotient += extra;
+ l2 = l2->tail;
+ } else if (!l2) {
+ quotient += undefined;
+ l1 = l1->tail;
+ } else {
+ int cmp = cmpKeys(l1->head, l2->head);
+ if (cmp < 0) {
+ quotient += undefined;
+ l1 = l1->tail;
+ } else if (cmp > 0) {
+ quotient += extra;
+ l2 = l2->tail;
+ } else {
+ if (strcasecmp(((Feature *)l1->head)->val, ((Feature *)l2->head)->val) ==
+ 0)
+ quotient += posMatch;
+ else
+ quotient += negMatch;
+ l1 = l1->tail;
+ l2 = l2->tail;
+ }
+ }
+ }
+ return quotient;
+}
+
+/**
+ * Return true if a character matches [0-9A-Za-z_-\.]
+ */
+static int
+isValidChar(char c) {
+ return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
+ c == '-' || c == '.' || c == '_';
+}
+
+/**
+ * Return true if a character matches [\s\t]
+ */
+static int
+isSpace(char c) {
+ return c == ' ' || c == '\t';
+}
+
+/**
+ * Parse a table query into a list of features. Features defined first get a
+ * higher importance.
+ */
+static List *
+parseQuery(const char *query) {
+ List *features = NULL;
+ const char *key = NULL;
+ const char *val = NULL;
+ size_t keySize = 0;
+ size_t valSize = 0;
+ const char *c;
+ int pos = 0;
+ while (1) {
+ c = &query[pos++];
+ if (isSpace(*c) || (*c == '\n') | (*c == '\0')) {
+ if (key) {
+ char *k = malloc(keySize + 1);
+ k[keySize] = '\0';
+ memcpy(k, key, keySize);
+ char *v = NULL;
+ if (val) {
+ v = malloc(valSize + 1);
+ v[valSize] = '\0';
+ memcpy(v, val, valSize);
+ }
+ FeatureWithImportance f = { feature_new(k, v), 0 };
+ _lou_logMessage(LOU_LOG_DEBUG, "Query has feature '%s:%s'", f.feature.key,
+ f.feature.val);
+ features = list_conj(features, memcpy(malloc(sizeof(f)), &f, sizeof(f)),
+ NULL, NULL, (void (*)(void *))feature_free);
+ free(k);
+ free(v);
+ key = val = NULL;
+ keySize = valSize = 0;
+ }
+ if (*c == '\0') break;
+ } else if (*c == ':') {
+ if (!key || val)
+ goto compile_error;
+ else {
+ c = &query[pos++];
+ if (isValidChar(*c)) {
+ val = c;
+ valSize = 1;
+ } else
+ goto compile_error;
+ }
+ } else if (isValidChar(*c)) {
+ if (val)
+ valSize++;
+ else if (key)
+ keySize++;
+ else {
+ key = c;
+ keySize = 1;
+ }
+ } else
+ goto compile_error;
+ }
+
+ {
+ int k = 1;
+ List *l;
+
+ for (l = features; l; l = l->tail) {
+ FeatureWithImportance *f = l->head;
+ f->importance = k++;
+ }
+ }
+ return list_sort(features, (int (*)(void *, void *))cmpKeys);
+compile_error:
+ _lou_logMessage(LOU_LOG_ERROR, "Unexpected character '%c' at position %d", c, pos);
+ list_free(features);
+ return NULL;
+}
+
+/**
+ * Convert a widechar string to a normal string.
+ */
+static char *
+widestrToStr(const widechar *str, size_t n) {
+ char *result = malloc((1 + n) * sizeof(char));
+ size_t k;
+ for (k = 0; k < n; k++) result[k] = (char)str[k];
+ result[k] = '\0';
+ return result;
+}
+
+/**
+ * Extract a list of features from a table.
+ */
+static List *
+analyzeTable(const char *table, int activeOnly) {
+ static char fileName[MAXSTRING];
+ List *features = NULL;
+ FileInfo info;
+
+ {
+ char **resolved = _lou_resolveTable(table, NULL);
+
+ if (resolved == NULL) {
+ _lou_logMessage(LOU_LOG_ERROR, "Cannot resolve table '%s'", table);
+ return NULL;
+ }
+
+ sprintf(fileName, "%s", *resolved);
+ int k = 0;
+
+ for (k = 0; resolved[k]; k += 1) free(resolved[k]);
+ free(resolved);
+
+ if (k > 1) {
+ _lou_logMessage(
+ LOU_LOG_ERROR, "Table '%s' resolves to more than one file", table);
+ return NULL;
+ }
+ }
+
+ info.fileName = fileName;
+ info.encoding = noEncoding;
+ info.status = 0;
+ info.lineNumber = 0;
+ if ((info.in = fopen(info.fileName, "rb"))) {
+ while (_lou_getALine(&info)) {
+ if (info.linelen == 0)
+ ;
+ else if (info.line[0] == '#') {
+ if (info.linelen >= 2 &&
+ (info.line[1] == '+' ||
+ (!activeOnly && info.line[1] == '-' &&
+ !(info.linelen > 2 && info.line[2] == '-')))) {
+ int active = (info.line[1] == '+');
+ widechar *key = NULL;
+ widechar *val = NULL;
+ size_t keySize = 0;
+ size_t valSize = 0;
+ info.linepos = 2;
+ if (info.linepos < info.linelen &&
+ isValidChar((char)info.line[info.linepos])) {
+ key = &info.line[info.linepos];
+ keySize = 1;
+ info.linepos++;
+ while (info.linepos < info.linelen &&
+ isValidChar((char)info.line[info.linepos])) {
+ keySize++;
+ info.linepos++;
+ }
+ if (info.linepos < info.linelen &&
+ info.line[info.linepos] == ':') {
+ info.linepos++;
+ while (info.linepos < info.linelen &&
+ isSpace((char)info.line[info.linepos]))
+ info.linepos++;
+ if (info.linepos < info.linelen &&
+ (!active ||
+ isValidChar((char)info.line[info.linepos]))) {
+ val = &info.line[info.linepos];
+ valSize = 1;
+ info.linepos++;
+ while (info.linepos < info.linelen &&
+ (!active ||
+ isValidChar(
+ (char)info.line[info.linepos]))) {
+ valSize++;
+ info.linepos++;
+ }
+ } else
+ goto compile_error;
+ }
+ if (info.linepos == info.linelen) {
+ char *k = widestrToStr(key, keySize);
+ char *v = val ? widestrToStr(val, valSize) : NULL;
+ if (!active) {
+ if (!v) goto compile_error;
+ // normalize space
+ int i = 0;
+ int j = 0;
+ int space = 1;
+ while (v[i]) {
+ if (isSpace(v[i])) {
+ if (!space) {
+ v[j++] = ' ';
+ space = 1;
+ }
+ } else {
+ v[j++] = v[i];
+ space = 0;
+ }
+ i++;
+ }
+ if (j > 0 && v[j - 1] == ' ') j--;
+ v[j] = '\0';
+ }
+ Feature f = feature_new(k, v);
+ _lou_logMessage(LOU_LOG_DEBUG, "Table has feature '%s:%s'",
+ f.key, f.val);
+ features = list_conj(features,
+ memcpy(malloc(sizeof(f)), &f, sizeof(f)), NULL, NULL,
+ (void (*)(void *))feature_free);
+ free(k);
+ free(v);
+ } else
+ goto compile_error;
+ } else
+ goto compile_error;
+ }
+ } else
+ break;
+ }
+ fclose(info.in);
+ } else
+ _lou_logMessage(LOU_LOG_ERROR, "Cannot open table '%s'", info.fileName);
+ return list_sort(features, (int (*)(void *, void *))cmpKeys);
+compile_error:
+ if (info.linepos < info.linelen)
+ _lou_logMessage(LOU_LOG_ERROR, "Unexpected character '%c' on line %d, column %d",
+ info.line[info.linepos], info.lineNumber, info.linepos);
+ else
+ _lou_logMessage(LOU_LOG_ERROR, "Unexpected newline on line %d", info.lineNumber);
+ list_free(features);
+ return NULL;
+}
+
+static List *tableIndex = NULL;
+
+void EXPORT_CALL
+lou_indexTables(const char **tables) {
+ const char **table;
+ list_free(tableIndex);
+ tableIndex = NULL;
+ for (table = tables; *table; table++) {
+ _lou_logMessage(LOU_LOG_DEBUG, "Analyzing table %s", *table);
+ List *features = analyzeTable(*table, 1);
+ if (features) {
+ TableMeta m = { strdup(*table), features };
+ tableIndex = list_conj(tableIndex, memcpy(malloc(sizeof(m)), &m, sizeof(m)),
+ NULL, NULL, free);
+ }
+ }
+ if (!tableIndex) _lou_logMessage(LOU_LOG_WARN, "No tables were indexed");
+}
+
+/**
+ * Returns the list of files found in a single directory.
+ */
+#ifdef _MSC_VER
+static List *
+listDir(List *list, char *dirName) {
+ static char glob[MAXSTRING];
+ static char fileName[MAXSTRING];
+ WIN32_FIND_DATAA ffd;
+ HANDLE hFind;
+ sprintf(glob, "%s%c%c", dirName, DIR_SEP, '*');
+ hFind = FindFirstFileA(glob, &ffd);
+ if (hFind == INVALID_HANDLE_VALUE) {
+ _lou_logMessage(LOU_LOG_WARN, "%s is not a directory", dirName);
+ } else {
+ do {
+ if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ sprintf(fileName, "%s%c%s", dirName, DIR_SEP, ffd.cFileName);
+ list = list_conj(list, strdup(fileName), NULL, NULL, free);
+ }
+ } while (FindNextFileA(hFind, &ffd));
+ FindClose(hFind);
+ }
+ return list;
+}
+#else /* !_MSC_VER */
+static List *
+listDir(List *list, char *dirName) {
+ static char fileName[MAXSTRING];
+ struct stat info;
+ DIR *dir;
+ struct dirent *file;
+ if ((dir = opendir(dirName))) {
+ while ((file = readdir(dir))) {
+ sprintf(fileName, "%s%c%s", dirName, DIR_SEP, file->d_name);
+ if (stat(fileName, &info) == 0 && !(info.st_mode & S_IFDIR)) {
+ list = list_conj(list, strdup(fileName), NULL, NULL, free);
+ }
+ }
+ closedir(dir);
+ } else {
+ _lou_logMessage(LOU_LOG_WARN, "%s is not a directory", dirName);
+ }
+ return list;
+}
+#endif /* !_MSC_VER */
+
+/**
+ * Returns the list of files found on searchPath, where searchPath is a
+ * comma-separated list of directories.
+ */
+static List *
+listFiles(char *searchPath) {
+ List *list = NULL;
+ char *dirName;
+ int pos = 0;
+ int n;
+ while (1) {
+ for (n = 0; searchPath[pos + n] != '\0' && searchPath[pos + n] != ','; n++)
+ ;
+ dirName = malloc(n + 1);
+ dirName[n] = '\0';
+ memcpy(dirName, &searchPath[pos], n);
+ list = listDir(list, dirName);
+ free(dirName);
+ pos += n;
+ if (searchPath[pos] == '\0')
+ break;
+ else
+ pos++;
+ }
+ return list;
+}
+
+static void
+indexTablePath(void) {
+ char *searchPath;
+ List *tables;
+ void *tablesArray;
+ _lou_logMessage(
+ LOU_LOG_WARN, "Tables have not been indexed yet. Indexing LOUIS_TABLEPATH.");
+ searchPath = _lou_getTablePath();
+ tables = listFiles(searchPath);
+ tablesArray = list_toArray(tables, NULL);
+ lou_indexTables(tablesArray);
+ free(searchPath);
+ list_free(tables);
+ free(tablesArray);
+}
+
+char *EXPORT_CALL
+lou_findTable(const char *query) {
+ if (!tableIndex) indexTablePath();
+ List *queryFeatures = parseQuery(query);
+ int bestQuotient = 0;
+ char *bestMatch = NULL;
+ List *l;
+ for (l = tableIndex; l; l = l->tail) {
+ TableMeta *table = l->head;
+ int q = matchFeatureLists(queryFeatures, table->features, 0);
+ if (q > bestQuotient) {
+ bestQuotient = q;
+ if (bestMatch) free(bestMatch);
+ bestMatch = strdup(table->name);
+ }
+ }
+ list_free(queryFeatures);
+ if (bestMatch) {
+ _lou_logMessage(LOU_LOG_INFO, "Best match: %s (%d)", bestMatch, bestQuotient);
+ return bestMatch;
+ } else {
+ _lou_logMessage(LOU_LOG_INFO, "No table could be found for query '%s'", query);
+ return NULL;
+ }
+}
+
+typedef struct {
+ char *name;
+ int matchQuotient;
+} TableMatch;
+
+static int
+cmpMatches(TableMatch *m1, TableMatch *m2) {
+ if (m1->matchQuotient > m2->matchQuotient)
+ return -1;
+ else
+ return 1;
+}
+
+char **EXPORT_CALL
+lou_findTables(const char *query) {
+ char **tablesArray;
+ List *matches = NULL;
+ if (!tableIndex) indexTablePath();
+ List *queryFeatures = parseQuery(query);
+ List *l;
+ for (l = tableIndex; l; l = l->tail) {
+ TableMeta *table = l->head;
+ int quotient = matchFeatureLists(queryFeatures, table->features, 0);
+ if (quotient > 0) {
+ TableMatch m = { strdup(table->name), quotient };
+ matches = list_conj(matches, memcpy(malloc(sizeof(m)), &m, sizeof(m)),
+ (int (*)(void *, void *))cmpMatches, NULL, free);
+ }
+ }
+ list_free(queryFeatures);
+ if (matches) {
+ _lou_logMessage(LOU_LOG_INFO, "%d matches found", list_size(matches));
+ int i = 0;
+ tablesArray = malloc((1 + list_size(matches)) * sizeof(void *));
+ for (; matches; matches = matches->tail)
+ tablesArray[i++] = ((TableMatch *)matches->head)->name;
+ tablesArray[i] = NULL;
+ list_free(matches);
+ return tablesArray;
+ } else {
+ _lou_logMessage(LOU_LOG_INFO, "No table could be found for query '%s'", query);
+ return NULL;
+ }
+}
+
+char *EXPORT_CALL
+lou_getTableInfo(const char *table, const char *key) {
+ char *value = NULL;
+ List *features = analyzeTable(table, 0);
+ List *l;
+ for (l = features; l; l = l->tail) {
+ Feature *f = l->head;
+ if (strcasecmp(f->key, key) == 0) {
+ value = strdup(f->val);
+ list_free(features);
+ break;
+ }
+ }
+ return value;
+}
+
+char **EXPORT_CALL
+lou_listTables(void) {
+ void *tablesArray;
+ List *tables = NULL;
+ List *l;
+ if (!tableIndex) indexTablePath();
+ for (l = tableIndex; l; l = l->tail) {
+ TableMeta *table = l->head;
+ tables = list_conj(
+ tables, strdup(table->name), (int (*)(void *, void *))strcmp, NULL, NULL);
+ }
+ tablesArray = list_toArray(tables, NULL);
+ list_free(tables);
+ return tablesArray;
+}
diff --git a/liblouis/pattern.c b/liblouis/pattern.c
new file mode 100644
index 0000000..643cccc
--- /dev/null
+++ b/liblouis/pattern.c
@@ -0,0 +1,1616 @@
+/* liblouis Braille Translation and Back-Translation Library
+
+ Copyright (C) 2016 Mike Gray, American Printing House for the Blind
+
+ This file is part of liblouis.
+
+ liblouis is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 2.1 of the License, or
+ (at your option) any later version.
+
+ liblouis is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "internal.h"
+
+//#define CHECK_OUTPUT_DEFINED
+
+/////
+
+static const TranslationTableHeader *table;
+
+// TODO: these functions are static and copied serveral times
+
+int translation_direction = 1;
+
+static TranslationTableCharacter *
+findCharOrDots(widechar c, int m) {
+ /* Look up character or dot pattern in the appropriate
+ * table. */
+ static TranslationTableCharacter noChar = { 0, 0, 0, CTC_Space, 32, 32, 32 };
+ static TranslationTableCharacter noDots = { 0, 0, 0, CTC_Space, LOU_DOTS, LOU_DOTS,
+ LOU_DOTS };
+ TranslationTableCharacter *notFound;
+ TranslationTableCharacter *character;
+ TranslationTableOffset bucket;
+ unsigned long int makeHash = _lou_charHash(c);
+ if (m == 0) {
+ bucket = table->characters[makeHash];
+ notFound = &noChar;
+ } else {
+ bucket = table->dots[makeHash];
+ notFound = &noDots;
+ }
+ while (bucket) {
+ character = (TranslationTableCharacter *)&table->ruleArea[bucket];
+ if (character->realchar == c) return character;
+ bucket = character->next;
+ }
+ notFound->realchar = notFound->uppercase = notFound->lowercase = c;
+ return notFound;
+}
+
+static int
+checkAttr(const widechar c, const TranslationTableCharacterAttributes a) {
+ return (((findCharOrDots(c, translation_direction ? 0 : 1))->attributes & a) ? 1 : 0);
+}
+
+/////
+
+enum pattern_type {
+ PTN_ERROR,
+
+ PTN_START,
+ PTN_GROUP,
+ PTN_NOT,
+
+ PTN_ONE_MORE,
+ PTN_ZERO_MORE,
+ PTN_OPTIONAL,
+
+ PTN_ALTERNATE,
+
+ PTN_ANY,
+ PTN_ATTRIBUTES,
+ PTN_CHARS,
+ PTN_HOOK,
+ PTN_END_OF_INPUT,
+
+ PTN_END = 0xffff,
+};
+
+#define EXPR_TYPE_IN(at, buffer) (buffer[(at) + 0])
+#define EXPR_PRV_IN(at, buffer) (buffer[(at) + 1])
+#define EXPR_NXT_IN(at, buffer) (buffer[(at) + 2])
+#define EXPR_DATA_0_IN(at, buffer) (buffer[(at) + 3])
+#define EXPR_DATA_1_IN(at, buffer) (buffer[(at) + 4])
+#define EXPR_DATA_2_IN(at, buffer) (buffer[(at) + 5])
+#define EXPR_DATA_IN(at, buffer) ((widechar *)&buffer[(at) + 3])
+#define EXPR_CONST_DATA_IN(at, buffer) ((const widechar *)&buffer[(at) + 3])
+
+#define EXPR_TYPE(at) EXPR_TYPE_IN((at), expr_data)
+#define EXPR_PRV(at) EXPR_PRV_IN((at), expr_data)
+#define EXPR_NXT(at) EXPR_NXT_IN((at), expr_data)
+#define EXPR_DATA_0(at) EXPR_DATA_0_IN((at), expr_data)
+#define EXPR_DATA_1(at) EXPR_DATA_1_IN((at), expr_data)
+#define EXPR_DATA_2(at) EXPR_DATA_2_IN((at), expr_data)
+#define EXPR_DATA(at) EXPR_DATA_IN((at), expr_data)
+#define EXPR_CONST_DATA(at) EXPR_CONST_DATA_IN((at), expr_data)
+
+#ifdef CHECK_OUTPUT_DEFINED
+
+#ifndef DEBUG
+#define DEBUG
+
+#endif
+
+#define START 0
+#define CALL 1
+#define RETURN 2
+#define SHOW 3
+
+#define CHECK_OUTPUT(type, ret, line, msg) \
+ { \
+ do_output(type, ret, line, input[*input_crs], input_minmax, *input_crs, \
+ input_dir, expr_data, expr_crs, not, loop_crs, loop_cnts, msg); \
+ }
+
+#else
+
+#define CHECK_OUTPUT(type, ret, line, msg) \
+ { ; }
+
+#endif
+
+struct expression {
+ widechar type;
+ widechar prv;
+ widechar nxt;
+ widechar data[1];
+};
+
+/* gdb won't know what this is unless it is actually used */
+#ifdef DEBUG
+static struct expression *expr_debug;
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+static char spaces[] = "..............................";
+static int space = 30;
+
+static void
+pattern_output_expression(const widechar *expr_data, int expr_crs) {
+ int i;
+
+ if (expr_crs == PTN_END) return;
+
+ while (EXPR_TYPE(expr_crs) != PTN_END) {
+ printf("%s%d", &spaces[space], expr_crs);
+ if (expr_crs < 100) printf(" ");
+ if (expr_crs < 10) printf(" ");
+ for (i = 0; i < 13 - (30 - space); i++) printf(" ");
+
+ switch (EXPR_TYPE(expr_crs)) {
+ case PTN_START:
+
+ printf("START\t%d\t%d\n", EXPR_PRV(expr_crs), EXPR_NXT(expr_crs));
+ break;
+
+ case PTN_GROUP:
+
+ printf("( \t%d\t%d\t-> %d\n", EXPR_PRV(expr_crs), EXPR_NXT(expr_crs),
+ EXPR_DATA_0(expr_crs));
+ space--;
+ if (space < 0) space = 0;
+ pattern_output_expression(expr_data, EXPR_DATA_0(expr_crs));
+ space++;
+ if (space > 30) space = 30;
+ break;
+
+ case PTN_NOT:
+
+ printf("! \t%d\t%d\t-> %d\n", EXPR_PRV(expr_crs), EXPR_NXT(expr_crs),
+ EXPR_DATA_0(expr_crs));
+ space--;
+ if (space < 0) space = 0;
+ pattern_output_expression(expr_data, EXPR_DATA_0(expr_crs));
+ space++;
+ if (space > 30) space = 30;
+ break;
+
+ case PTN_ONE_MORE:
+
+ printf("+ \t%d\t%d\t-> %d\t#%d\n", EXPR_PRV(expr_crs), EXPR_NXT(expr_crs),
+ EXPR_DATA_0(expr_crs), EXPR_DATA_1(expr_crs));
+ space--;
+ if (space < 0) space = 0;
+ pattern_output_expression(expr_data, EXPR_DATA_0(expr_crs));
+ space++;
+ if (space > 30) space = 30;
+ break;
+
+ case PTN_ZERO_MORE:
+
+ printf("* \t%d\t%d\t-> %d\t#%d\n", EXPR_PRV(expr_crs), EXPR_NXT(expr_crs),
+ EXPR_DATA_0(expr_crs), EXPR_DATA_1(expr_crs));
+ space--;
+ if (space < 0) space = 0;
+ pattern_output_expression(expr_data, EXPR_DATA_0(expr_crs));
+ space++;
+ if (space > 30) space = 30;
+ break;
+
+ case PTN_OPTIONAL:
+
+ printf("? \t%d\t%d\t-> %d\n", EXPR_PRV(expr_crs), EXPR_NXT(expr_crs),
+ EXPR_DATA_0(expr_crs));
+ space--;
+ if (space < 0) space = 0;
+ pattern_output_expression(expr_data, EXPR_DATA_0(expr_crs));
+ space++;
+ if (space > 30) space = 30;
+ break;
+
+ case PTN_ALTERNATE:
+
+ printf("| \t%d\t%d\t-> %d\t-> %d\n", EXPR_PRV(expr_crs),
+ EXPR_NXT(expr_crs), EXPR_DATA_0(expr_crs), EXPR_DATA_1(expr_crs));
+ space--;
+ if (space < 0) space = 0;
+ pattern_output_expression(expr_data, EXPR_DATA_0(expr_crs));
+ pattern_output_expression(expr_data, EXPR_DATA_1(expr_crs));
+ space++;
+ if (space > 30) space = 30;
+ break;
+
+ case PTN_ANY:
+
+ printf(". \t%d\t%d\n", EXPR_PRV(expr_crs), EXPR_NXT(expr_crs));
+ break;
+
+ case PTN_ATTRIBUTES:
+
+ printf("%% \t%d\t%d\t", EXPR_PRV(expr_crs), EXPR_NXT(expr_crs));
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined0 >> 16)) printf("0");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined1 >> 16)) printf("1");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined2 >> 16)) printf("2");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined3 >> 16)) printf("3");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined4 >> 16)) printf("4");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined5 >> 16)) printf("5");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined6 >> 16)) printf("6");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined7 >> 16)) printf("7");
+ if (EXPR_DATA_0(expr_crs) & (CTC_EndOfInput >> 16)) printf("^");
+ if (EXPR_DATA_1(expr_crs) & CTC_Space) printf("_");
+ if (EXPR_DATA_1(expr_crs) & CTC_Digit) printf("#");
+ if (EXPR_DATA_1(expr_crs) & CTC_Letter) printf("a");
+ if (EXPR_DATA_1(expr_crs) & CTC_UpperCase) printf("u");
+ if (EXPR_DATA_1(expr_crs) & CTC_LowerCase) printf("l");
+ if (EXPR_DATA_1(expr_crs) & CTC_Punctuation) printf(".");
+ if (EXPR_DATA_1(expr_crs) & CTC_Sign) printf("$");
+ if (EXPR_DATA_1(expr_crs) & CTC_SeqDelimiter) printf("~");
+ if (EXPR_DATA_1(expr_crs) & CTC_SeqBefore) printf("<");
+ if (EXPR_DATA_1(expr_crs) & CTC_SeqAfter) printf(">");
+ puts("");
+ break;
+
+ case PTN_CHARS:
+
+ printf("[] \t%d\t%d\t", EXPR_PRV(expr_crs), EXPR_NXT(expr_crs));
+ for (i = 0; i < EXPR_DATA_0(expr_crs); i++)
+ printf("%c", EXPR_CONST_DATA(expr_crs)[i + 1]);
+ puts("");
+ break;
+
+ case PTN_HOOK:
+
+ printf("@ \t%d\t%d\t", EXPR_PRV(expr_crs), EXPR_NXT(expr_crs));
+ for (i = 0; i < EXPR_DATA_0(expr_crs); i++)
+ printf("%c", EXPR_CONST_DATA(expr_crs)[i + 1]);
+ puts("");
+ break;
+
+ case PTN_END_OF_INPUT:
+
+ printf("^ \t%d\t%d\n", EXPR_PRV(expr_crs), EXPR_NXT(expr_crs));
+ break;
+
+ default:
+
+ printf("%d? \t%d\t%d\n", EXPR_TYPE(expr_crs), EXPR_PRV(expr_crs),
+ EXPR_NXT(expr_crs));
+ break;
+ }
+
+ expr_crs = EXPR_NXT(expr_crs);
+ }
+
+ printf("%s%d", &spaces[space], expr_crs);
+ if (expr_crs < 100) printf(" ");
+ if (expr_crs < 10) printf(" ");
+ for (i = 0; i < 13 - (30 - space); i++) printf(" ");
+ printf("END\t%d\t%d\n", EXPR_PRV(expr_crs), EXPR_NXT(expr_crs));
+ fflush(stdout);
+ return;
+}
+
+static void
+pattern_output(const widechar *expr_data) {
+ printf("%d \tlength\n", expr_data[0]);
+ printf("%d \tloops\n", expr_data[1]);
+ if (expr_data[0] > 0 && expr_data[0] != PTN_END)
+ pattern_output_expression(expr_data, 2);
+}
+
+static void
+pattern_print_expression(const widechar *expr_data, int expr_crs) {
+ int i;
+
+ if (expr_crs == PTN_END) return;
+
+ while (EXPR_TYPE(expr_crs) != PTN_END) {
+ switch (EXPR_TYPE(expr_crs)) {
+ case PTN_START:
+ break;
+
+ case PTN_GROUP:
+
+ printf(" (");
+ pattern_print_expression(expr_data, EXPR_DATA_0(expr_crs));
+ printf(") ");
+ break;
+
+ case PTN_NOT:
+
+ printf("!");
+ pattern_print_expression(expr_data, EXPR_DATA_0(expr_crs));
+ break;
+
+ case PTN_ONE_MORE:
+
+ pattern_print_expression(expr_data, EXPR_DATA_0(expr_crs));
+ printf("+");
+ break;
+
+ case PTN_ZERO_MORE:
+
+ pattern_print_expression(expr_data, EXPR_DATA_0(expr_crs));
+ printf("*");
+ break;
+
+ case PTN_OPTIONAL:
+
+ pattern_print_expression(expr_data, EXPR_DATA_0(expr_crs));
+ printf("?");
+ break;
+
+ case PTN_ALTERNATE:
+
+ pattern_print_expression(expr_data, EXPR_DATA_0(expr_crs));
+ printf(" | ");
+ pattern_print_expression(expr_data, EXPR_DATA_1(expr_crs));
+ break;
+
+ case PTN_ANY:
+
+ printf(".");
+ break;
+
+ case PTN_ATTRIBUTES:
+
+ printf("%%[");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined0 >> 16)) printf("0");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined1 >> 16)) printf("1");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined2 >> 16)) printf("2");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined3 >> 16)) printf("3");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined4 >> 16)) printf("4");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined5 >> 16)) printf("5");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined6 >> 16)) printf("6");
+ if (EXPR_DATA_0(expr_crs) & (CTC_UserDefined7 >> 16)) printf("7");
+ if (EXPR_DATA_0(expr_crs) & (CTC_EndOfInput >> 16)) printf("^");
+ if (EXPR_DATA_1(expr_crs) & CTC_Space) printf("_");
+ if (EXPR_DATA_1(expr_crs) & CTC_Digit) printf("#");
+ if (EXPR_DATA_1(expr_crs) & CTC_Letter) printf("a");
+ if (EXPR_DATA_1(expr_crs) & CTC_UpperCase) printf("u");
+ if (EXPR_DATA_1(expr_crs) & CTC_LowerCase) printf("l");
+ if (EXPR_DATA_1(expr_crs) & CTC_Punctuation) printf(".");
+ if (EXPR_DATA_1(expr_crs) & CTC_Sign) printf("$");
+ if (EXPR_DATA_1(expr_crs) & CTC_SeqDelimiter) printf("~");
+ if (EXPR_DATA_1(expr_crs) & CTC_SeqBefore) printf("<");
+ if (EXPR_DATA_1(expr_crs) & CTC_SeqAfter) printf(">");
+ printf("]");
+ break;
+
+ case PTN_CHARS:
+
+ if (EXPR_DATA_0(expr_crs) == 1)
+ printf("%c", EXPR_DATA_1(expr_crs));
+ else {
+ printf("[");
+ for (i = 0; i < EXPR_DATA_0(expr_crs); i++)
+ printf("%c", EXPR_CONST_DATA(expr_crs)[i + 1]);
+ printf("]");
+ }
+ break;
+
+ case PTN_HOOK:
+
+ printf("@[");
+ for (i = 0; i < EXPR_DATA_0(expr_crs); i++)
+ printf("%c", EXPR_CONST_DATA(expr_crs)[i + 1]);
+ printf("]");
+ break;
+
+ case PTN_END_OF_INPUT:
+
+ printf("^");
+ break;
+
+ // default: printf("%d?\n", EXPR_TYPE(expr_crs)); break;
+ }
+
+ expr_crs = EXPR_NXT(expr_crs);
+ }
+
+ return;
+}
+
+static void
+pattern_print(const widechar *expr_data) {
+ if (expr_data[0] > 0 && expr_data[0] != PTN_END)
+ pattern_print_expression(expr_data, 2);
+ puts("");
+}
+
+#ifdef CHECK_OUTPUT_DEFINED
+
+static void
+do_padd(const int value) {
+ if (value < 100000) printf(" ");
+ if (value < 10000) printf(" ");
+ if (value < 1000) printf(" ");
+ if (value < 100) printf(" ");
+ if (value < 10) printf(" ");
+}
+
+static void
+do_pad(const int value) {
+ if (value < 100) printf(" ");
+ if (value < 10) printf(" ");
+}
+
+static void
+do_output(const int type, const int ret, const int line,
+
+ const int input, const int input_minmax, const int input_crs, const int input_dir,
+ const widechar *expr_data, const int expr_crs, const int not, const int loop_crs,
+ const int *loop_cnts,
+
+ const char *msg) {
+ switch (type) {
+ case START:
+
+ space--;
+ if (space < 0) space = 0;
+ printf("|%s() ", &spaces[space]);
+ break;
+
+ case CALL:
+
+ printf("|%s> ", &spaces[space]);
+ break;
+
+ case RETURN:
+
+ printf("|%s<%d ", &spaces[space], ret);
+ space++;
+ if (space > 31) space = 31;
+ break;
+
+ case SHOW:
+
+ printf("|%s ", &spaces[space]);
+ break;
+ }
+
+ printf("%d ", line);
+ do_padd(line);
+
+ switch (expr_data[expr_crs]) {
+ case PTN_ERROR:
+ printf("# ");
+ break;
+ case PTN_START:
+ printf("> ");
+ break;
+ case PTN_END_OF_INPUT:
+ printf("^ ");
+ break;
+ case PTN_ALTERNATE:
+ printf("| ");
+ break;
+ case PTN_OPTIONAL:
+ printf("? ");
+ break;
+ case PTN_ONE_MORE:
+ printf("+ ");
+ break;
+ case PTN_ZERO_MORE:
+ printf("* ");
+ break;
+ case PTN_NOT:
+ printf("! ");
+ break;
+ case PTN_GROUP:
+ printf("( ");
+ break;
+ case PTN_ANY:
+ printf(". ");
+ break;
+ case PTN_ATTRIBUTES:
+ printf("%% ");
+ break;
+ case PTN_CHARS:
+ printf("[ ");
+ break;
+ case PTN_HOOK:
+ printf("@ ");
+ break;
+ case PTN_END:
+ printf("< ");
+ break;
+ default:
+ printf(" ");
+ break;
+ }
+ printf("%d ", expr_crs);
+ do_padd(expr_crs);
+
+ if (input > 31 && input < 127)
+ printf("%c ", input);
+ else
+ printf("_ ");
+
+ if (input_crs * input_dir >= input_minmax * input_dir)
+ printf("# ");
+ else {
+ printf("%d ", input_crs);
+ do_pad(input_crs);
+ }
+
+ if (input_dir > 0)
+ printf("<");
+ else
+ printf(">");
+ printf("%d ", input_minmax);
+ do_pad(input_minmax);
+
+ if (not)
+ printf("! ");
+ else
+ printf(" ");
+
+ if (loop_crs) {
+ printf("%d ", loop_crs);
+ do_pad(loop_crs);
+ printf("%d ", loop_cnts[EXPR_DATA_1(loop_crs)]);
+ do_pad(loop_cnts[EXPR_DATA_1(loop_crs)]);
+ } else
+ printf("- - ");
+ if (EXPR_TYPE(expr_crs) == PTN_ONE_MORE || EXPR_TYPE(expr_crs) == PTN_ZERO_MORE) {
+ printf("%d ", loop_cnts[EXPR_DATA_1(expr_crs)]);
+ do_pad(loop_cnts[EXPR_DATA_1(expr_crs)]);
+ } else
+ printf("- ");
+
+ if (msg) printf("%s", msg);
+ puts("");
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+static int
+pattern_compile_1(const widechar *input, const int input_max, int *input_crs,
+ widechar *expr_data, const int expr_max, widechar *expr_crs, widechar *loop_cnts);
+
+static int
+pattern_compile_expression(const widechar *input, const int input_max, int *input_crs,
+ widechar *expr_data, const int expr_max, widechar *expr_crs,
+ widechar *loop_cnts) {
+ widechar *data;
+ int expr_start, expr_end, expr_sub, expr_crs_prv;
+ int input_end;
+ int attrs0, attrs1;
+ int set, esc, nest, i;
+
+ switch (input[*input_crs]) {
+ case '(':
+
+ if (*expr_crs + 10 >= expr_max) return 0;
+
+ (*input_crs)++;
+ if (*input_crs >= input_max) return 0;
+
+ /* find closing parenthesis */
+ nest = esc = 0;
+ for (input_end = *input_crs; input_end < input_max; input_end++) {
+ if (input[input_end] == '\\' && !esc) {
+ esc = 1;
+ continue;
+ }
+
+ if (input[input_end] == '(' && !esc)
+ nest++;
+ else if (input[input_end] == ')' && !esc) {
+ if (nest)
+ nest--;
+ else
+ break;
+ }
+
+ esc = 0;
+ }
+ if (input_end >= input_max) return 0;
+
+ EXPR_TYPE(*expr_crs) = PTN_GROUP;
+
+ /* compile sub expressions */
+ expr_crs_prv = *expr_crs;
+ *expr_crs += 4;
+ EXPR_DATA_0(expr_crs_prv) = *expr_crs;
+ expr_sub = *expr_crs;
+ EXPR_TYPE(expr_sub) = PTN_ERROR;
+ EXPR_PRV(expr_sub) = PTN_END;
+ EXPR_NXT(expr_sub) = PTN_END;
+ if (!pattern_compile_1(input, input_end, input_crs, expr_data, expr_max, expr_crs,
+ loop_cnts))
+ return 0;
+ (*input_crs)++;
+
+ /* reset end expression */
+ expr_end = *expr_crs;
+ EXPR_NXT(expr_end) = expr_crs_prv;
+
+ return *expr_crs += 3;
+
+ case '!':
+
+ if (*expr_crs + 10 >= expr_max) return 0;
+
+ (*input_crs)++;
+ EXPR_TYPE(*expr_crs) = PTN_NOT;
+ expr_crs_prv = *expr_crs;
+ *expr_crs += 4;
+ EXPR_DATA_0(expr_crs_prv) = *expr_crs;
+
+ /* create start expression */
+ expr_start = *expr_crs;
+ EXPR_TYPE(expr_start) = PTN_START;
+ EXPR_PRV(expr_start) = PTN_END;
+ *expr_crs += 3;
+ EXPR_NXT(expr_start) = *expr_crs;
+
+ /* compile sub expression */
+ expr_sub = *expr_crs;
+ EXPR_TYPE(expr_sub) = PTN_ERROR;
+ EXPR_PRV(expr_sub) = expr_start;
+ EXPR_NXT(expr_sub) = PTN_END;
+
+ if (!pattern_compile_expression(input, input_max, input_crs, expr_data, expr_max,
+ expr_crs, loop_cnts))
+ return 0;
+
+ if (*expr_crs + 3 >= expr_max) return 0;
+
+ EXPR_NXT(expr_sub) = *expr_crs;
+
+ /* create end expression */
+ expr_end = *expr_crs;
+ EXPR_TYPE(expr_end) = PTN_END;
+ EXPR_PRV(expr_end) = expr_sub;
+ EXPR_NXT(expr_end) = expr_crs_prv;
+
+ return *expr_crs += 3;
+
+ case '+':
+
+ if (*expr_crs + 5 >= expr_max) return 0;
+ EXPR_TYPE(*expr_crs) = PTN_ONE_MORE;
+ EXPR_DATA_1(*expr_crs) = (*loop_cnts)++;
+ (*input_crs)++;
+ return *expr_crs += 5;
+
+ case '*':
+
+ if (*expr_crs + 5 >= expr_max) return 0;
+ EXPR_TYPE(*expr_crs) = PTN_ZERO_MORE;
+ EXPR_DATA_1(*expr_crs) = (*loop_cnts)++;
+ (*input_crs)++;
+ return *expr_crs += 5;
+
+ case '?':
+
+ if (*expr_crs + 4 >= expr_max) return 0;
+ EXPR_TYPE(*expr_crs) = PTN_OPTIONAL;
+ (*input_crs)++;
+ return *expr_crs += 4;
+
+ case '|':
+
+ if (*expr_crs + 5 >= expr_max) return 0;
+ EXPR_TYPE(*expr_crs) = PTN_ALTERNATE;
+ (*input_crs)++;
+ return *expr_crs += 5;
+
+ case '.':
+
+ if (*expr_crs + 3 >= expr_max) return 0;
+ EXPR_TYPE(*expr_crs) = PTN_ANY;
+ (*input_crs)++;
+ return *expr_crs += 3;
+
+ case '%':
+
+ if (*expr_crs + 5 >= expr_max) return 0;
+
+ (*input_crs)++;
+ if (*input_crs >= input_max) return 0;
+
+ /* find closing bracket */
+ if (input[*input_crs] == '[') {
+ set = 1;
+ (*input_crs)++;
+ for (input_end = *input_crs; input_end < input_max; input_end++)
+ if (input[input_end] == ']') break;
+ if (input_end >= input_max) return 0;
+ } else {
+ set = 0;
+ input_end = *input_crs + 1;
+ }
+
+ EXPR_TYPE(*expr_crs) = PTN_ATTRIBUTES;
+
+ attrs0 = attrs1 = 0;
+ for (; (*input_crs) < input_end; (*input_crs)++) {
+ switch (input[*input_crs]) {
+ case '_':
+ attrs0 |= CTC_Space;
+ break;
+ case '#':
+ attrs0 |= CTC_Digit;
+ break;
+ case 'a':
+ attrs0 |= CTC_Letter;
+ break;
+ case 'u':
+ attrs0 |= CTC_UpperCase;
+ break;
+ case 'l':
+ attrs0 |= CTC_LowerCase;
+ break;
+ case '.':
+ attrs0 |= CTC_Punctuation;
+ break;
+ case '$':
+ attrs0 |= CTC_Sign;
+ break;
+ case '~':
+ attrs0 |= CTC_SeqDelimiter;
+ break;
+ case '<':
+ attrs0 |= CTC_SeqBefore;
+ break;
+ case '>':
+ attrs0 |= CTC_SeqAfter;
+ break;
+
+ case '0':
+ attrs1 |= (CTC_UserDefined0 >> 16);
+ break;
+ case '1':
+ attrs1 |= (CTC_UserDefined1 >> 16);
+ break;
+ case '2':
+ attrs1 |= (CTC_UserDefined2 >> 16);
+ break;
+ case '3':
+ attrs1 |= (CTC_UserDefined3 >> 16);
+ break;
+ case '4':
+ attrs1 |= (CTC_UserDefined4 >> 16);
+ break;
+ case '5':
+ attrs1 |= (CTC_UserDefined5 >> 16);
+ break;
+ case '6':
+ attrs1 |= (CTC_UserDefined6 >> 16);
+ break;
+ case '7':
+ attrs1 |= (CTC_UserDefined7 >> 16);
+ break;
+ case '^':
+ attrs1 |= (CTC_EndOfInput >> 16);
+ break;
+
+ default:
+ return 0;
+ }
+ }
+ EXPR_DATA_0(*expr_crs) = attrs1;
+ EXPR_DATA_1(*expr_crs) = attrs0;
+
+ if (set) (*input_crs)++;
+ return *expr_crs += 5;
+
+ case '[':
+
+ (*input_crs)++;
+ if (*input_crs >= input_max) return 0;
+
+ /* find closing bracket */
+ esc = 0;
+ for (input_end = *input_crs; input_end < input_max; input_end++) {
+ if (input[input_end] == '\\' && !esc) {
+ esc = 1;
+ continue;
+ }
+
+ if (input[input_end] == ']' && !esc) break;
+ esc = 0;
+ }
+ if (input_end >= input_max) return 0;
+
+ if (*expr_crs + 4 + (input_end - *input_crs) >= expr_max) return 0;
+
+ EXPR_TYPE(*expr_crs) = PTN_CHARS;
+
+ esc = 0;
+ data = EXPR_DATA(*expr_crs);
+ for (i = 1; *input_crs < input_end; (*input_crs)++) {
+ if (input[*input_crs] == '\\' && !esc) {
+ esc = 1;
+ continue;
+ }
+
+ esc = 0;
+ data[i++] = (widechar)input[*input_crs];
+ }
+ data[0] = i - 1;
+ (*input_crs)++;
+ return *expr_crs += 4 + data[0];
+
+ case '@':
+
+ (*input_crs)++;
+ if (*input_crs >= input_max) return 0;
+
+ /* find closing bracket */
+ if (input[*input_crs] == '[') {
+ set = 1;
+ (*input_crs)++;
+ for (input_end = *input_crs; input_end < input_max; input_end++)
+ if (input[input_end] == ']') break;
+ if (input_end >= input_max) return 0;
+ } else {
+ set = 0;
+ input_end = *input_crs + 1;
+ }
+
+ if (*expr_crs + 4 + (input_end - *input_crs) >= expr_max) return 0;
+
+ EXPR_TYPE(*expr_crs) = PTN_HOOK;
+
+ esc = 0;
+ data = EXPR_DATA(*expr_crs);
+ for (i = 1; *input_crs < input_end; (*input_crs)++) {
+ if (input[*input_crs] == '\\' && !esc) {
+ esc = 1;
+ continue;
+ }
+
+ esc = 0;
+ data[i++] = (widechar)input[*input_crs];
+ }
+ data[0] = i - 1;
+ if (set) (*input_crs)++;
+ return *expr_crs += 4 + data[0];
+
+ case '^':
+ case '$':
+
+ if (*expr_crs + 3 >= expr_max) return 0;
+ EXPR_TYPE(*expr_crs) = PTN_END_OF_INPUT;
+ (*input_crs)++;
+ return *expr_crs += 3;
+
+ case '\\':
+
+ (*input_crs)++;
+ if (*input_crs >= input_max) return 0;
+
+ default:
+
+ if (*expr_crs + 5 >= expr_max) return 0;
+ EXPR_TYPE(*expr_crs) = PTN_CHARS;
+ EXPR_DATA_0(*expr_crs) = 1;
+ EXPR_DATA_1(*expr_crs) = (widechar)input[*input_crs];
+ (*input_crs)++;
+ return *expr_crs += 5;
+ }
+}
+
+static int
+pattern_insert_alternate(const widechar *input, const int input_max, int *input_crs,
+ widechar *expr_data, const int expr_max, widechar *expr_crs, widechar *loop_cnts,
+ int expr_insert) {
+ int expr_group, expr_alt, expr_end;
+
+ if (EXPR_TYPE(*expr_crs) == PTN_START) return 0;
+
+ if (*expr_crs + 12 >= expr_max) return 0;
+
+ /* setup alternate expression */
+ expr_alt = *expr_crs;
+ EXPR_TYPE(expr_alt) = PTN_ALTERNATE;
+ EXPR_PRV(expr_alt) = PTN_END;
+ EXPR_NXT(expr_alt) = PTN_END;
+ *expr_crs += 5;
+
+ /* setup group expression */
+ expr_group = *expr_crs;
+ EXPR_TYPE(expr_group) = PTN_GROUP;
+ EXPR_PRV(expr_group) = PTN_END;
+ EXPR_NXT(expr_group) = PTN_END;
+ *expr_crs += 4;
+ EXPR_DATA_0(expr_group) = *expr_crs;
+
+ EXPR_TYPE(*expr_crs) = PTN_ERROR;
+ EXPR_PRV(*expr_crs) = PTN_END;
+ EXPR_NXT(*expr_crs) = PTN_END;
+ if (!pattern_compile_1(
+ input, input_max, input_crs, expr_data, expr_max, expr_crs, loop_cnts))
+ return 0;
+ expr_end = *expr_crs;
+ EXPR_NXT(expr_end) = expr_group;
+
+ /* setup last end expression */
+ if (*expr_crs + 3 >= expr_max) return 0;
+ *expr_crs += 3;
+ EXPR_TYPE(*expr_crs) = PTN_END;
+ EXPR_NXT(*expr_crs) = PTN_END;
+
+ /* replace insert expression with group expression using last end expression */
+ EXPR_NXT(EXPR_PRV(expr_insert)) = expr_group;
+ EXPR_PRV(expr_group) = EXPR_PRV(expr_insert);
+
+ EXPR_NXT(expr_group) = *expr_crs;
+ EXPR_PRV(*expr_crs) = expr_group;
+
+ /* link alternate and insert expressions before group end expression */
+ EXPR_NXT(EXPR_PRV(expr_end)) = expr_alt;
+ EXPR_PRV(expr_alt) = EXPR_PRV(expr_end);
+
+ EXPR_NXT(expr_alt) = expr_insert;
+ EXPR_PRV(expr_insert) = expr_alt;
+
+ EXPR_NXT(expr_insert) = expr_end;
+ EXPR_PRV(expr_end) = expr_insert;
+
+ return *expr_crs;
+}
+
+/* Compile all expression sequences, resolving character sets, attributes,
+ * groups, nots, and hooks. Note that unlike the other compile functions, on
+ * returning the expr_crs is set to the last end expression, not after it.
+ */
+static int
+pattern_compile_1(const widechar *input, const int input_max, int *input_crs,
+ widechar *expr_data, const int expr_max, widechar *expr_crs,
+ widechar *loop_cnts) {
+ int expr_crs_prv;
+
+ if (*expr_crs + 6 >= expr_max) return 0;
+
+ expr_crs_prv = *expr_crs;
+
+ /* setup start expression */
+ EXPR_TYPE(*expr_crs) = PTN_START;
+ EXPR_PRV(*expr_crs) = PTN_END;
+ *expr_crs += 3;
+ EXPR_NXT(expr_crs_prv) = *expr_crs;
+
+ /* setup end expression */
+ EXPR_TYPE(*expr_crs) = PTN_END;
+ EXPR_PRV(*expr_crs) = expr_crs_prv;
+ EXPR_NXT(*expr_crs) = PTN_END;
+
+ while (*input_crs < input_max) {
+ expr_crs_prv = *expr_crs;
+ if (!pattern_compile_expression(input, input_max, input_crs, expr_data, expr_max,
+ expr_crs, loop_cnts))
+ return 0;
+
+ /* setup end expression */
+ if (*expr_crs + 3 >= expr_max) return 0;
+ EXPR_NXT(expr_crs_prv) = *expr_crs;
+ EXPR_TYPE(*expr_crs) = PTN_END;
+ EXPR_PRV(*expr_crs) = expr_crs_prv;
+ EXPR_NXT(*expr_crs) = PTN_END;
+
+ /* insert seqafterexpression before attributes of seqafterchars */
+ // if(EXPR_TYPE(expr_crs_prv) == PTN_ATTRIBUTES)
+ // if(EXPR_DATA_1(expr_crs_prv) & CTC_SeqAfter)
+ // {
+ // i = 0;
+ // pattern_insert_alternate(table->seqAfterExpression,
+ // table->seqAfterExpressionLength, &i, expr_data, expr_max,
+ // expr_crs, loop_cnts, expr_crs_prv);
+ // }
+ }
+
+ return *expr_crs;
+}
+
+/* Resolve optional and loop expressions.
+ */
+static int
+pattern_compile_2(
+ widechar *expr_data, int expr_at, const int expr_max, widechar *expr_crs) {
+ int expr_start, expr_end, expr_prv, expr_sub;
+
+ while (EXPR_TYPE(expr_at) != PTN_END) {
+ if (EXPR_TYPE(expr_at) == PTN_GROUP || EXPR_TYPE(expr_at) == PTN_NOT) {
+ if (!pattern_compile_2(expr_data, EXPR_DATA_0(expr_at), expr_max, expr_crs))
+ return 0;
+ }
+
+ if (EXPR_TYPE(expr_at) == PTN_ZERO_MORE || EXPR_TYPE(expr_at) == PTN_ONE_MORE ||
+ EXPR_TYPE(expr_at) == PTN_OPTIONAL) {
+ if (*expr_crs + 6 >= expr_max) return 0;
+
+ /* get previous expressions, there must
+ * be at least something and a PTN_START */
+ expr_sub = EXPR_PRV(expr_at);
+ if (EXPR_TYPE(expr_sub) == PTN_START) return 0;
+ expr_prv = EXPR_PRV(expr_sub);
+
+ /* create start expression */
+ expr_start = *expr_crs;
+ EXPR_TYPE(expr_start) = PTN_START;
+ EXPR_PRV(expr_start) = PTN_END;
+ EXPR_NXT(expr_start) = expr_sub;
+ *expr_crs += 3;
+
+ /* create end expression */
+ expr_end = *expr_crs;
+ EXPR_TYPE(expr_end) = PTN_END;
+ EXPR_PRV(expr_end) = expr_sub;
+ EXPR_NXT(expr_end) = expr_at;
+ *expr_crs += 3;
+
+ /* relink previous expression before sub expression */
+ EXPR_DATA_0(expr_at) = expr_start;
+ EXPR_NXT(expr_prv) = expr_at;
+ EXPR_PRV(expr_at) = expr_prv;
+
+ /* relink sub expression to start and end */
+ EXPR_PRV(expr_sub) = expr_start;
+ EXPR_NXT(expr_sub) = expr_end;
+ }
+
+ expr_at = EXPR_NXT(expr_at);
+ }
+
+ return 1;
+}
+
+/* Resolves alternative expressions.
+ */
+static int
+pattern_compile_3(
+ widechar *expr_data, int expr_at, const int expr_max, widechar *expr_crs) {
+ int expr_mrk, expr_start, expr_end, expr_sub_start, expr_sub_end;
+
+ while (EXPR_TYPE(expr_at) != PTN_END) {
+ if (EXPR_TYPE(expr_at) == PTN_GROUP || EXPR_TYPE(expr_at) == PTN_NOT ||
+ EXPR_TYPE(expr_at) == PTN_OPTIONAL ||
+ EXPR_TYPE(expr_at) == PTN_ZERO_MORE ||
+ EXPR_TYPE(expr_at) == PTN_ONE_MORE) {
+ if (!pattern_compile_3(expr_data, EXPR_DATA_0(expr_at), expr_max, expr_crs))
+ return 0;
+ }
+
+ if (EXPR_TYPE(expr_at) == PTN_ALTERNATE) {
+ if (*expr_crs + 12 >= expr_max) return 0;
+
+ /* get previous start expression,
+ * can include alternate expressions */
+ expr_mrk = EXPR_PRV(expr_at);
+ if (EXPR_TYPE(expr_mrk) == PTN_START) return 0;
+ expr_sub_end = expr_mrk;
+ while (EXPR_TYPE(expr_mrk) != PTN_START) expr_mrk = EXPR_PRV(expr_mrk);
+ expr_sub_start = EXPR_NXT(expr_mrk);
+
+ /* create first start expression */
+ expr_start = *expr_crs;
+ EXPR_TYPE(expr_start) = PTN_START;
+ EXPR_PRV(expr_start) = PTN_END;
+ EXPR_NXT(expr_start) = expr_sub_start;
+ *expr_crs += 3;
+
+ /* create first end expression */
+ expr_end = *expr_crs;
+ EXPR_TYPE(expr_end) = PTN_END;
+ EXPR_PRV(expr_end) = expr_sub_end;
+ EXPR_NXT(expr_end) = expr_at;
+ *expr_crs += 3;
+
+ /* relink previous expression before sub expression */
+ EXPR_DATA_0(expr_at) = expr_start;
+ EXPR_NXT(expr_mrk) = expr_at;
+ EXPR_PRV(expr_at) = expr_mrk;
+
+ /* relink sub expression to start and end */
+ EXPR_PRV(expr_sub_start) = expr_start;
+ EXPR_NXT(expr_sub_end) = expr_end;
+
+ /* get following PTN_END or PTN_ALTERNATE expression */
+ expr_mrk = EXPR_NXT(expr_at);
+ if (EXPR_TYPE(expr_mrk) == PTN_END || EXPR_TYPE(expr_mrk) == PTN_ALTERNATE)
+ return 0;
+ expr_sub_start = expr_mrk;
+ while (EXPR_TYPE(expr_mrk) != PTN_END && EXPR_TYPE(expr_mrk) != PTN_ALTERNATE)
+ expr_mrk = EXPR_NXT(expr_mrk);
+ expr_sub_end = EXPR_PRV(expr_mrk);
+
+ /* create first start expression */
+ expr_start = *expr_crs;
+ EXPR_TYPE(expr_start) = PTN_START;
+ EXPR_PRV(expr_start) = PTN_END;
+ EXPR_NXT(expr_start) = expr_sub_start;
+ *expr_crs += 3;
+
+ /* create first end expression */
+ expr_end = *expr_crs;
+ EXPR_TYPE(expr_end) = PTN_END;
+ EXPR_PRV(expr_end) = expr_sub_end;
+ EXPR_NXT(expr_end) = expr_at;
+ *expr_crs += 3;
+
+ /* relink following expression before sub expression */
+ EXPR_DATA_1(expr_at) = expr_start;
+ EXPR_PRV(expr_mrk) = expr_at;
+ EXPR_NXT(expr_at) = expr_mrk;
+
+ /* relink sub expression to start and end */
+ EXPR_PRV(expr_sub_start) = expr_start;
+ EXPR_NXT(expr_sub_end) = expr_end;
+
+ /* check expressions were after alternate and got moved into
+ * a sub expression, previous expressions already checked */
+ if (!pattern_compile_3(expr_data, EXPR_DATA_1(expr_at), expr_max, expr_crs))
+ return 0;
+ }
+
+ expr_at = EXPR_NXT(expr_at);
+ }
+
+ return 1;
+}
+
+int EXPORT_CALL
+_lou_pattern_compile(const widechar *input, const int input_max, widechar *expr_data,
+ const int expr_max, const TranslationTableHeader *t) {
+ int input_crs;
+
+ table = t;
+ input_crs = 0;
+ expr_data[0] = 2;
+ expr_data[1] = 0;
+
+ if (!pattern_compile_1(input, input_max, &input_crs, expr_data, expr_max,
+ &expr_data[0], &expr_data[1]))
+ return 0;
+
+ /* shift past the last end */
+ expr_data[0] += 3;
+
+ if (!pattern_compile_2(expr_data, 2, expr_max, &expr_data[0])) return 0;
+
+ if (!pattern_compile_3(expr_data, 2, expr_max, &expr_data[0])) return 0;
+
+ return expr_data[0];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static void
+pattern_reverse_expression(widechar *expr_data, const int expr_start);
+
+static void
+pattern_reverse_branch(widechar *expr_data, const int expr_at) {
+ widechar expr_swap;
+
+ switch (EXPR_TYPE(expr_at)) {
+ case PTN_ALTERNATE:
+
+ pattern_reverse_expression(expr_data, EXPR_DATA_0(expr_at));
+ expr_swap = EXPR_DATA_0(expr_at);
+ EXPR_DATA_0(expr_at) = EXPR_DATA_1(expr_at);
+ EXPR_DATA_1(expr_at) = expr_swap;
+
+ case PTN_GROUP:
+ case PTN_NOT:
+ case PTN_ONE_MORE:
+ case PTN_ZERO_MORE:
+ case PTN_OPTIONAL:
+
+ pattern_reverse_expression(expr_data, EXPR_DATA_0(expr_at));
+ }
+}
+
+static void
+pattern_reverse_expression(widechar *expr_data, const int expr_start) {
+ widechar expr_end, expr_crs, expr_prv;
+
+ expr_end = EXPR_NXT(expr_start);
+
+ /* empty expression */
+ if (EXPR_TYPE(expr_end) == PTN_END) return;
+
+ /* find end expression */
+ while (EXPR_TYPE(expr_end) != PTN_END) expr_end = EXPR_NXT(expr_end);
+
+ expr_crs = EXPR_PRV(expr_end);
+ expr_prv = EXPR_PRV(expr_crs);
+
+ /* relink expression before end expression */
+ EXPR_NXT(expr_start) = expr_crs;
+ EXPR_PRV(expr_crs) = expr_start;
+ EXPR_NXT(expr_crs) = expr_prv;
+
+ /* reverse any branching expressions */
+ pattern_reverse_branch(expr_data, expr_crs);
+
+ while (expr_prv != expr_start) {
+ /* shift current expression */
+ expr_crs = expr_prv;
+ expr_prv = EXPR_PRV(expr_prv);
+
+ /* reverse any branching expressions */
+ pattern_reverse_branch(expr_data, expr_crs);
+
+ /* relink current expression */
+ EXPR_PRV(expr_crs) = EXPR_NXT(expr_crs);
+ EXPR_NXT(expr_crs) = expr_prv;
+ }
+
+ /* relink expression after start expression */
+ EXPR_PRV(expr_crs) = EXPR_NXT(expr_crs);
+ EXPR_NXT(expr_crs) = expr_end;
+ EXPR_PRV(expr_end) = expr_crs;
+}
+
+void EXPORT_CALL
+_lou_pattern_reverse(widechar *expr_data) {
+ pattern_reverse_expression(expr_data, 2);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static int
+pattern_check_chars(const widechar input_char, const widechar *expr_data) {
+ int expr_cnt, i;
+
+ expr_cnt = expr_data[0] + 1;
+
+ for (i = 1; i < expr_cnt; i++)
+ if (input_char == expr_data[i]) break;
+
+ if (i == expr_cnt) return 0;
+ return 1;
+}
+
+static int
+pattern_check_attrs(const widechar input_char, const widechar *expr_data) {
+ int attrs;
+
+ attrs = ((expr_data[0] << 16) | expr_data[1]) & ~(CTC_EndOfInput | CTC_EmpMatch);
+ if (!checkAttr(input_char, attrs)) return 0;
+ return 1;
+}
+
+static int
+pattern_check_expression(const widechar *const input, int *input_crs,
+ const int input_minmax, const int input_dir, const widechar *const expr_data,
+ int (*hook)(const widechar input, const int data_len), widechar *hook_data,
+ const int hook_max, int expr_crs, int not, int loop_crs, int *loop_cnts) {
+ int input_crs_prv, input_start, attrs, ret, i;
+ const widechar *data;
+
+ data = NULL;
+
+ /* save input_crs to know if loop consumed input */
+ input_start = *input_crs;
+
+ CHECK_OUTPUT(START, 0, __LINE__, "check start")
+
+ while (!(EXPR_TYPE(expr_crs) == PTN_END && EXPR_TYPE(expr_crs) == PTN_END)) {
+ /* end of input expression */
+ if (EXPR_TYPE(expr_crs) == PTN_END_OF_INPUT) {
+ if (*input_crs * input_dir >= input_minmax * input_dir) {
+ if (not)
+ CHECK_OUTPUT(RETURN, 0, __LINE__,
+ "end of input failed: no input and not ")
+ else
+ CHECK_OUTPUT(RETURN, 1, __LINE__, "end of input passed: no input")
+ return !not;
+ } else {
+ if (not)
+ CHECK_OUTPUT(
+ RETURN, 1, __LINE__, "end of input passed: input and not")
+ else
+ CHECK_OUTPUT(RETURN, 0, __LINE__, "end of input failed: input")
+ return not;
+ }
+ }
+
+ /* no more input */
+ if (*input_crs * input_dir >= input_minmax * input_dir) {
+ switch (EXPR_TYPE(expr_crs)) {
+ case PTN_ATTRIBUTES:
+
+ attrs = (EXPR_DATA_0(expr_crs) << 16);
+ if (attrs & CTC_EndOfInput) {
+ if (not) {
+ CHECK_OUTPUT(RETURN, 0, __LINE__,
+ "attributes failed: end of input attribute: not")
+ return 0;
+ }
+ CHECK_OUTPUT(RETURN, 1, __LINE__,
+ "attributes passed: end of input attribute")
+ return 1;
+ }
+ CHECK_OUTPUT(RETURN, 0, __LINE__,
+ "attributes failed: no end of input attribute")
+ return 0;
+
+ case PTN_ANY:
+ case PTN_CHARS:
+
+ CHECK_OUTPUT(RETURN, 0, __LINE__, "chars failed: no input")
+ return 0;
+ }
+
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "no input")
+ }
+
+ switch (EXPR_TYPE(expr_crs)) {
+
+ case PTN_START:
+
+ expr_crs = EXPR_NXT(expr_crs);
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "start next")
+ break;
+
+ case PTN_GROUP:
+
+ expr_crs = EXPR_DATA_0(expr_crs);
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "group next")
+ break;
+
+ case PTN_NOT:
+
+ not = !not;
+ expr_crs = EXPR_DATA_0(expr_crs);
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "not next")
+ break;
+
+ case PTN_ONE_MORE:
+
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "loop+ start")
+
+ case PTN_ZERO_MORE:
+
+ /* check if loop already started */
+ if (expr_crs == loop_crs) {
+ loop_cnts[EXPR_DATA_1(loop_crs)]++;
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "loop again")
+ } else {
+ /* check if loop nested, wasn't running but has a count */
+ if (loop_cnts[EXPR_DATA_1(expr_crs)]) {
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "loop already running")
+ goto loop_next;
+ }
+
+ /* start loop */
+ loop_crs = expr_crs;
+ loop_cnts[EXPR_DATA_1(loop_crs)] = 1;
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "loop start")
+ }
+
+ /* start loop expression */
+ input_crs_prv = *input_crs;
+ ret = pattern_check_expression(input, input_crs, input_minmax, input_dir,
+ expr_data, hook, hook_data, hook_max, EXPR_DATA_0(expr_crs), not,
+ loop_crs, loop_cnts);
+ if (ret) {
+ CHECK_OUTPUT(RETURN, 1, __LINE__, "loop passed")
+ return 1;
+ }
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "loop failed")
+ *input_crs = input_crs_prv;
+
+ /* check loop count */
+ loop_cnts[EXPR_DATA_1(loop_crs)]--;
+ if (EXPR_TYPE(expr_crs) == PTN_ONE_MORE) {
+ if (loop_cnts[EXPR_DATA_1(loop_crs)] < 1) {
+ CHECK_OUTPUT(RETURN, 0, __LINE__, "loop+ failed")
+ return 0;
+ } else
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "loop+ passed")
+ }
+
+ /* continue after loop */
+ loop_next:
+ expr_crs = EXPR_NXT(expr_crs);
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "loop next")
+ break;
+
+ case PTN_OPTIONAL:
+
+ /* save current state */
+ input_crs_prv = *input_crs;
+
+ /* start optional expression */
+ CHECK_OUTPUT(CALL, 0, __LINE__, "option start")
+ if (pattern_check_expression(input, input_crs, input_minmax, input_dir,
+ expr_data, hook, hook_data, hook_max, EXPR_DATA_0(expr_crs), not,
+ loop_crs, loop_cnts)) {
+ CHECK_OUTPUT(RETURN, 1, __LINE__, "option passed")
+ return 1;
+ }
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "option failed")
+
+ /* continue after optional expression */
+ *input_crs = input_crs_prv;
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "no option start")
+ expr_crs = EXPR_NXT(expr_crs);
+ break;
+
+ case PTN_ALTERNATE:
+
+ /* save current state */
+ input_crs_prv = *input_crs;
+
+ /* start first expression */
+ CHECK_OUTPUT(CALL, 0, __LINE__, "or 1 start")
+ if (pattern_check_expression(input, input_crs, input_minmax, input_dir,
+ expr_data, hook, hook_data, hook_max, EXPR_DATA_0(expr_crs), not,
+ loop_crs, loop_cnts)) {
+ CHECK_OUTPUT(RETURN, 1, __LINE__, "or 1 passed")
+ return 1;
+ }
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "or 1 failed")
+
+ /* start second expression (no need to push) */
+ *input_crs = input_crs_prv;
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "or 2 start")
+ expr_crs = EXPR_DATA_1(expr_crs);
+ break;
+
+ case PTN_ANY:
+
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "any")
+ *input_crs += input_dir;
+ expr_crs = EXPR_NXT(expr_crs);
+ break;
+
+ case PTN_ATTRIBUTES:
+
+ ret = pattern_check_attrs(input[*input_crs], EXPR_CONST_DATA(expr_crs));
+ if (ret && not) {
+ CHECK_OUTPUT(RETURN, 0, __LINE__, "attributes failed: not");
+ return 0;
+ }
+ if (!ret && !not) {
+ CHECK_OUTPUT(RETURN, 0, __LINE__, "attributes failed");
+ return 0;
+ }
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "attributes passed")
+ *input_crs += input_dir;
+ expr_crs = EXPR_NXT(expr_crs);
+ break;
+
+ case PTN_CHARS:
+
+ ret = pattern_check_chars(input[*input_crs], EXPR_CONST_DATA(expr_crs));
+ if (ret && not) {
+ CHECK_OUTPUT(RETURN, 0, __LINE__, "chars failed: not");
+ return 0;
+ }
+ if (!ret && !not) {
+ CHECK_OUTPUT(RETURN, 0, __LINE__, "chars failed");
+ return 0;
+ }
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "chars passed")
+ *input_crs += input_dir;
+ expr_crs = EXPR_NXT(expr_crs);
+ break;
+
+ case PTN_HOOK:
+
+ if (hook == NULL) {
+ CHECK_OUTPUT(RETURN, 0, __LINE__, "hook failed: NULL");
+ return 0;
+ }
+
+ /* copy expression data */
+ data = EXPR_CONST_DATA(expr_crs);
+ for (i = 0; i < data[0]; i++) hook_data[i] = data[i + 1];
+
+ /* call hook function */
+ ret = hook(input[*input_crs], data[0]);
+ if (ret && not) {
+ CHECK_OUTPUT(RETURN, 0, __LINE__, "hook failed: not");
+ return 0;
+ }
+ if (!ret && !not) {
+ CHECK_OUTPUT(RETURN, 0, __LINE__, "hook failed");
+ return 0;
+ }
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "hook passed")
+ *input_crs += input_dir;
+ expr_crs = EXPR_NXT(expr_crs);
+ break;
+
+ case PTN_END:
+ break;
+
+ default:
+
+ CHECK_OUTPUT(RETURN, 0, __LINE__, "unknown opcode")
+ return 0;
+ }
+
+ /* check end expression */
+ while (EXPR_TYPE(expr_crs) == PTN_END) {
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "end")
+
+ /* check for end of expressions */
+ if (EXPR_NXT(expr_crs) == PTN_END) break;
+
+ expr_crs = EXPR_NXT(expr_crs);
+
+ /* returning loop */
+ if (EXPR_TYPE(expr_crs) == PTN_ZERO_MORE ||
+ EXPR_TYPE(expr_crs) == PTN_ONE_MORE) {
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "end loop")
+
+ /* check that loop consumed input */
+ if (*input_crs == input_start) {
+ CHECK_OUTPUT(RETURN, 0, __LINE__, "loop failed: did not consume")
+ return 0;
+ }
+
+ /* loops do not continue to the next expression */
+ break;
+ }
+
+ /* returning not */
+ if (EXPR_TYPE(expr_crs) == PTN_NOT) not = !not;
+
+ expr_crs = EXPR_NXT(expr_crs);
+
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "end next")
+ }
+
+ CHECK_OUTPUT(SHOW, 0, __LINE__, "check next")
+ }
+
+ CHECK_OUTPUT(RETURN, 1, __LINE__, "check passed: end of expression");
+ return 1;
+}
+
+static int
+pattern_check_hook(const widechar *input, const int input_start, const int input_minmax,
+ const int input_dir, const widechar *expr_data,
+ int (*hook)(const widechar input, const int data_len), widechar *hook_data,
+ const int hook_max) {
+ int input_crs, ret, *loop_cnts;
+
+ input_crs = input_start;
+ loop_cnts = malloc(expr_data[1] * sizeof(int));
+ memset(loop_cnts, 0, expr_data[1] * sizeof(int));
+ ret = pattern_check_expression(input, &input_crs, input_minmax, input_dir, expr_data,
+ hook, hook_data, hook_max, 2, 0, 0, loop_cnts);
+ free(loop_cnts);
+ return ret;
+}
+
+int EXPORT_CALL
+_lou_pattern_check(const widechar *input, const int input_start, const int input_minmax,
+ const int input_dir, const widechar *expr_data, const TranslationTableHeader *t) {
+#ifdef CHECK_OUTPUT_DEFINED
+ pattern_output(expr_data);
+#endif
+ table = t;
+ return pattern_check_hook(
+ input, input_start, input_minmax, input_dir, expr_data, NULL, NULL, 0);
+}
+
+////////////////////////////////////////////////////////////////////////////////
diff --git a/liblouis/utils.c b/liblouis/utils.c
new file mode 100644
index 0000000..7f0dcab
--- /dev/null
+++ b/liblouis/utils.c
@@ -0,0 +1,433 @@
+/* liblouis Braille Translation and Back-Translation Library
+
+ Based on the Linux screenreader BRLTTY, copyright (C) 1999-2006 by The
+ BRLTTY Team
+
+ Copyright (C) 2004, 2005, 2006 ViewPlus Technologies, Inc. www.viewplus.com
+ Copyright (C) 2004, 2005, 2006 JJB Software, Inc. www.jjb-software.com
+ Copyright (C) 2016 Mike Gray, American Printing House for the Blind
+ Copyright (C) 2016 Davy Kager, Dedicon
+
+ This file is part of liblouis.
+
+ liblouis is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 2.1 of the License, or
+ (at your option) any later version.
+
+ liblouis is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file
+ * @brief Common utility functions
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/stat.h>
+
+#include "internal.h"
+#include "config.h"
+
+/* Contributed by Michel Such <michel.such@free.fr> */
+#ifdef _WIN32
+
+/* Adapted from BRLTTY code (see sys_progs_wihdows.h) */
+
+#include <shlobj.h>
+
+static void *
+reallocWrapper(void *address, size_t size) {
+ if (!(address = realloc(address, size)) && size) _lou_outOfMemory();
+ return address;
+}
+
+static char *
+strdupWrapper(const char *string) {
+ char *address = strdup(string);
+ if (!address) _lou_outOfMemory();
+ return address;
+}
+
+char *EXPORT_CALL
+lou_getProgramPath(void) {
+ char *path = NULL;
+ HMODULE handle;
+
+ if ((handle = GetModuleHandle(NULL))) {
+ DWORD size = 0X80;
+ char *buffer = NULL;
+
+ while (1) {
+ buffer = reallocWrapper(buffer, size <<= 1);
+
+ {
+ // As the "UNICODE" Windows define may have been set at compilation,
+ // This call must be specifically GetModuleFilenameA as further code
+ // expects it to be single byte chars.
+ DWORD length = GetModuleFileNameA(handle, buffer, size);
+
+ if (!length) {
+ printf("GetModuleFileName\n");
+ exit(3);
+ }
+
+ if (length < size) {
+ buffer[length] = 0;
+ path = strdupWrapper(buffer);
+
+ while (length > 0)
+ if (path[--length] == '\\') break;
+
+ strncpy(path, path, length + 1);
+ path[length + 1] = '\0';
+ break;
+ }
+ }
+ }
+
+ free(buffer);
+ } else {
+ printf("GetModuleHandle\n");
+ exit(3);
+ }
+
+ return path;
+}
+#endif
+/* End of MS contribution */
+
+static widechar
+toLowercase(widechar c, const TranslationTableHeader *table) {
+ static TranslationTableOffset offset;
+ static TranslationTableCharacter *character;
+ offset = table->characters[_lou_charHash(c)];
+ while (offset) {
+ character = (TranslationTableCharacter *)&table->ruleArea[offset];
+ if (character->realchar == c) return character->lowercase;
+ offset = character->next;
+ }
+ return c;
+}
+
+unsigned long int EXPORT_CALL
+_lou_stringHash(const widechar *c, int lowercase, const TranslationTableHeader *table) {
+ if (!lowercase)
+ return (((unsigned long int)c[0] << 8) + (unsigned long int)c[1]) % HASHNUM;
+ else
+ return (((unsigned long int)toLowercase(c[0], table) << 8) +
+ (unsigned long int)toLowercase(c[1], table)) %
+ HASHNUM;
+}
+
+unsigned long int EXPORT_CALL
+_lou_charHash(widechar c) {
+ return (unsigned long int)c % HASHNUM;
+}
+
+const char *EXPORT_CALL
+_lou_showString(widechar const *chars, int length, int forceHex) {
+ /* Translate a string of characters to the encoding used in character
+ * operands */
+ static char scratchBuf[MAXSTRING];
+ int bufPos = 0;
+ scratchBuf[bufPos++] = '\'';
+
+ for (int charPos = 0; (charPos < length) && (bufPos < (MAXSTRING - 2));
+ charPos += 1) {
+ widechar c = chars[charPos];
+
+ if (!forceHex && isASCII(c)) {
+ scratchBuf[bufPos++] = (char)c;
+ } else {
+ char hexbuf[20];
+ int hexLength;
+ char escapeLetter;
+
+ int leadingZeros;
+ int hexPos;
+ hexLength = sprintf(hexbuf, "%x", c);
+ switch (hexLength) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ escapeLetter = 'x';
+ leadingZeros = 4 - hexLength;
+ break;
+ case 5:
+ escapeLetter = 'y';
+ leadingZeros = 0;
+ break;
+ case 6:
+ case 7:
+ case 8:
+ escapeLetter = 'z';
+ leadingZeros = 8 - hexLength;
+ break;
+ default:
+ escapeLetter = '?';
+ leadingZeros = 0;
+ break;
+ }
+ if ((bufPos + leadingZeros + hexLength + 4) >= (MAXSTRING - 2)) break;
+ scratchBuf[bufPos++] = '\\';
+ scratchBuf[bufPos++] = escapeLetter;
+ for (hexPos = 0; hexPos < leadingZeros; hexPos++) scratchBuf[bufPos++] = '0';
+ for (hexPos = 0; hexPos < hexLength; hexPos++)
+ scratchBuf[bufPos++] = hexbuf[hexPos];
+ }
+ }
+ scratchBuf[bufPos++] = '\'';
+ scratchBuf[bufPos] = 0;
+ return scratchBuf;
+}
+
+/**
+ * Mapping between braille dot and textual representation as used in dots operands
+ */
+static const intCharTupple dotMapping[] = {
+ { LOU_DOT_1, '1' },
+ { LOU_DOT_2, '2' },
+ { LOU_DOT_3, '3' },
+ { LOU_DOT_4, '4' },
+ { LOU_DOT_5, '5' },
+ { LOU_DOT_6, '6' },
+ { LOU_DOT_7, '7' },
+ { LOU_DOT_8, '8' },
+ { LOU_DOT_9, '9' },
+ { LOU_DOT_10, 'A' },
+ { LOU_DOT_11, 'B' },
+ { LOU_DOT_12, 'C' },
+ { LOU_DOT_13, 'D' },
+ { LOU_DOT_14, 'E' },
+ { LOU_DOT_15, 'F' },
+ { 0, 0 },
+};
+
+/**
+ * Print out dot numbers
+ *
+ * @return a string containing the dot numbers. The longest possible
+ * output is "\123456789ABCDEF0/"
+ */
+const char *EXPORT_CALL
+_lou_unknownDots(widechar dots) {
+ static char buffer[20];
+
+ int k = 0;
+ buffer[k++] = '\\';
+
+ for (int mappingPos = 0; dotMapping[mappingPos].key; mappingPos++) {
+ if (dots & dotMapping[mappingPos].key) buffer[k++] = dotMapping[mappingPos].value;
+ }
+
+ if (k == 1) buffer[k++] = '0';
+ buffer[k++] = '/';
+ buffer[k] = 0;
+ return buffer;
+}
+
+/**
+ * Translate a sequence of dots to the encoding used in dots operands.
+ */
+const char *EXPORT_CALL
+_lou_showDots(widechar const *dots, int length) {
+ int bufPos = 0;
+ static char scratchBuf[MAXSTRING];
+ for (int dotsPos = 0; dotsPos < length && bufPos < (MAXSTRING - 1); dotsPos++) {
+ for (int mappingPos = 0; dotMapping[mappingPos].key; mappingPos++) {
+ if ((dots[dotsPos] & dotMapping[mappingPos].key) &&
+ (bufPos < (MAXSTRING - 1)))
+ scratchBuf[bufPos++] = dotMapping[mappingPos].value;
+ }
+ if ((dots[dotsPos] == LOU_DOTS) && (bufPos < (MAXSTRING - 1)))
+ scratchBuf[bufPos++] = '0';
+ if ((dotsPos != length - 1) && (bufPos < (MAXSTRING - 1)))
+ scratchBuf[bufPos++] = '-';
+ }
+ scratchBuf[bufPos] = 0;
+ return scratchBuf;
+}
+
+/**
+ * Mapping between character attribute and textual representation
+ */
+static const intCharTupple attributeMapping[] = {
+ { CTC_Space, 's' },
+ { CTC_Letter, 'l' },
+ { CTC_Digit, 'd' },
+ { CTC_Punctuation, 'p' },
+ { CTC_UpperCase, 'U' },
+ { CTC_LowerCase, 'u' },
+ { CTC_Math, 'm' },
+ { CTC_Sign, 'S' },
+ { CTC_LitDigit, 'D' },
+ { CTC_Class1, 'w' },
+ { CTC_Class2, 'x' },
+ { CTC_Class3, 'y' },
+ { CTC_Class4, 'z' },
+ { 0, 0 },
+};
+
+/**
+ * Show attributes using the letters used after the $ in multipass
+ * opcodes.
+ */
+char *EXPORT_CALL
+_lou_showAttributes(TranslationTableCharacterAttributes a) {
+ int bufPos = 0;
+ static char scratchBuf[MAXSTRING];
+ for (int mappingPos = 0; attributeMapping[mappingPos].key; mappingPos++) {
+ if ((a & attributeMapping[mappingPos].key) && bufPos < (MAXSTRING - 1))
+ scratchBuf[bufPos++] = attributeMapping[mappingPos].value;
+ }
+ scratchBuf[bufPos] = 0;
+ return scratchBuf;
+}
+
+void EXPORT_CALL
+_lou_outOfMemory(void) {
+ _lou_logMessage(LOU_LOG_FATAL, "liblouis: Insufficient memory\n");
+ exit(3);
+}
+
+#ifdef DEBUG
+void EXPORT_CALL
+_lou_debugHook(void) {
+ char *hook = "debug hook";
+ printf("%s\n", hook);
+}
+#endif
+
+static const int validTranslationModes[] = { noContractions, compbrlAtCursor, dotsIO,
+ compbrlLeftCursor, ucBrl, noUndefined, partialTrans };
+
+int EXPORT_CALL
+_lou_isValidMode(int mode) {
+ // mask out all valid mode bits. If you end up with some bits set
+ // then the input isn't valid. See
+ // https://en.wikipedia.org/wiki/Material_nonimplication
+ for (int i = 0; i < (sizeof(validTranslationModes) / sizeof(*validTranslationModes));
+ i++)
+ mode &= ~validTranslationModes[i];
+ return !mode;
+}
+
+/* Map char to dots according to North American Braille Computer Code (NABCC) */
+widechar EXPORT_CALL
+_lou_charToFallbackDots(widechar c) {
+ static const unsigned char charToDots[] = {
+ /* ASCII characters 0X00-0X1F - control characters.
+ * These won't be referenced so we have room for data.
+ * These groups must be in descending order.
+ * Each group contains the following four bytes:
+ * 1) The first character to which this block applies.
+ * 2) The bits to remove from the character.
+ * 3) The bits to add to the character.
+ * 4) The dots to add to the braille pattern.
+ */
+ // clang-format off
+ 0X7F, 0X20, 0X00, LOU_DOT_7,
+ 0X60, 0X20, 0X00, 0,
+ 0X5F, 0X00, 0X00, 0,
+ 0X40, 0X00, 0X00, LOU_DOT_7,
+ 0X20, 0X00, 0X00, 0,
+ 0X00, 0X00, 0X40, LOU_DOT_7 | LOU_DOT_8,
+
+ // ASCII characters 0X20-0X3F - digits and common symbols.
+ [' '] = 0,
+ ['!'] = LOU_DOT_2 | LOU_DOT_3 | LOU_DOT_4 | LOU_DOT_6,
+ ['"'] = LOU_DOT_5,
+ ['#'] = LOU_DOT_3 | LOU_DOT_4 | LOU_DOT_5 | LOU_DOT_6,
+ ['$'] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_4 | LOU_DOT_6,
+ ['%'] = LOU_DOT_1 | LOU_DOT_4 | LOU_DOT_6,
+ ['&'] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_3 | LOU_DOT_4 | LOU_DOT_6,
+ ['\''] = LOU_DOT_3,
+ ['('] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_3 | LOU_DOT_5 | LOU_DOT_6,
+ [')'] = LOU_DOT_2 | LOU_DOT_3 | LOU_DOT_4 | LOU_DOT_5 | LOU_DOT_6,
+ ['*'] = LOU_DOT_1 | LOU_DOT_6,
+ ['+'] = LOU_DOT_3 | LOU_DOT_4 | LOU_DOT_6,
+ [','] = LOU_DOT_6,
+ ['-'] = LOU_DOT_3 | LOU_DOT_6,
+ ['.'] = LOU_DOT_4 | LOU_DOT_6,
+ ['/'] = LOU_DOT_3 | LOU_DOT_4,
+ ['0'] = LOU_DOT_3 | LOU_DOT_5 | LOU_DOT_6,
+ ['1'] = LOU_DOT_2,
+ ['2'] = LOU_DOT_2 | LOU_DOT_3,
+ ['3'] = LOU_DOT_2 | LOU_DOT_5,
+ ['4'] = LOU_DOT_2 | LOU_DOT_5 | LOU_DOT_6,
+ ['5'] = LOU_DOT_2 | LOU_DOT_6,
+ ['6'] = LOU_DOT_2 | LOU_DOT_3 | LOU_DOT_5,
+ ['7'] = LOU_DOT_2 | LOU_DOT_3 | LOU_DOT_5 | LOU_DOT_6,
+ ['8'] = LOU_DOT_2 | LOU_DOT_3 | LOU_DOT_6,
+ ['9'] = LOU_DOT_3 | LOU_DOT_5,
+ [':'] = LOU_DOT_1 | LOU_DOT_5 | LOU_DOT_6,
+ [';'] = LOU_DOT_5 | LOU_DOT_6,
+ ['<'] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_6,
+ ['='] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_3 | LOU_DOT_4 | LOU_DOT_5 | LOU_DOT_6,
+ ['>'] = LOU_DOT_3 | LOU_DOT_4 | LOU_DOT_5,
+ ['?'] = LOU_DOT_1 | LOU_DOT_4 | LOU_DOT_5 | LOU_DOT_6,
+
+ // ASCII characters 0X40-0X5F - letters and other symbols.
+ ['@'] = LOU_DOT_4,
+ ['A'] = LOU_DOT_1,
+ ['B'] = LOU_DOT_1 | LOU_DOT_2,
+ ['C'] = LOU_DOT_1 | LOU_DOT_4,
+ ['D'] = LOU_DOT_1 | LOU_DOT_4 | LOU_DOT_5,
+ ['E'] = LOU_DOT_1 | LOU_DOT_5,
+ ['F'] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_4,
+ ['G'] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_4 | LOU_DOT_5,
+ ['H'] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_5,
+ ['I'] = LOU_DOT_2 | LOU_DOT_4,
+ ['J'] = LOU_DOT_2 | LOU_DOT_4 | LOU_DOT_5,
+ ['K'] = LOU_DOT_1 | LOU_DOT_3,
+ ['L'] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_3,
+ ['M'] = LOU_DOT_1 | LOU_DOT_3 | LOU_DOT_4,
+ ['N'] = LOU_DOT_1 | LOU_DOT_3 | LOU_DOT_4 | LOU_DOT_5,
+ ['O'] = LOU_DOT_1 | LOU_DOT_3 | LOU_DOT_5,
+ ['P'] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_3 | LOU_DOT_4,
+ ['Q'] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_3 | LOU_DOT_4 | LOU_DOT_5,
+ ['R'] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_3 | LOU_DOT_5,
+ ['S'] = LOU_DOT_2 | LOU_DOT_3 | LOU_DOT_4,
+ ['T'] = LOU_DOT_2 | LOU_DOT_3 | LOU_DOT_4 | LOU_DOT_5,
+ ['U'] = LOU_DOT_1 | LOU_DOT_3 | LOU_DOT_6,
+ ['V'] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_3 | LOU_DOT_6,
+ ['W'] = LOU_DOT_2 | LOU_DOT_4 | LOU_DOT_5 | LOU_DOT_6,
+ ['X'] = LOU_DOT_1 | LOU_DOT_3 | LOU_DOT_4 | LOU_DOT_6,
+ ['Y'] = LOU_DOT_1 | LOU_DOT_3 | LOU_DOT_4 | LOU_DOT_5 | LOU_DOT_6,
+ ['Z'] = LOU_DOT_1 | LOU_DOT_3 | LOU_DOT_5 | LOU_DOT_6,
+ ['['] = LOU_DOT_2 | LOU_DOT_4 | LOU_DOT_6,
+ ['\\'] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_5 | LOU_DOT_6,
+ [']'] = LOU_DOT_1 | LOU_DOT_2 | LOU_DOT_4 | LOU_DOT_5 | LOU_DOT_6,
+ ['^'] = LOU_DOT_4 | LOU_DOT_5,
+ ['_'] = LOU_DOT_4 | LOU_DOT_5 | LOU_DOT_6
+ // clang-format on
+ };
+
+ if (c >= 0X80) c = '?';
+ widechar dots = LOU_DOTS;
+
+ {
+ const unsigned char *p = charToDots;
+ while (*p > c) p += 4;
+
+ c &= ~*++p;
+ c |= *++p;
+ dots |= *++p;
+ }
+
+ dots |= charToDots[c];
+ return dots;
+}
diff --git a/m4/.gitkeep b/m4/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/m4/.gitkeep
diff --git a/man/Makefile.am b/man/Makefile.am
new file mode 100644
index 0000000..14cd263
--- /dev/null
+++ b/man/Makefile.am
@@ -0,0 +1,68 @@
+# Only build man pages if configure found the HELP2MAN tool
+if HAVE_HELP2MAN
+man_MANS = \
+ lou_allround.1 \
+ lou_checkhyphens.1 \
+ lou_checktable.1 \
+ lou_debug.1 \
+ lou_translate.1 \
+ lou_trace.1 \
+ lou_checkyaml.1 \
+ lou_tableinfo.1
+endif
+
+CLEANFILES = $(man_MANS)
+
+# The man pages depend on the --help strings and the version number.
+common_mandeps = $(top_srcdir)/configure.ac
+
+# We are not distributing the man pages otherwise we would need rules
+# such as below. The user will have to install help2man if they want
+# man pages.
+# lou_allround.1: $(top_srcdir)/tools/lou_allround.c $(common_mandeps)
+# cd ../liblouis && $(MAKE) $(AM_MAKEFLAGS) liblouis.la
+# cd ../gnulib && $(MAKE) $(AM_MAKEFLAGS) libgnu.la
+# cd ../tools && $(MAKE) $(AM_MAKEFLAGS) lou_allround$(EXEEXT)
+# $(HELP2MAN) ../tools/lou_allround$(EXEEXT) --info-page=$(PACKAGE) --output=$@
+
+# Depend on the source, not the binary; we don't need to regenerate the
+# binary when any source file changes, only the main one.
+lou_allround.1: $(top_srcdir)/tools/lou_allround.c $(common_mandeps)
+ $(HELP2MAN) ../tools/lou_allround$(EXEEXT) --info-page=$(PACKAGE) \
+ --name="Test every capability of the liblouis library" \
+ --output=$@
+
+lou_checkhyphens.1: $(top_srcdir)/tools/lou_checkhyphens.c $(common_mandeps)
+ $(HELP2MAN) ../tools/lou_checkhyphens$(EXEEXT) --info-page=$(PACKAGE) \
+ --name="Check the accuracy of hyphenation in liblouis Braille translation tables" \
+ --output=$@
+
+lou_checktable.1: $(top_srcdir)/tools/lou_checktable.c $(common_mandeps)
+ $(HELP2MAN) ../tools/lou_checktable$(EXEEXT) --info-page=$(PACKAGE) \
+ --name="Test a liblouis Braille translation table" \
+ --output=$@
+
+lou_debug.1: $(top_srcdir)/tools/lou_debug.c $(common_mandeps)
+ $(HELP2MAN) ../tools/lou_debug$(EXEEXT) --info-page=$(PACKAGE) \
+ --name="A debugger for liblouis Braille translation tables" \
+ --output=$@
+
+lou_translate.1: $(top_srcdir)/tools/lou_translate.c $(common_mandeps)
+ $(HELP2MAN) ../tools/lou_translate$(EXEEXT) --info-page=$(PACKAGE) \
+ --name="A Braille translator for large scale testing of liblouis Braille translation tables" \
+ --output=$@
+
+lou_trace.1: $(top_srcdir)/tools/lou_trace.c $(common_mandeps)
+ $(HELP2MAN) ../tools/lou_trace$(EXEEXT) --info-page=$(PACKAGE) \
+ --name="A tool to list all the rules that were used for a Braille translation" \
+ --output=$@
+
+lou_checkyaml.1: $(top_srcdir)/tools/lou_checkyaml.c $(common_mandeps)
+ $(HELP2MAN) ../tools/lou_checkyaml$(EXEEXT) --info-page=$(PACKAGE) \
+ --name="A tool to check Braille tests defined in a YAML file" \
+ --output=$@
+
+lou_tableinfo.1: $(top_srcdir)/tools/lou_tableinfo.c $(common_mandeps)
+ $(HELP2MAN) ../tools/lou_tableinfo$(EXEEXT) --info-page=$(PACKAGE) \
+ --name="A tool to query meta data from a liblouis Braille translation table" \
+ --output=$@
diff --git a/python/Makefile.am b/python/Makefile.am
new file mode 100644
index 0000000..e076110
--- /dev/null
+++ b/python/Makefile.am
@@ -0,0 +1,4 @@
+SUBDIRS = louis
+
+EXTRA_DIST = setup.py README
+
diff --git a/python/README b/python/README
new file mode 100644
index 0000000..abcb7d2
--- /dev/null
+++ b/python/README
@@ -0,0 +1,16 @@
+Liblouis Python ctypes bindings
+
+These bindings allow you to use liblouis from within Python. The
+package is called "louis". See the documentation included in the
+module for usage instructions.
+
+These bindings use ctypes to access the liblouis shared library. The
+liblouis shared library needs to be located in the library search
+path. In most cases, if liblouis has been installed in a standard
+location on your system, this is already the case and the bindings
+will work without any additional steps.
+
+A standard distutils setup.py script is provided for installation
+tasks. To install this package for system wide use, run (as root):
+
+ python setup.py install
diff --git a/python/examples/dtbook2brldtbook.xsl b/python/examples/dtbook2brldtbook.xsl
new file mode 100644
index 0000000..7c644e3
--- /dev/null
+++ b/python/examples/dtbook2brldtbook.xsl
@@ -0,0 +1,51 @@
+<?xml version='1.0'?>
+
+<!-- liblouis Braille Translation and Back-Translation Library -->
+
+<!-- Copyright (C) 2010 Swiss Library for the Blind, Visually Impaired and Print Disabled -->
+
+<!-- Copying and distribution of this file, with or without modification, -->
+<!-- are permitted in any medium without royalty provided the copyright -->
+<!-- notice and this notice are preserved. This file is offered as-is, -->
+<!-- without any warranty. -->
+
+<xsl:stylesheet
+ version='1.0'
+ xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
+ xmlns:dtb="http://www.daisy.org/z3986/2005/dtbook/"
+ xmlns:louis="http://liblouis.org/liblouis"
+ exclude-result-prefixes="dtb">
+
+ <xsl:output omit-xml-declaration="no" encoding="UTF-8" method="xml"
+ indent="yes" media-type="text/xml"/>
+
+ <xsl:param name="translation_table">de-ch-g2.ctb</xsl:param>
+
+ <xsl:template match="dtb:em">
+ <xsl:apply-templates mode="italic"/>
+ </xsl:template>
+
+ <xsl:template match="dtb:strong">
+ <xsl:apply-templates mode="bold"/>
+ </xsl:template>
+
+ <xsl:template match="text()">
+ <xsl:value-of select='louis:translate(string(),string($translation_table))'/>
+ </xsl:template>
+
+ <xsl:template match="text()" mode="italic">
+ <xsl:value-of select='louis:translate(string(),string($translation_table),"italic")'/>
+ </xsl:template>
+
+ <xsl:template match="text()" mode="bold">
+ <xsl:value-of select='louis:translate(string(),string($translation_table),"bold")'/>
+ </xsl:template>
+
+ <xsl:template match="@*|node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@*|node()"/>
+ </xsl:copy>
+ </xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/python/examples/liblouisxslt.py b/python/examples/liblouisxslt.py
new file mode 100755
index 0000000..2f1267b
--- /dev/null
+++ b/python/examples/liblouisxslt.py
@@ -0,0 +1,70 @@
+#! /usr/bin/python -u
+#
+# liblouis Braille Translation and Back-Translation Library
+
+# Copyright (C) 2010 Swiss Library for the Blind, Visually Impaired and Print Disabled
+
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved. This file is offered as-is,
+# without any warranty.
+
+# This is a very simple example on how to extend libxslt to be able to
+# invoke liblouis from xslt. See also the accompanying
+# dtbook2brldtbook.xsl in the same directory which simpy copies a dtbook
+# xml and translates all the text node into Braille.
+
+import louis
+import libxml2
+import libxslt
+import sys
+import getopt
+from optparse import OptionParser
+
+nodeName = None
+
+emphasisMap = {
+ 'plain_text' : louis.plain_text,
+ 'italic' : louis.italic,
+ 'underline' : louis.underline,
+ 'bold' : louis.bold,
+ 'computer_braille' : louis.computer_braille}
+
+def translate(ctx, str, translation_table, emphasis=None):
+ global nodeName
+
+ try:
+ pctxt = libxslt.xpathParserContext(_obj=ctx)
+ ctxt = pctxt.context()
+ tctxt = ctxt.transformContext()
+ nodeName = tctxt.insertNode().name
+ except:
+ pass
+
+ typeform = len(str)*[emphasisMap[emphasis]] if emphasis else None
+ braille = louis.translate([translation_table], str.decode('utf-8'), typeform=typeform)[0]
+ return braille.encode('utf-8')
+
+def xsltProcess(styleFile, inputFile, outputFile):
+ """Transform an xml inputFile to an outputFile using the given styleFile"""
+ styledoc = libxml2.parseFile(styleFile)
+ style = libxslt.parseStylesheetDoc(styledoc)
+ doc = libxml2.parseFile(inputFile)
+ result = style.applyStylesheet(doc, None)
+ style.saveResultToFilename(outputFile, result, 0)
+ style.freeStylesheet()
+ doc.freeDoc()
+ result.freeDoc()
+
+libxslt.registerExtModuleFunction("translate", "http://liblouis.org/liblouis", translate)
+
+def main():
+ usage = "Usage: %prog [options] styleFile inputFile outputFile"
+ parser = OptionParser(usage)
+ (options, args) = parser.parse_args()
+ if len(args) != 3:
+ parser.error("incorrect number of arguments")
+ xsltProcess(args[0], args[1], args[2])
+
+if __name__ == "__main__":
+ main()
diff --git a/python/louis/Makefile.am b/python/louis/Makefile.am
new file mode 100644
index 0000000..fd02120
--- /dev/null
+++ b/python/louis/Makefile.am
@@ -0,0 +1,8 @@
+EXTRA_DIST = __init__.py.in
+CLEANFILES = __init__.py __init__.pyc
+
+all:
+ source ../../liblouis/liblouis.la ; \
+ sed "s/###LIBLOUIS_SONAME###/$$dlname/" \
+ < $(srcdir)/__init__.py.in \
+ > __init__.py
diff --git a/python/louis/__init__.py.in b/python/louis/__init__.py.in
new file mode 100644
index 0000000..065061a
--- /dev/null
+++ b/python/louis/__init__.py.in
@@ -0,0 +1,474 @@
+# Liblouis Python ctypes bindings
+#
+# Copyright (C) 2009, 2010 James Teh <jamie@jantrid.net>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
+#
+
+"""Liblouis Python ctypes bindings
+These bindings allow you to use the liblouis braille translator and back-translator library from within Python.
+This documentation is only a Python helper.
+Please see the liblouis documentation for more information.
+
+Most of these functions take a C{tableList} argument which specifies
+a list of translation tables to use. Please see the liblouis documentation
+concerning the C{tableList} parameter to the C{lou_translateString}
+function for information about how liblouis searches for these tables.
+
+@author: Michael Curran <mick@kulgan.net>
+@author: James Teh <jamie@jantrid.net>
+@author: Eitan Isaacson <eitan@ascender.com>
+@author: Michael Whapples <mwhapples@aim.com>
+@author: Davy Kager <mail@davykager.nl>
+@author: Leonard de Ruijter (Babbage B.V.) <alderuijter@gmail.com>
+"""
+
+from __future__ import unicode_literals
+from ctypes import *
+import atexit
+import sys
+
+# Some general utility functions
+def _createTablesString(tablesList):
+ """Creates a tables string for liblouis calls"""
+ return b",".join([x.encode(filesystemencoding) if isinstance(x, str) else bytes(x) for x in tablesList])
+
+def _createTypeformbuf(length, typeform=None):
+ """Creates a typeform buffer for liblouis calls"""
+ return (c_ushort*length)(*typeform) if typeform else (c_ushort*length)()
+
+ENCODING_ERROR_HANDLER = None
+createEncodedByteString = None
+if sys.version_info.major == 2:
+ ENCODING_ERROR_HANDLER = "strict"
+ createEncodedByteString = lambda x: unicode(x).encode(conversionEncoding, errors=ENCODING_ERROR_HANDLER)
+else: # sys.version_info[0] == 3
+ ENCODING_ERROR_HANDLER = "surrogatepass"
+ createEncodedByteString = lambda x: str(x).encode(conversionEncoding, errors=ENCODING_ERROR_HANDLER)
+
+try:
+ # Native win32
+ _loader = windll
+ _functype = WINFUNCTYPE
+except NameError:
+ # Unix/Cygwin
+ _loader = cdll
+ _functype = CFUNCTYPE
+liblouis = _loader["###LIBLOUIS_SONAME###"]
+
+atexit.register(liblouis.lou_free)
+
+liblouis.lou_version.restype = c_char_p
+
+liblouis.lou_charSize.restype = c_int
+
+liblouis.lou_translateString.argtypes = (
+ c_char_p, POINTER(c_char), POINTER(c_int), POINTER(c_char),
+ POINTER(c_int), POINTER(c_ushort), POINTER(c_char), c_int)
+
+liblouis.lou_translate.argtypes = (
+ c_char_p, POINTER(c_char), POINTER(c_int), POINTER(c_char),
+ POINTER(c_int), POINTER(c_ushort), POINTER(c_char),
+ POINTER(c_int), POINTER(c_int), POINTER(c_int), c_int)
+
+liblouis.lou_backTranslateString.argtypes = (
+ c_char_p, POINTER(c_char), POINTER(c_int), POINTER(c_char),
+ POINTER(c_int), POINTER(c_ushort), POINTER(c_char), c_int)
+
+liblouis.lou_backTranslate.argtypes = (
+ c_char_p, POINTER(c_char), POINTER(c_int), POINTER(c_char), POINTER(c_int),
+ POINTER(c_ushort), POINTER(c_char), POINTER(c_int), POINTER(c_int),
+ POINTER(c_int), c_int)
+
+liblouis.lou_hyphenate.argtypes = (
+ c_char_p, POINTER(c_char), c_int, POINTER(c_char), c_int)
+
+liblouis.lou_checkTable.argtypes = (c_char_p,)
+
+liblouis.lou_compileString.argtypes = (c_char_p, c_char_p)
+
+liblouis.lou_getTypeformForEmphClass.argtypes = (c_char_p, c_char_p)
+
+liblouis.lou_dotsToChar.argtypes = (
+ c_char_p, POINTER(c_char), POINTER(c_char),
+ c_int, c_int)
+
+liblouis.lou_charToDots.argtypes = (
+ c_char_p, POINTER(c_char), POINTER(c_char),
+ c_int, c_int)
+
+LogCallback = _functype(None, c_int, c_char_p)
+
+liblouis.lou_registerLogCallback.restype = None
+
+liblouis.lou_setLogLevel.restype = None
+liblouis.lou_setLogLevel.argtypes = (c_int,)
+
+#{ Module Configuration
+#: Specifies the charSize (in bytes) used by liblouis.
+#: This is fetched once using L{liblouis.lou_charSize}.
+#: Call it directly, since L{charSize} is not yet defined.
+#: @type: int
+wideCharBytes = liblouis.lou_charSize()
+#: Specifies the number by which the input length should be multiplied
+#: to calculate the maximum output length.
+#: @type: int
+# This default will handle the case where every input character is
+# undefined in the translation table.
+outlenMultiplier = 4 + wideCharBytes * 2
+#: Specifies the encoding to use when encode/decode filenames
+#: @type: str
+filesystemencoding = sys.getfilesystemencoding()
+#: Specifies the encoding to use when converting from byte strings to unicode strings.
+#: @type: str
+conversionEncoding = "utf_%d_le" % (wideCharBytes * 8)
+#}
+
+def version():
+ """Obtain version information for liblouis.
+ @return: The version of liblouis, plus other information, such as
+ the release date and perhaps notable changes.
+ @rtype: str
+ """
+ return liblouis.lou_version().decode("ASCII")
+
+def charSize():
+ """Obtain charSize information for liblouis.
+ @return: The size of the widechar with which liblouis was compiled.
+ @rtype: int
+ """
+ return liblouis.lou_charSize()
+
+def translate(tableList, inbuf, typeform=None, cursorPos=0, mode=0):
+ """Translate a string of characters, providing position information.
+ @param tableList: A list of translation tables.
+ @type tableList: list of str
+ @param inbuf: The string to translate.
+ @type inbuf: str
+ @param typeform: A list of typeform constants indicating the typeform for each position in inbuf,
+ C{None} for no typeform information.
+ @type typeform: list of int
+ @param cursorPos: The position of the cursor in inbuf.
+ @type cursorPos: int
+ @param mode: The translation mode; add multiple values for a combined mode.
+ @type mode: int
+ @return: A tuple of: the translated string,
+ a list of input positions for each position in the output,
+ a list of output positions for each position in the input, and
+ the position of the cursor in the output.
+ @rtype: (str, list of int, list of int, int)
+ @raise RuntimeError: If a complete translation could not be done.
+ @see: lou_translate in the liblouis documentation
+ """
+ tablesString = _createTablesString(tableList)
+ inbuf = createEncodedByteString(inbuf)
+ inlen = c_int(len(inbuf) // wideCharBytes)
+ outlen = c_int(inlen.value*outlenMultiplier)
+ outbuf = create_string_buffer(outlen.value * wideCharBytes)
+ typeformbuf = None
+ if typeform:
+ typeformbuf = _createTypeformbuf(outlen.value, typeform)
+ inPos = (c_int*outlen.value)()
+ outPos = (c_int*inlen.value)()
+ cursorPos = c_int(cursorPos)
+ if not liblouis.lou_translate(tablesString, inbuf, byref(inlen),
+ outbuf, byref(outlen), typeformbuf,
+ None, outPos, inPos, byref(cursorPos), mode):
+ raise RuntimeError("Can't translate: tables %s, inbuf %s, typeform %s, cursorPos %s, mode %s"%(tableList, inbuf, typeform, cursorPos, mode))
+ if isinstance(typeform, list):
+ typeform[:] = list(typeformbuf)
+ return outbuf.raw[:outlen.value * wideCharBytes].decode(conversionEncoding, errors=ENCODING_ERROR_HANDLER), inPos[:outlen.value], outPos[:inlen.value], cursorPos.value
+
+def translateString(tableList, inbuf, typeform=None, mode=0):
+ """Translate a string of characters.
+ @param tableList: A list of translation tables.
+ @type tableList: list of str
+ @param inbuf: The string to translate.
+ @type inbuf: str
+ @param typeform: A list of typeform constants indicating the typeform for each position in inbuf,
+ C{None} for no typeform information.
+ @type typeform: list of int
+ @param mode: The translation mode; add multiple values for a combined mode.
+ @type mode: int
+ @return: The translated string.
+ @rtype: str
+ @raise RuntimeError: If a complete translation could not be done.
+ @see: lou_translateString in the liblouis documentation
+ """
+ tablesString = _createTablesString(tableList)
+ inbuf = createEncodedByteString(inbuf)
+ inlen = c_int(len(inbuf) // wideCharBytes)
+ outlen = c_int(inlen.value*outlenMultiplier)
+ outbuf = create_string_buffer(outlen.value * wideCharBytes)
+ typeformbuf = None
+ if typeform:
+ typeformbuf = _createTypeformbuf(outlen.value, typeform)
+ if not liblouis.lou_translateString(tablesString, inbuf, byref(inlen),
+ outbuf, byref(outlen), typeformbuf,
+ None, mode):
+ raise RuntimeError("Can't translate: tables %s, inbuf %s, typeform %s, mode %s"%(tableList, inbuf, typeform, mode))
+ if isinstance(typeform, list):
+ typeform[:] = list(typeformbuf)
+ return outbuf.raw[:outlen.value * wideCharBytes].decode(conversionEncoding, errors=ENCODING_ERROR_HANDLER)
+
+def backTranslate(tableList, inbuf, typeform=None, cursorPos=0, mode=0):
+ """Back translates a string of characters, providing position information.
+ @param tableList: A list of translation tables.
+ @type tableList: list of str
+ @param inbuf: Braille to back translate.
+ @type inbuf: str
+ @param typeform: List where typeform constants will be placed.
+ @type typeform: list
+ @param cursorPos: Position of cursor.
+ @type cursorPos: int
+ @param mode: Translation mode.
+ @type mode: int
+ @return: A tuple: A string of the back translation,
+ a list of input positions for each position in the output,
+ a list of the output positions for each position in the input and
+ the position of the cursor in the output.
+ @rtype: (str, list of int, list of int, int)
+ @raise RuntimeError: If a complete back translation could not be done.
+ @see: lou_backTranslate in the liblouis documentation.
+ """
+ tablesString = _createTablesString(tableList)
+ inbuf = createEncodedByteString(inbuf)
+ inlen = c_int(len(inbuf) // wideCharBytes)
+ outlen = c_int(inlen.value * outlenMultiplier)
+ outbuf = create_string_buffer(outlen.value * wideCharBytes)
+ typeformbuf = None
+ if isinstance(typeform, list):
+ typeformbuf = _createTypeformbuf(outlen.value)
+ inPos = (c_int*outlen.value)()
+ outPos = (c_int*inlen.value)()
+ cursorPos = c_int(cursorPos)
+ if not liblouis.lou_backTranslate(tablesString, inbuf, byref(inlen),
+ outbuf, byref(outlen), typeformbuf, None,
+ outPos, inPos, byref(cursorPos), mode):
+ raise RuntimeError("Can't back translate: tables %s, inbuf %s, typeform %s, cursorPos %d, mode %d"%(tableList, inbuf, typeform, cursorPos, mode))
+ if isinstance(typeform, list):
+ typeform[:] = list(typeformbuf)
+ return outbuf.raw[:outlen.value * wideCharBytes].decode(conversionEncoding, errors=ENCODING_ERROR_HANDLER), inPos[:outlen.value], outPos[:inlen.value], cursorPos.value
+
+def backTranslateString(tableList, inbuf, typeform=None, mode=0):
+ """Back translate from Braille.
+ @param tableList: A list of translation tables.
+ @type tableList: list of str
+ @param inbuf: The Braille to back translate.
+ @type inbuf: str
+ @param typeform: List for typeform constants to be put in.
+ If you don't want typeform data then give None
+ @type typeform: list
+ @param mode: The translation mode
+ @type mode: int
+ @return: The back translation of inbuf.
+ @rtype: str
+ @raise RuntimeError: If a complete back translation could not be done.
+ @see: lou_backTranslateString in the liblouis documentation.
+ """
+ tablesString = _createTablesString(tableList)
+ inbuf = createEncodedByteString(inbuf)
+ inlen = c_int(len(inbuf) // wideCharBytes)
+ outlen = c_int(inlen.value * outlenMultiplier)
+ outbuf = create_string_buffer(outlen.value * wideCharBytes)
+ typeformbuf = None
+ if isinstance(typeform, list):
+ typeformbuf = _createTypeformbuf(outlen.value)
+ if not liblouis.lou_backTranslateString(tablesString, inbuf, byref(inlen), outbuf,
+ byref(outlen), typeformbuf, None, mode):
+ raise RuntimeError("Can't back translate: tables %s, inbuf %s, mode %d"%(tableList, inbuf, mode))
+ if isinstance(typeform, list):
+ typeform[:] = list(typeformbuf)
+ return outbuf.raw[:outlen.value * wideCharBytes].decode(conversionEncoding, errors=ENCODING_ERROR_HANDLER)
+
+def hyphenate(tableList, inbuf, mode=0):
+ """Get information for hyphenation.
+ @param tableList: A list of translation tables and hyphenation
+ dictionaries.
+ @type tableList: list of str
+ @param inbuf: The text to get hyphenation information about.
+ This should be a single word and leading/trailing whitespace
+ and punctuation is ignored.
+ @type inbuf: str
+ @param mode: Lets liblouis know if inbuf is plain text or Braille.
+ Set to 0 for text and anyother value for Braille.
+ @type mode: int
+ @return: A string with '1' at the beginning of every syllable
+ and '0' elsewhere.
+ @rtype: str
+ @raise RuntimeError: If hyphenation data could not be produced.
+ @see: lou_hyphenate in the liblouis documentation.
+ """
+ tablesString = _createTablesString(tableList)
+ inbuf = createEncodedByteString(inbuf)
+ inlen = c_int(len(inbuf) // wideCharBytes)
+ hyphen_string = create_string_buffer(inlen.value + 1)
+ if not liblouis.lou_hyphenate(tablesString, inbuf, inlen, hyphen_string, mode):
+ raise RuntimeError("Can't hyphenate: tables %s, inbuf %s, mode %d"%(tableList, inbuf, mode))
+ return hyphen_string.value.decode("ASCII")
+
+def checkTable(tableList):
+ """Check if the specified tables can be found and compiled.
+ This can be used to check if a list of tables contains errors
+ before sending it to other liblouis functions
+ that accept a list of tables.
+ @param tableList: A list of translation tables.
+ @type tableList: list of str
+ @raise RuntimeError: If compilation failed.
+ @see: lou_checkTable in the liblouis documentation
+ """
+ tablesString = _createTablesString(tableList)
+ if not liblouis.lou_checkTable(tablesString):
+ raise RuntimeError("Can't compile: tables %s"%tableList)
+
+def compileString(tableList, inString):
+ """Compile a table entry on the fly at run-time.
+ @param tableList: A list of translation tables.
+ @type tableList: list of str
+ @param inString: The table entry to be added.
+ @type inString: str
+ @raise RuntimeError: If compilation of the entry failed.
+ @see: lou_compileString in the liblouis documentation
+ """
+ tablesString = _createTablesString(tableList)
+ inBytes = inString.encode("ASCII") if isinstance(inString, str) else bytes(inString)
+ if not liblouis.lou_compileString(tablesString, inString):
+ raise RuntimeError("Can't compile entry: tables %s, inString %s"%(tableList, inString))
+
+def getTypeformForEmphClass(tableList, emphClass):
+ """Get the typeform bit for the named emphasis class.
+ @param tableList: A list of translation tables.
+ @type tableList: list of str
+ @param emphClass: An emphasis class name.
+ @type emphClass: str
+ @see: lou_getTypeformForEmphClass in the liblouis documentation
+ """
+ tablesString = _createTablesString(tableList)
+ return liblouis.lou_getTypeformForEmphClass(tablesString, emphClass)
+
+def dotsToChar(tableList, inbuf):
+ """"Convert a string of dot patterns to a string of characters according to the specifications in tableList.
+ @param tableList: A list of translation tables.
+ @type tableList: list of str
+ @param inbuf: a string of dot patterns, either in liblouis format or Unicode braille.
+ @type inbuf: str
+ @raise RuntimeError: If a complete conversion could not be done.
+ @see: lou_dotsToChar in the liblouis documentation
+ """
+ tablesString = _createTablesString(tableList)
+ inbuf = createEncodedByteString(inbuf)
+ length = c_int(len(inbuf) // wideCharBytes)
+ outbuf = create_string_buffer(length.value * wideCharBytes)
+ if not liblouis.lou_dotsToChar(tablesString, inbuf, outbuf, length, 0):
+ raise RuntimeError("Can't convert dots to char: tables %s, inbuf %s"%(tableList, inbuf))
+ return outbuf.raw[:length.value * wideCharBytes].decode(conversionEncoding, errors=ENCODING_ERROR_HANDLER)
+
+def charToDots(tableList, inbuf, mode=0):
+ """"Convert a string of characterss to a string of dot patterns according to the specifications in tableList.
+ @param tableList: A list of translation tables.
+ @type tableList: list of str
+ @param inbuf: a string of characters.
+ @type inbuf: str
+ @param mode: The translation mode; add multiple values for a combined mode.
+ @type mode: int
+ @raise RuntimeError: If a complete conversion could not be done.
+ @see: lou_charToDOts in the liblouis documentation
+ """
+ tablesString = _createTablesString(tableList)
+ inbuf = createEncodedByteString(inbuf)
+ length = c_int(len(inbuf) // wideCharBytes)
+ outbuf = create_string_buffer(length.value * wideCharBytes)
+ if not liblouis.lou_charToDots(tablesString, inbuf, outbuf, length, mode):
+ raise RuntimeError("Can't convert char to dots: tables %s, inbuf %s, mode %d"%(tableList, inbuf, mode))
+ return outbuf.raw[:length.value * wideCharBytes].decode(conversionEncoding, errors=ENCODING_ERROR_HANDLER)
+
+def registerLogCallback(logCallback):
+ """Register logging callbacks.
+ Set to C{None} for default callback.
+ @param logCallback: The callback to use.
+ The callback must take two arguments:
+ @param level: The log level on which a message is logged.
+ @type level: int
+ @param message: The logged message.
+ Note that the callback should provide its own ASCII decoding routine.
+ @type message: bytes
+
+ Example callback:
+
+ @louis.LogCallback
+ def incomingLouisLog(level, message):
+ print("Message %s logged at level %d" % (message.decode("ASCII"), level))
+
+ @type logCallback: L{LogCallback}
+ """
+ if logCallback is not None and not isinstance(logCallback, LogCallback):
+ raise TypeError("logCallback should be of type {} or NoneType".format(LogCallback.__name__))
+ return liblouis.lou_registerLogCallback(logCallback)
+
+def setLogLevel(level):
+ """Set the level for logging callback to be called at.
+ @param level: one of the C{LOG_*} constants.
+ @type level: int
+ @raise ValueError: If an invalid log level is provided.
+ """
+ if level not in logLevels:
+ raise ValueError("Level %d is an invalid log level"%level)
+ return liblouis.lou_setLogLevel(level)
+
+#{ Typeforms
+plain_text = 0x0000
+emph_1 = comp_emph_1 = italic = 0x0001
+emph_2 = comp_emph_2 = underline = 0x0002
+emph_3 = comp_emph_3 = bold = 0x0004
+emph_4 = 0x0008
+emph_5 = 0x0010
+emph_6 = 0x0020
+emph_7 = 0x0040
+emph_8 = 0x0080
+emph_9 = 0x0100
+emph_10 = 0x0200
+computer_braille = 0x0400
+no_translate = 0x0800
+no_contract = 0x1000
+#}
+
+#{ Translation modes
+noContractions = 1
+compbrlAtCursor = 2
+dotsIO = 4
+compbrlLeftCursor = 32
+ucBrl = 64
+noUndefined = 128
+noUndefinedDots = noUndefined # alias for backward compatiblity
+partialTrans = 256
+#}
+
+#{ logLevels
+LOG_ALL = 0
+LOG_DEBUG = 10000
+LOG_INFO = 20000
+LOG_WARN = 30000
+LOG_ERROR = 40000
+LOG_FATAL = 50000
+LOG_OFF = 60000
+#}
+
+logLevels = (LOG_ALL, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL, LOG_OFF)
+
+if __name__ == '__main__':
+ # Just some common tests.
+ print(version())
+ print(translate([b'../tables/en-us-g2.ctb'], 'Hello world!', cursorPos=5))
diff --git a/python/setup.py.in b/python/setup.py.in
new file mode 100644
index 0000000..09d5e04
--- /dev/null
+++ b/python/setup.py.in
@@ -0,0 +1,41 @@
+# Liblouis Python ctypes bindings
+#
+# Copyright (C) 2009 Eitan Isaacson <eitan@ascender.com>
+# Copyright (C) 2010 James Teh <jamie@jantrid.net>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
+#
+
+r"""Python bindings for liblouis
+"""
+
+from distutils.core import setup
+
+classifiers = [
+ 'Development Status :: 4 - Beta',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
+ 'Programming Language :: Python',
+ 'Topic :: Text Processing :: Linguistic',
+ ]
+
+setup(name="louis",
+ description=__doc__,
+ download_url = "https://github.com/liblouis/liblouis",
+ license="LGPLv2.1+",
+ classifiers=classifiers,
+ version='@VERSION@',
+ packages=["louis"])
diff --git a/tables/Es-Es-G0.utb b/tables/Es-Es-G0.utb
new file mode 100644
index 0000000..62f1db9
--- /dev/null
+++ b/tables/Es-Es-G0.utb
@@ -0,0 +1,217 @@
+# liblouis: Computer Spanish 8 dots Braille table
+#
+# -----------
+#-index-name: Spanish, computer
+#-display-name: Spanish computer braille
+#
+#+locale:es
+#+type:computer
+# -----------
+#
+# Copyright (C) 2012 by José Enrique Fernández del Campo and Juan Carlos Buño Suárez <quetzatl@eresmas.net>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# -----------------------------------------------------------------------------
+
+# Uncontracted Computer Spanish Table
+# Autor José Enrique Fernández del Campo <jefdelcampo@gmail.com> and Juan Carlos Buño Suárez <quetzatl@eresmas.net>
+# -----------------------------------------------------------------------------
+
+
+space \s 0 # blank 32
+space \t 9 # tab 9
+space \x001B 1b # escape
+space \x000A 0 # lf
+space \x000D 0 # cr
+space \x00A0 0 # Espacio de no separación
+
+# all except 0 are the same, so define 0 here to take higher presidence
+# Also define ó (lowercase o acute) not to clash with the definition of 0 in original include.
+digit 0 34678 cero
+uplow \x00d3\x00f3 3467,346 o con acento
+include digits6DotsPlusDot6.uti
+
+include latinLetterDef8Dots.uti
+
+uplow \x00c7\x00e7 1234678,123468 c cedilla
+uplow \x00c1\x00e1 123567,12356 a con acento
+uplow \x00c9\x00e9 23467,2346 e con acento
+uplow \x00cd\x00ed 347,34 i con acento
+uplow \x00da\x00fa 234567,23456 u con acento
+uplow \x00c0\x00e0 1235678,123568 a grave
+uplow \x00c8\x00e8 234678,23468 e grave
+uplow \x00cc\x00ec 345,348 i grave
+uplow \x00d2\x00f2 2458,3468 o grave
+uplow \x00d9\x00f9 2345678,234568 u grave
+uplow \x00c2\x00e2 178,18 a con circunflejo
+uplow \x00ca\x00ea 1578,158 e con circunflejo
+uplow \x00ce\x00ee 2478,248 i con circunflejo
+uplow \x00d4\x00f4 13578,1358 o con circunflejo
+uplow \x00db\x00fb 13678,1368 u con circunflejo
+uplow \x00c4\x00e4 34578,3458 a con diéresis
+uplow \x00cb\x00eb 124678,12468 e con diéresis
+uplow \x00cf\x00ef 1245678,258 i con diéresis
+uplow \x00d6\x00f6 24678,2468 o con diéresis
+uplow \x00dc\x00fc 125678,12568 u con diéresis
+uplow \x00dd\x00fd 1567,2348 ye con acento agudo
+uplow \x009F\x00FF 367,67 ye con diéresis
+
+uplow \x00c6\x00e6 38,1348 ae
+uplow \x0152\x0153 1468,1238 oe
+uplow \x008C\x009C 1468,1238 oe
+uplow \x00C3\x00E3 3567,168 a con tilde
+uplow \x00D5\x00F5 12458,4567 o con tilde
+uplow \x00D1\x00F1 124567,124568 letra eñe
+
+punctuation , 2 coma
+punctuation ; 23 punto y coma
+punctuation : 25 dos puntos
+punctuation - 36 guión
+punctuation . 3 punto
+punctuation ? 26 cerrar interrogación
+punctuation ! 2357 cerrar admiración
+punctuation \x0022 56 comillas
+punctuation \x201c 14568 abrir comillas
+punctuation \x201d 12348 cerrar comillas
+punctuation ( 1268 abre paréntesis
+punctuation ) 3457 cierra paréntesis
+punctuation ' 4 apóstrofo
+punctuation \x00ab 238 comillas angulares izquierda
+punctuation \x00bb 567 comillas angulares derecha
+punctuation [ 2367 abre corchetes
+punctuation ] 3568 cierra corchetes
+punctuation { 46 abre llave
+punctuation } 35 cierra llave
+
+sign * 256 asterisco
+sign \\ 123456 barra invertida
+sign @ 5 arroba
+sign % 456 por ciento
+sign _ 6 subrayado
+sign # 3456 signo de número
+sign \x0060 58 acento grave
+sign ^ 45 circunflejo
+sign \x007E 57 #126 ~ tilde
+sign \x007C 4568 # barra vertical
+sign \x007F 7 # borrar
+sign \x00a1 23578 # abrir admiración
+sign \x00A6 478 # barra vertical cortada
+sign \x00A7 167 # sección
+sign \x00A8 268 # diéresis
+sign \x00A9 23567 # copyright
+sign \x00AC 257 # guión opcional
+sign \x20AC 12358 # euros
+sign \x00AD 2358 # soft hyphen
+sign \x00AE 2368 # registrado
+sign \x00AF 24568 # macron
+sign \x00B1 12467 # más-menos
+sign \x00B5 13468 # my
+sign \x00B6 14567 # párrafo
+sign \x00B7 14678 # punto centrado
+sign \x00B9 237 # Super uno
+sign \x00BA 5678 # ordinal masculino
+sign \x00AA 23568 # ordinal femenino
+sign \x00BF 267 # abrir interrogación
+sign \x00C5 12368 #*a mayúscula con círculo superescrito
+
+sign \x00D0 13458 # letra eth mayúscula
+sign \x00D7 1678 # multiplicado por
+sign \x00D8 34567 # Alfa
+sign \x00DE 123458 # Thorn
+sign \x00DF 128 # Beta
+sign \x00E5 15678 # a con círculo superescrito
+sign \x00F0 235678 # letra eth
+sign \x00F7 2578 # dividido por
+sign \x00F8 457 # latin small letter o with stroke
+sign \x00FE 1568 # thorn
+sign \x00A8 268 diéresis
+
+math + 235 más
+math = 2356 igual
+math \x00d7 1678 multiplicado por
+math < 236 menor que
+math > 356 mayor que
+math / 3478 barra oblicua
+math \x00F7 2578 dividido por
+
+sign \x00a9 23567 copyright
+sign \x00b0 8 grado
+sign & 12346 ampersand
+sign \x00a2 12678 centavo
+sign \x00a4 2567
+sign \x00a3 2378 libra
+sign \x00a7 167 sección
+sign \x0024 123467 dólar
+sign \x00a5 145678 yen
+sign \x00b9 237 super 1
+sign \x00b2 47 al cuadrado
+sign \x00b3 568 al cubo
+sign \x00bc 1467 un cuarto
+sign \x00bd 468 un medio
+sign \x00be 48 tres cuartos
+
+sign \x0081 358 sin nombre
+sign \x0082 37 por
+sign \x201a 37 por
+sign \x0083 1248 signo
+sign \x0192 1248 signo
+sign \x0084 78 signo
+sign \x201e 78 signo
+sign \x0085 1267 elipsis
+sign \x2026 1267 elipsis
+sign \x0086 28 sin nombre
+sign \x2020 28 sin nombre
+sign \x0087 23458 sin nombre
+sign \x2021 23458 sin nombre
+sign \x0088 458 sin nombre
+sign \x02c6 23458 sin nombre
+sign \x0089 45678 sin nombre
+sign \x2030 45678 sin nombre
+sign \x008a 1234568 sh mayúscula
+sign \x0160 1234568 sh mayúscula
+sign \x008b 1258
+sign \x2039 1258
+sign \x008d 357 sin nombre
+sign \x008e 148 sin nombre
+sign \x017d 148 sin nombre
+sign \x008f 58
+sign \x0090 68 sin nombre
+sign \x2018 4 apóstrofo
+sign \x2019 4 apóstrofo
+sign \x0095 1458 signo
+sign \x2022 1458 signo
+sign \x0096 368 guión
+sign \x2013 368 guión
+sign \x0097 3678 guión
+sign \x2014 3678 guión
+sign \x0098 134568 tilde
+sign \x02dc 134568 tilde
+sign \x0099 2467 marca registrada
+sign \x2122 2467 marca registrada
+sign \x009a 34568 signo
+sign \x203a 34568 signo
+sign \x0161 12567 sh
+sign \x009d 25678
+sign \x009e 2568
+sign \x017e 2568
+sign \x009f 367
+sign \x0178 367
+sign \x00b4 467 acento agudo
+sign \x00B8 135678 z con caron
+
+noback sign \x25CF 256 black circle
diff --git a/tables/IPA-unicode-range.uti b/tables/IPA-unicode-range.uti
new file mode 100644
index 0000000..e4e26bf
--- /dev/null
+++ b/tables/IPA-unicode-range.uti
@@ -0,0 +1,200 @@
+# liblouis: International Phonetic Alphabet
+
+# Copyright (C) 2016 Ludovic Oger <oger.ludovic@gmail.com>
+
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+# This table contains braille codes for a part of the International Phonetic Alphabet (IPA, 2005) :
+# The IPA symbols in this table do not conflict with other tables
+# The others IPA symbols might conflict with other tables are inclued in the 'IPA.utb' table.
+# (e.g. conflict: θ (Unicode 03B8) is the greek letter theta, french braille code is different between greek and phonetic)
+
+
+# --------REFERENCES--------
+# - IPA Braille: An Updated Tactile Representation of the International Phonetic Alphabet
+# Print Edition
+# Edited by Robert Englebretson, Ph.D.
+# Produced by CNIB
+# For the International Council on English Braille - 2008
+# <http://www.iceb.org/icebipa.htm>
+# (this reference document is reprinted in 'World Braille Usage - Third Edition - 2013 - Copyright (C) 1954, 1990 UNESCO')
+#
+# - "IPA Chart, http://www.internationalphoneticassociation.org/content/ipa-chart,
+# available under a Creative Commons Attribution-Sharealike 3.0 Unported License.
+# Copyright (C) 2015 International Phonetic Association."
+
+
+# Last updated on January 23, 2018
+
+
+#--------PULMONIC CONSONANTS--------
+# UNICODE DOTS # GLYPH - TYPOGRAPHIC DESC. - ARTICULATORY DESC.
+noback sign \x0288 256-2345 # ʈ - right-tail t - voiceless retroflex plosive
+noback sign \x0256 256-145 # ɖ - right-tail d - voiced retroflex plosive
+noback sign \x025F 35-245 # ɟ - barred dotless j - voiced palatal plosive
+noback sign \x0261 1245 # ɡ - lowercase script g - voiced velar plosive
+noback sign \x0262 35-1245 # ɢ - small capital g - voiced uvular plosive
+noback sign \x0294 23 # ʔ - glottal stop - glottal plosive
+noback sign \x0271 235-134 # ɱ - left-tail m (at right) - voiced labiodental nasal
+noback sign \x0273 256-1345 # ɳ - right-tail n - voiced retroflex nasal
+noback sign \x0272 123456 # ɲ - left-tail n (at left) - voiced palatal nasal
+noback sign \x014B 1246 # ŋ - eng - voiced velar nasal
+noback sign \x0274 35-1345 # ɴ - small capital n - voiced uvular nasal
+noback sign \x0299 35-12 # ʙ - small capital b - voiced bilabial trill
+noback sign \x0280 35-1235 # ʀ - small capital r - voiced uvular trill
+noback sign \x027E 235-1235 # ɾ - fish-hook r - voiced alveolar tap
+noback sign \x027D 256-1235 # ɽ - right-tail r - voiced retroflex flap
+noback sign \x0278 46-124 # ɸ - 'phi' (latin small letter phi) - voiceless bilabial fricative (IPA Extensions here, greek phi is \x03D5)
+noback sign \x00F0 12456 # ð - edh - voiced dental fricative
+noback sign \x0283 156 # ʃ - esh - voiceless postalveolar fricative
+noback sign \x0292 2346 # ʒ - ezh - voiced postalveolar fricative
+noback sign \x0282 256-234 # ʂ - right-tail s (at left) - voiceless retroflex fricative
+noback sign \x0290 256-1356 # ʐ - right-tail z - voiced retroflex fricative
+noback sign \x029D 236-245 # ʝ - curly-tail j - voiced palatal fricative
+noback sign \x0263 46-1245 # ɣ - 'gamma' (latin small letter gamma) - voiced velar fricative (IPA Extensions here, greek gamma is \x03B3)
+noback sign \x0281 35-3456 # ʁ - inverted small capital r - voiced uvular fricative
+noback sign \x0127 235-125 # ħ - barred h - voiceless pharyngeal fricative
+noback sign \x0295 235-23 # ʕ - reversed glottal stop - voiced pharyngeal fricative or approximant
+noback sign \x0266 236-125 # ɦ - hooktop h - voiced glottal fricative
+noback sign \x026C 236-123 # ɬ - belted l - voiceless alveolar lateral fricative
+noback sign \x026E 123-5-2346 # ɮ - l-ezh ligature - voiced alveolar lateral fricative
+noback sign \x028B 236-1236 # ʋ - script v - voiced labiodental approximant
+noback sign \x0279 3456 # ɹ - turned r - voiced alveolar approximant
+noback sign \x027B 256-3456 # ɻ - turned r, right tail - voiced retroflex approximant
+noback sign \x0270 236-134 # ɰ - turned m, right leg - voiced velar approximant
+noback sign \x026D 256-123 # ɭ - right-tail l - voiced retroflex lateral approximant
+noback sign \x028E 236-13456 # ʎ - turned y - voiced palatal lateral approximant
+noback sign \x029F 35-123 # ʟ - small capital l - voiced velar lateral approximant
+
+
+#--------NON-PULMONIC CONSONANTS--------
+# UNICODE DOTS # GLYPH - TYPOGRAPHIC DESC. - ARTICULATORY DESC.
+noback sign \x0253 236-12 # ɓ - hooktop b - voiced bilabial implosive
+noback sign \x0257 236-145 # ɗ - hooktop d - voiced dental/alveolar implosive
+noback sign \x0284 236-35-245 # ʄ - hooktop barred dotless j - voiced palatal implosive
+noback sign \x0260 236-1245 # ɠ - hooktop g - voiced velar implosive
+noback sign \x029B 236-35-1245 # ʛ - hooktop small capital g - voiced uvular implosive
+noback sign \x0298 12346-1234 # ʘ - bull's eye - bilabial click
+noback sign \x01C0 12346-1456 # ǀ - pipe - dental click
+noback sign \x01C3 12346-2345 # ǃ - exclamation point - (post-)alveolar click
+noback sign \x01C2 12346-156 # ǂ - double-barred pipe - palatoalveolar click
+noback sign \x01C1 12346-123 # ǁ - double pipe - alveolar lateral click
+
+
+#--------OTHER PULMONIC CONSONANTS--------
+# UNICODE DOTS # GLYPH - TYPOGRAPHIC DESC. - ARTICULATORY DESC.
+noback sign \x028D 235-2456 # ʍ - turned w - voiceless labial-velar fricative
+noback sign \x0265 256-125 # ɥ - turned h - voiced labial-palatal approximant
+noback sign \x029C 35-125 # ʜ - small capital h - voiceless epiglottal fricative
+noback sign \x02A1 236-23 # ʡ - barred glottal stop - epiglottal plosive
+noback sign \x02A2 35-23 # ʢ - barred reversed glottal stop - voiced epiglottal fricative
+noback sign \x0267 236-1246 # ɧ - hooktop heng - simultaneous voiceless postalveolar and velar fricative
+noback sign \x027A 236-3456 # ɺ - turned long-leg r - voiced alveolar lateral flap
+noback sign \x0255 236-14 # ɕ - curly-tail c - voiceless alveolopalatal fricative
+noback sign \x0291 236-1356 # ʑ - curly-tail z - voiced alveolopalatal fricative
+noback sign \x026B 235-123 # ɫ - lowercase l with tilde - velarized voiced alveolar lateral approximant
+
+
+#--------VOWELS--------
+# UNICODE DOTS # GLYPH - TYPOGRAPHIC DESC. - ARTICULATORY DESC.
+noback sign \x025B 345 # ɛ - 'epsilon' (latin small letter open e) - open-mid front unrounded vowel (IPA Extensions here, greek epsilon is \x03B5)
+noback sign \x0251 16 # ɑ - script a - open back unrounded vowel
+noback sign \x0254 126 # ɔ - open o - open-mid back rounded vowel
+noback sign \x0276 35-246 # ɶ - small capital o-e ligature - open front rounded vowel
+noback sign \x0252 235-16 # ɒ - turned script a - open back rounded vowel
+noback sign \x028C 346 # ʌ - turned v (caret) - open-mid back unrounded vowel
+noback sign \x0264 235-135 # ɤ - ram's horns - close-mid back unrounded vowel
+noback sign \x026F 235-136 # ɯ - turned m - close back unrounded vowel
+noback sign \x0268 356-24 # ɨ - barred i - close central unrounded vowel
+noback sign \x0289 356-136 # ʉ - barred u - close central rounded vowel
+noback sign \x026A 34 # ɪ - small capital i - near-close near-front unrounded vowel
+noback sign \x028F 35-13456 # ʏ - small capital y - near-close near-front rounded vowel
+noback sign \x028A 12356 # ʊ - 'upsilon' (latin small letter upsilon) - near-close near-back rounded vowel (IPA Extensions here, greek upsilon is \x03C5)
+noback sign \x0259 26 # ə - schwa - mid central vowel
+noback sign \x0275 356-135 # ɵ - barred o - close-mid central rounded vowel
+noback sign \x0250 235-1 # ɐ - turned a - near-open central vowel
+noback sign \x025C 235-345 # ɜ - reversed epsilon - open-mid central unrounded vowel
+noback sign \x025A 26-5-1235 # ɚ - right-hook schwa - r-colored mid central vowel
+noback sign \x025E 236-345 # ɞ - closed reversed epsilon - open-mid central rounded vowel
+noback sign \x0258 235-15 # ɘ - reversed e - close-mid central unrounded vowel
+
+
+#--------DIACRITICS--------
+# UNICODE DOTS # GLYPH - TYPOGRAPHIC DESC. - ARTICULATORY DESC.
+noback sign \x02BC 5-3 # ʼ - apostrophe - ejective
+noback sign \x0325 6-1246 # ̥ - ring below - voiceless
+noback sign \x030A 4-1246 # ̊ - ring above - voiceless
+noback sign \x02B0 4-125 # ʰ - superscript h - aspirated
+noback sign \x0324 6-25 # ̤ - umlaut below - breathy voiced
+noback sign \x0330 6-12456 # ̰ - tilde below - creaky voiced
+noback sign \x033C 6-12346 # ̼ - seagull below - linguolabial
+noback sign \x032A 6-1456 # ̪ - bridge below - dental
+noback sign \x033A 6-235-1456 # ̺ - inverted bridge below - apical
+noback sign \x033B 6-2356 # ̻ - square below - laminal
+noback sign \x0339 6-135 # ̹ - right half-ring below - more rounded
+noback sign \x031C 6-246 # ̜ - left half-ring below - less rounded
+noback sign \x031F 6-346 # ̟ - plus below - advanced
+noback sign \x0320 6-36 # ̠ - minus below - retracted
+noback sign \x0308 4-25 # ̈ - umlaut above - centralized
+noback sign \x033D 4-1346 # ̽ - over-cross above - mid-centralized
+noback sign \x0318 6-156 # ̘ - advancing sign below - advanced tongue root
+noback sign \x0319 6-234 # ̙ - retracting sign below - retracted tongue root
+noback sign \x02DE 5-1235 # ˞ - right hook - rhoticity
+noback sign \x02B7 4-2456 # ʷ - superscript w - labialized
+noback sign \x02B2 4-245 # ʲ - superscript j - palatalized
+noback sign \x02E0 4-46-1245 # ˠ - superscript gamma - velarized
+noback sign \x02E4 4-235-23 # ˤ - superscript reversed glottal stop - pharyngealized
+noback sign \x0303 4-12456 # ̃ - tilde above - nasalized
+noback sign \x207F 4-1345 # ⁿ - superscript n - nasal release
+noback sign \x02E1 4-123 # ˡ - superscript l - lateral release
+noback sign \x031A 4-145 # ̚ - corner above - no audible release
+noback sign \x0334 5-12456 # ̴ - superimposed tilde - velarized or pharyngealized
+noback sign \x031D 6-345 # ̝ - raising sign below - raised
+noback sign \x031E 6-126 # ̞ - lowering sign below - lowered
+noback sign \x0329 6-23 # ̩ - vertical line below - syllabic
+noback sign \x0361 5 # ͡ - top tie bar - affricate or double articulation
+
+
+#--------SUPRASEGMENTALS--------
+# UNICODE DOTS # GLYPH - TYPOGRAPHIC DESC. - ARTICULATORY DESC.
+noback sign \x02C8 456-12 # ˈ - vertical stroke (superior) - (primary) stress
+noback sign \x02CC 456-23 # ˌ - vertical stroke (inferior) - secondary stress
+noback sign \x02D0 25 # ː - length mark - long
+noback sign \x02D1 5-2 # ˑ - half-length mark - half-long
+noback sign \x0306 4-12356 # ̆ - breve above - extra-short
+noback sign \x203F 456-123 # ‿ - bottom tie bar - linking (absence of a break)
+
+
+#--------TONES AND WORD ACCENTS--------
+# UNICODE DOTS # GLYPH - TYPOGRAPHIC DESC. - ARTICULATORY DESC.
+noback sign \x030B 4-6-34 # ̋ - double acute accent above - extra high level tone
+noback sign \x0301 4-34 # ́ - acute accent above - high level tone
+noback sign \x0304 4-14 # ̄ - macron above - mid level tone
+noback sign \x0300 4-16 # ̀ - grave accent above - low level tone
+noback sign \x030F 4-6-16 # ̏ - double grave accent above - extra low level tone
+noback sign \x030C 4-236 # ̌ - wedge above - rising contour tone
+noback sign \x0302 4-146 # ̂ - circumflex above - falling contour tone
+noback sign \x1DC4 4-24 # ᷄ (UTF-16) - macron-acute above - high -rising contour tone
+noback sign \x1DC5 4-35 # ᷅ (UTF-16) - grave-macron above - low-rising contour tone
+noback sign \x1DC8 4-256 # ᷈ (UTF-16) - grave-acute- grave above - rising-falling contour tone
+noback sign \xF19D 456-2346 # - down arrow - downstep
+noback sign \x02E5 456-4-14 # ˥ - extra-high (55) tone bar - extra high level tone
+noback sign \x02E6 456-14 # ˦ - high (44) tone bar - high level tone
+noback sign \x02E7 456-25 # ˧ - mid (33) tone bar - mid level tone
+noback sign \x02E8 456-36 # ˨ - low (22) tone bar - low level tone
+noback sign \x02E9 456-6-36 # ˩ - extra-low (11) tone bar - extra low level tone
diff --git a/tables/IPA.utb b/tables/IPA.utb
new file mode 100644
index 0000000..7df34de
--- /dev/null
+++ b/tables/IPA.utb
@@ -0,0 +1,135 @@
+# liblouis: International Phonetic Alphabet
+
+# Copyright (C) 2016 Ludovic Oger <oger.ludovic@gmail.com>
+
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+
+# This table contains braille codes for a part of the International Phonetic Alphabet (IPA, 2005).
+# WARNING! The IPA symbols in this table might conflict with other tables. (e.g. conflict: θ
+# (Unicode 03B8) is the greek letter theta, french braille code is different between greek
+# and phonetic)
+# WARNING! This table is not intended to be included in other tables. The symbol definitions that
+# are safe to include in other tables are collected in IPA-unicode-range.uti.
+
+
+# --------REFERENCES--------
+# - IPA Braille: An Updated Tactile Representation of the International Phonetic Alphabet
+# Print Edition
+# Edited by Robert Englebretson, Ph.D.
+# Produced by CNIB
+# For the International Council on English Braille - 2008
+# <http://www.iceb.org/icebipa.htm>
+# (this reference document is reprinted in 'World Braille Usage - Third Edition - 2013 - Copyright (C) 1954, 1990 UNESCO')
+#
+# - "IPA Chart, http://www.internationalphoneticassociation.org/content/ipa-chart,
+# available under a Creative Commons Attribution-Sharealike 3.0 Unported License.
+# Copyright (C) 2015 International Phonetic Association."
+
+
+#--------NOTES--------
+# This table includes:
+# - Symbols defined in IPA-unicode-range.uti
+# - Characters include in latinLetterDef6Dots.uti table (a, b, c...).
+# - Some current symbols (e.g. point '.')
+# - 'Phonetic and Phonemic Enclosures'
+# Some lines are commented for reference:
+# - Tricky character compositions, see end of 'Tones and Word Accents'
+# Some IPA unicode symbols are not present in the reference document so there is no braille equivalent.
+# Example: \x02D4 for 'MODIFIER LETTER UP TACK',
+# see <http://unicode.org/cldr/utility/list-unicodeset.jsp?a=\p{subhead=Miscellaneous%20phonetic%20modifiers}>
+
+
+# Last updated on January 23, 2018
+
+# IPA symbols that do not conflict with other tables
+include IPA-unicode-range.uti
+sign \x032C 6-236 # ̬ - wedge below - voiced
+sign \x032F 6-23456 # ̯ - arch below - non-syllabic
+sign \x2016 456-123456 # ‖ - double vertical line - major (intonation) group
+sign \x2197 456-145 # ↗ - upward diagonal arrow - global rise
+sign \x2198 456-356 # ↘ - downward diagonal arrow - global fall
+sign \xF19C 456-1246 # - up arrow - upstep
+sign \x2193 456-2346 # ↓ - down arrow - downstep
+sign \x2191 456-1246 # ↑ - up arrow - upstep
+
+#--------PULMONIC CONSONANTS--------
+# UNICODE DOTS # GLYPH - TYPOGRAPHIC DESC. - ARTICULATORY DESC.
+sign \x0070 1234 # p - lowercase p - voiceless bilabial plosive
+sign \x0062 12 # b - lowercase b - voiced bilabial plosive
+sign \x0074 2345 # t - lowercase t - voiceless alveolar plosive
+sign \x0064 145 # d - lowercase d - voiced alveolar plosive
+sign \x0063 14 # c - lowercase c - voiceless palatal plosive
+sign \x006B 13 # k - lowercase k - voiceless velar plosive
+sign \x0067 1245 # g - lowercase g - voiced velar plosive (alternate glyph)
+sign \x0071 12345 # q - lowercase q - voiceless uvular plosive
+sign \x006D 134 # m - lowercase m - voiced bilabial nasal
+sign \x006E 1345 # n - lowercase n - voiced alveolar nasal
+sign \x0072 1235 # r - lowercase r - voiced alveolar trill
+sign \x2C71 235-1236 # ⱱ (UTF-16) - right-hook v - labiodental flap
+sign \xF25F 235-1236 # (UTF-16) - right-hook v - labiodental flap
+sign \x03B2 46-12 # β - beta - voiced bilabial fricative (WARNING: greek letter)
+sign \x0066 124 # f - lowercase f - voiceless labiodental fricative
+sign \x0076 1236 # v - lowercase v - voiced labiodental fricative
+sign \x03B8 46-1456 # θ - theta - voiceless dental fricative (WARNING: greek letter)
+sign \x0073 234 # s - lowercase s - voiceless alveolar fricative
+sign \x007A 1356 # z - lowercase z - voiced alveolar fricative
+sign \x00E7 235-14 # ç - c cedilla - voiceless palatal fricative
+sign \x0078 1346 # x - lowercase x - voiceless velar fricative
+sign \x03C7 46-12346 # χ - chi - voiceless uvular fricative (WARNING: greek letter)
+sign \x0068 125 # h - lowercase h - voiceless glottal fricative
+sign \x006A 245 # j - lowercase j - voiced palatal approximant
+sign \x006C 123 # l - lowercase l - voiced alveolar lateral approximant
+
+
+#--------OTHER PULMONIC CONSONANTS--------
+# UNICODE DOTS # GLYPH - TYPOGRAPHIC DESC. - ARTICULATORY DESC.
+sign \x0077 2456 # w - lowercase w - voiced labial-velar approximant
+
+
+#--------VOWELS--------
+# UNICODE DOTS # GLYPH - TYPOGRAPHIC DESC. - ARTICULATORY DESC.
+sign \x0069 24 # i - lowercase i - close front unrounded vowel
+sign \x0065 15 # e - lowercase e - close-mid front unrounded vowel
+sign \x0061 1 # a - lowercase a - open front unrounded vowel
+sign \x006F 135 # o - lowercase o - close-mid back rounded vowel
+sign \x0075 136 # u - lowercase u - close back rounded vowel
+sign \x0079 13456 # y - lowercase y - close front rounded vowel
+sign \x00F8 1256 # ø - slashed o - close-mid front rounded vowel
+sign \x0153 246 # œ - lowercase o-e ligature - open-mid front rounded vowel
+sign \x00E6 146 # æ - ash - near-open front unrounded vowel
+
+
+#--------SUPRASEGMENTALS--------
+# UNICODE DOTS # GLYPH - TYPOGRAPHIC DESC. - ARTICULATORY DESC.
+sign \x002E 3 # . - full stop - syllable break
+sign \x007C 456-1256 # | - vertical line - minor (foot) group
+
+#--------TONES AND WORD ACCENTS--------
+# UNICODE DOTS # GLYPH - TYPOGRAPHIC DESC. - ARTICULATORY DESC.
+# The following lines seems tricky (https://en.wikipedia.org/wiki/Tone_letter)
+# sign \x02E9 + \x02E5 456-34 # ˩˥ - rising (15) tone bar - rising contour tone
+# sign \x02E9 + \x02E7 456-35 # ˩˧ - low-rising (13) tone bar - low-rising contour tone
+# sign \x02E7 + \x02E5 456-24 # ˧˥ - high-rising (35) tone bar - high-rising contour tone
+# sign \x02E5 + \x02E9 456-16 # ˥˩ - falling (51) tone bar - falling contour tone
+# sign \x02E8 + \x02E5 + \x02E8 456-256 # ˨˥˨ - rising-falling (151) tone bar - rising-falling contour tone
+
+#--------PHONETIC AND PHONEMIC ENCLOSURES--------
+sign \x005B 45-12356 # [ - left square bracket - begin phonetic transcription
+sign \x005D 45-23456 # ] - right square bracket - end phonetic transcription
+sign \x002F 45-34 # / - slash - begin/end phonemic transcription
diff --git a/tables/Lv-Lv-g1.utb b/tables/Lv-Lv-g1.utb
new file mode 100644
index 0000000..2d3b3ad
--- /dev/null
+++ b/tables/Lv-Lv-g1.utb
@@ -0,0 +1,462 @@
+# liblouis: Latvian Grade 1 Braille Table
+#
+# Copyright (C) 2004-2008 ViewPlus Technologies, Inc. www.viewplus.com
+# Copyright (C) 2004-2006 JJB Software, Inc. www.jjb-software.com
+# Copyright (C) 2012 Mesar Hameed <mesar.hameed@gmail.com>
+# Copyright (C) 2018-2019 Bert Frees
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# Created & maintained by Leon Ungier <Leon.Ungier@ViewPlus.com>.
+
+# Modifications done by Bert Frees based on input from Gatis Grintals
+# and Artis Raugulis.
+
+include text_nabcc.dis
+
+space \x00a0 a
+include spaces.uti
+
+# ----------- define all chars --------------------------------------
+
+punctuation ! 235 exclamation sign x0021
+punctuation " 356 double quote x0022
+sign # 3456 number sign x0023
+sign $ 4-256 dollar sign x0024
+math % 3456-245-356 percent sign x0025
+sign & 4-12346 ampersand z0026
+punctuation ' 3 apostrophe x0027
+punctuation ( 2356 left parenthesis x0028
+punctuation ) 2356 right parenthesis x0029
+sign * 35 asterisk x002A
+math + 235 plus 002B
+punctuation , 2 coma 002C
+punctuation - 36 hyphen-minus 002D
+punctuation . 256 point 002E
+math / 34 solidus 002F
+
+punctuation : 25 colon x003A
+punctuation ; 23 semicolon x003B
+punctuation < 246 less-than sign x003C
+math = 2356 equal sign x003D
+punctuation ? 26 question mark x003F
+sign @ 4 commercial at x0040
+
+uplow \x0100\x0101 16 letter A with macron
+uplow \x010C\x010D 146 letter C with caron
+uplow \x0112\x0113 156 letter E with macron
+uplow \x0122\x0123 12456 letter g with cedilla
+uplow \x012A\x012B 246 letter I with macron
+uplow \x0136\x0137 136 letter K with cedilla
+uplow \x013B\x013C 1236 letter L with cedilla
+uplow \x0145\x0146 13456 Letter N with cedilla
+uplow \x014C\x014D 1356 letter O with macron
+uplow \x0156\x0157 12356 letter R with cedilla
+uplow \x0160\x0161 2346 letter S with caron
+uplow \x016A\x016B 346 letter U with macron
+uplow \x017D\x017E 3456 letter Z with caron
+
+# define the dot combinations that are different from the default: U, V and Z
+# these definitions need to be placed before AND after the "latinLetterDef6Dots" include
+# in order for both the lower- and uppercase part to take precedence
+# see issue https://github.com/liblouis/liblouis/issues/384
+uplow Uu 34
+uplow Vv 2456
+uplow Zz 345
+include latinLetterDef6Dots.uti
+include digits6Dots.uti # Must come after letters.
+include litdigits6Dots.uti # Must come after letters.
+uplow Uu 34
+uplow Vv 2456
+uplow Zz 345
+
+math > 135 greater-than sign x003E
+punctuation [ 12356 left square bracket x005B
+sign \\ 56-36 reverse solidus x005C
+punctuation ] 23456 right square bracket x005D
+sign ^ 46 circumflex accent x005E
+sign _ 6 low line x005F
+sign ` 3 grave accent x0060
+
+# a - z # 97 - 122 x0061-x007A
+
+punctuation { 12346 left curly bracket x007B
+sign | 456 vertical line x007C
+punctuation } 13456 right curly bracket x007D
+math ~ 25-25 tilde x007E
+sign \x0080 15-136-1235-135 x0080
+
+sign ¢ 4-14 cent sign x00A2
+sign £ 4-123 pound sign x00A3
+sign ¤ 45-15 currency sign x00A4
+sign ¥ 45-13456 yen sign x00A5
+sign € 4-15 euro sign x20AC
+sign § 346 section sign x00A7
+sign © 2356-6-14-2356 copyright x00A9
+punctuation « 236 left-pointing double angle quotation x00AB
+punctuation ¬ 1256 not sign x00AC
+punctuation \x00AD 36 soft hyphen
+sign ° 356 degree sign x00B0
+sign ² 4-6-126 superscript 2 sign x00B2
+sign ³ 4-6-146 superscript 3 sign x00B3
+sign µ 46-134 micro sign x00B5
+sign ¶ 1456 pilcrow sign (paragraph) x00B6
+sign ¹ 156 superscript 1 sign x00B9
+punctuation » 356 right-pointing double angle quotation x00BB
+math ¼ 6-16-34-1456 vulgar fraction one quarter x00BC
+math ½ 6-16-34-126 vulgar fraction one half x00BD
+math ¾ 6-126-34-1456 vulgar fraction 3 quarters x00BE
+
+
+
+uplow \x00C0\x00E0 12356 letter a with grave x00C0 / 00E0
+uplow \x00C1\x00E1 16 letter a with acute x00E1
+uplow \x00C2\x00E2 16 letter a with circumflex x00E2
+uplow \x00C3\x00E3 126 letter a with tilde x00E3
+uplow Ää 1356 A with diaeresis x00C4 / 00E4
+uplow Åå 16 A with ring above x00C5 / 00E5
+uplow \x00C6\x00E6 456 ae x00C6
+uplow Çç 12346 letter c with cedilla x00C7 / 00E7
+uplow Èè 2346 e with grave x00C8 / 00E8
+uplow \x00C9\x00E9 123456 e with acute x00E9
+uplow \x00CA\x00EA 126 e with circumflex x00EA
+uplow \x00CB\x00EB 1246 e with diaeresis x00EB
+uplow \x00CD\x00ED 34 i with acute x00ED
+uplow \x00CE\x00EE 146 i with circumflex x00EE
+uplow \x00CF\x00EF 12456 i with diaeresis x00CF / 00EF
+
+uplow \x00D3\x00F3 246 O with acute x00D3 / 00F3
+uplow \x00D4\x00F4 1456 o with circumflex x00F4
+uplow \x00D5\x00F5 246 o with tilde x00F5
+uplow Öö 246 O with diaeresis x00D6 / 00F6
+math × 236 multiplication sign x00D7
+uplow \x00D8\x00F8 246 o with stroke x00D8 / 00F8
+
+math ÷ 256 division sign x00F7
+
+uplow \x00DA\x00FA 346 u with acute x00DA / 00FA
+uplow \x00DB\x00FB 156 u with circumflex x00FB
+uplow \x00DC\x00FC 1256 u with diaeresis x00FC
+uplow \x00DD\x00FD 12346 y with acute x00DD / 00FD
+
+noback sign \x25CF 35-35 black circle
+
+# the letter a with ogonek -----------------------------------
+uplow \x0104\x0105 16
+
+# the letter c with acute
+uplow \x0106\x0107 146
+
+uplow \x010C\x010D 146 C with caron
+uplow \x010E\x010F 1456 D with caron
+
+
+# the letter e with ogonek
+uplow \x0118\x0119 156
+
+uplow \x011A\x011B 126 E with caron
+
+lowercase \x012F 1246 I with ogonek
+
+# the letter l with stroke
+uplow \x0141\x0142 126
+
+# the letter n with acute
+uplow \x0143\x0144 1456
+uplow \x0147\x0148 1246 N with caron
+
+uplow \x0158\x0159 2456 R with caron
+
+# the letter s with acute
+uplow \x015A\x015B 246
+
+uplow \x0164\x0165 1256 T with caron
+uplow \x016C\x016D 23456 U with breve
+uplow \x016E\x016F 23456 U with ring above
+
+
+# the letter z with acute
+uplow \x0179\x017A 2346
+
+# the letter z with dot above
+uplow \x017B\x017C 12346
+
+# Russian letters
+letter \x0410 1 # 1040 cyrillic capital letter a А
+letter \x0430 1 # 1072 cyrillic small letter a а
+letter \x0411 12 # 1041 cyrillic capital letter be Б
+letter \x0431 12 # 1073 cyrillic small letter be б
+letter \x0412 2456 # 1042 cyrillic capital letter ve В
+letter \x0432 2456 # 1074 cyrillic small letter ve в
+letter \x0413 1245 # 1043 cyrillic capital letter ghe Г
+letter \x0433 1245 # 1075 cyrillic small letter ghe г
+letter \x0414 145 # 1044 cyrillic capital letter de Д
+letter \x0434 145 # 1076 cyrillic small letter de д
+letter \x0415 15 # 1045 cyrillic capital letter ie Е
+letter \x0435 15 # 1077 cyrillic small letter ie е
+letter \x0401 16 # 1025 cyrillic capital letter io Ё
+letter \x0451 16 # 1105 cyrillic small letter io ё
+letter \x0416 245 # 1046 cyrillic capital letter zhe Ж
+letter \x0436 245 # 1078 cyrillic small letter zhe ж
+letter \x0417 1356 # 1047 cyrillic capital letter ze З
+letter \x0437 1356 # 1079 cyrillic small letter ze з
+letter \x0418 24 # 1048 cyrillic capital letter i И
+letter \x0438 24 # 1080 cyrillic small letter i и
+letter \x0419 12346 # 1049 cyrillic capital letter short i Й
+letter \x0439 12346 # 1081 cyrillic small letter short i й
+letter \x041a 13 # 1050 cyrillic capital letter ka К
+letter \x043a 13 # 1082 cyrillic small letter ka к
+letter \x041b 123 # 1051 cyrillic capital letter el Л
+letter \x043b 123 # 1083 cyrillic small letter el л
+letter \x041c 134 # 1052 cyrillic capital letter em М
+letter \x043c 134 # 1084 cyrillic small letter em м
+letter \x041d 1345 # 1053 cyrillic capital letter en Н
+letter \x043d 1345 # 1085 cyrillic small letter en н
+letter \x041e 135 # 1054 cyrillic capital letter o О
+letter \x043e 135 # 1086 cyrillic small letter o о
+letter \x041f 1234 # 1055 cyrillic capital letter pe П
+letter \x043f 1234 # 1087 cyrillic small letter pe п
+letter \x0420 1235 # 1056 cyrillic capital letter er Р
+letter \x0440 1235 # 1088 cyrillic small letter er р
+letter \x0421 234 # 1057 cyrillic capital letter es С
+letter \x0441 234 # 1089 cyrillic small letter es с
+letter \x0422 2345 # 1058 cyrillic capital letter te Т
+letter \x0442 2345 # 1090 cyrillic small letter te т
+letter \x0423 136 # 1059 cyrillic capital letter u У
+letter \x0443 136 # 1091 cyrillic small letter u у
+letter \x0424 124 # 1060 cyrillic capital letter ef Ф
+letter \x0444 124 # 1092 cyrillic small letter ef ф
+letter \x0425 125 # 1061 cyrillic capital letter ha Х
+letter \x0445 125 # 1093 cyrillic small letter ha х
+letter \x0426 14 # 1062 cyrillic capital letter tse Ц
+letter \x0446 14 # 1094 cyrillic small letter tse ц
+letter \x0427 12345 # 1063 cyrillic capital letter che Ч
+letter \x0447 12345 # 1095 cyrillic small letter che ч
+letter \x0428 156 # 1064 cyrillic capital letter sha Ш
+letter \x0448 156 # 1096 cyrillic small letter sha ш
+letter \x0429 1346 # 1065 cyrillic capital letter shcha Щ
+letter \x0449 1346 # 1097 cyrillic small letter shcha щ
+letter \x042a 12356 # 1066 cyrillic capital letter hard sign Ъ
+letter \x044a 12356 # 1098 cyrillic small letter hard sign ъ
+letter \x042b 2346 # 1067 cyrillic capital letter yeru Ы
+letter \x044b 2346 # 1099 cyrillic small letter yeru ы
+letter \x042c 23456 # 1068 cyrillic capital letter soft sign Ь
+letter \x044c 23456 # 1100 cyrillic small letter soft sign ь
+letter \x042d 246 # 1069 cyrillic capital letter e Э
+letter \x044d 246 # 1101 cyrillic small letter e э
+letter \x042e 1256 # 1070 cyrillic capital letter yu Ю
+letter \x044e 1256 # 1102 cyrillic small letter yu ю
+letter \x042f 1246 # 1071 cyrillic capital letter ya Я
+letter \x044f 1246 # 1103 cyrillic small letter ya я
+
+# Greek letters
+letter \x0391 1 # 913 greek capital letter alpha Α
+letter \x03b1 1 # 945 greek small letter alpha α
+letter \x0392 12 # 914 greek capital letter beta Β
+letter \x03b2 12 # 946 greek small letter beta β
+letter \x0393 1245 # 915 greek capital letter gamma Γ
+letter \x03b3 1245 # 947 greek small letter gamma γ
+letter \x0394 145 # 916 greek capital letter delta Δ
+letter \x03b4 145 # 948 greek small letter delta δ
+letter \x0395 15 # 917 greek capital letter epsilon Ε
+letter \x03b5 15 # 949 greek small letter epsilon ε
+letter \x0396 1356 # 918 greek capital letter zeta Ζ
+letter \x03b6 1356 # 950 greek small letter zeta ζ
+letter \x0397 156 # 919 greek capital letter eta Η
+letter \x03b7 156 # 951 greek small letter eta η
+letter \x0398 1456 # 920 greek capital letter theta Θ
+letter \x03b8 1456 # 952 greek small letter theta θ
+letter \x0399 24 # 921 greek capital letter iota Ι
+letter \x03b9 24 # 953 greek small letter iota ι
+letter \x039a 13 # 922 greek capital letter kappa Κ
+letter \x03ba 13 # 954 greek small letter kappa κ
+letter \x039b 123 # 923 greek capital letter lamda Λ
+letter \x03bb 123 # 955 greek small letter lamda λ
+letter \x039c 134 # 924 greek capital letter mu Μ
+letter \x03bc 134 # 956 greek small letter mu μ
+letter \x039d 1345 # 925 greek capital letter nu Ν
+letter \x03bd 1345 # 957 greek small letter nu ν
+letter \x039e 1346 # 926 greek capital letter xi Ξ
+letter \x03be 1346 # 958 greek small letter xi ξ
+letter \x039f 135 # 927 greek capital letter omicron Ο
+letter \x03bf 135 # 959 greek small letter omicron ο
+letter \x03a0 1234 # 928 greek capital letter pi Π
+letter \x03c0 1234 # 960 greek small letter pi π
+letter \x03a1 1235 # 929 greek capital letter rho Ρ
+letter \x03c1 1235 # 961 greek small letter rho ρ
+letter \x03a3 234 # 931 greek capital letter sigma Σ
+letter \x03c2 234 # 962 greek small letter final sigma ς
+letter \x03c3 234 # 963 greek small letter sigma σ
+letter \x03a4 2345 # 932 greek capital letter tau Τ
+letter \x03c4 2345 # 964 greek small letter tau τ
+letter \x03a5 136 # 933 greek capital letter upsilon Υ
+letter \x03c5 136 # 965 greek small letter upsilon υ
+letter \x03a6 124 # 934 greek capital letter phi Φ
+letter \x03c6 124 # 966 greek small letter phi φ
+letter \x03a7 12346 # 935 greek capital letter chi Χ
+letter \x03c7 12346 # 967 greek small letter chi χ
+letter \x03a8 13456 # 936 greek capital letter psi Ψ
+letter \x03c8 13456 # 968 greek small letter psi ψ
+letter \x03a9 2456 # 937 greek capital letter omega Ω
+letter \x03c9 2456 # 969 greek small letter omega ω
+
+punctuation \x2010 36 # 8208 hyphen
+punctuation \x2011 36 # 8209 non-breaking hyphen
+punctuation \x2013 36 # 8211 smart minus sign
+punctuation \x2212 36 # 8722 minus sign
+punctuation \x2014 25 # 8212 em dash
+punctuation \x2018 23 # 8216 smart single left quotation mark
+punctuation \x2019 56 # 8217 smart single right quotation mark
+
+punctuation \x201C 236 # 8220 smart opening double quote
+punctuation \x201D 356 # 8221 smart closing double quote
+punctuation \x201E 236 # 8222 smart double low quotation mark
+punctuation \x201F 356 # 8223 smart double high reverse quotation mark
+punctuation \x2020 126 # 8224 dagger
+punctuation \x2022 5 # 8226 bullet
+punctuation \x2026 256-256-256 # 8230 smart ellipsis
+
+math \x2030 3456-245-356-356 # 8240 promille
+
+sign \x00af 46-25 # 175 macron ¯
+sign \x00b1 235-36 # 177 plus-minus sign ±
+sign \x02b9 5-35 # 697 modifier letter prime ʹ
+sign \x02ba 5-35-35 # 698 modifier letter double prime ʺ
+sign \x1d17 456-345 # 7447 latin small letter bottom half o ᴗ
+sign \x2032 35 # 8242 prime ′
+sign \x2044 1256 # 8260 fraction slash ⁄
+sign \x2081 156 # 8321 subscript one ₁
+sign \x20d1 45-25-2 # 8401 combining right harpoon above ⃑
+sign \x20d7 25-2 # 8407 combining right arrow above ⃗
+sign \x211c 6-1235 # 8476 black-letter capital r ℜ
+sign \x2192 25-135 # 8594 rightwards arrow →
+sign \x21c5 34-16 # 8645 upwards arrow leftwards of downwards arrow ⇅
+sign \x21c8 34-34 # 8648 upwards paired arrows ⇈
+sign \x21d2 2356-345 # 8658 rightwards double arrow ⇒
+sign \x21d4 126-2356-345 # 8660 left right double arrow ⇔
+sign \x2205 4-356 # 8709 empty set ∅
+sign \x2206 456-145 # 8710 increment ∆
+sign \x2208 5-246 # 8712 element of ∈
+sign \x2209 45-246 # 8713 not an element of ∉
+sign \x2211 456-234 # 8721 n-ary summation ∑
+sign \x2215 456-123 # 8725 division slash ∕
+sign \x2217 123456 # 8727 asterisk operator ∗
+sign \x2218 3456-356 # 8728 ring operator ∘
+sign \x221a 146-156 # 8730 square root √
+sign \x221b 146 # 8731 cube root ∛
+sign \x221e 12456 # 8734 infinity ∞
+sign \x2222 456-246 # 8738 spherical angle ∢
+sign \x2223 123 # 8739 divides ∣
+sign \x2225 123-123 # 8741 parallel to ∥
+sign \x2226 4-123-123 # 8742 not parallel to ∦
+sign \x2229 56-256 # 8745 intersection ∩
+sign \x222a 56-356 # 8746 union ∪
+sign \x222b 2346 # 8747 integral ∫
+sign \x2236 5-25 # 8758 ratio ∶
+sign \x223e 456-1456 # 8766 inverted lazy s ∾
+sign \x2245 26-2356 # 8773 approximately equal to ≅
+sign \x2248 46-2356 # 8776 almost equal to ≈
+sign \x2248 46-2356 # 8776 almost equal to ≈
+sign \x2260 4-2356 # 8800 not equal to ≠
+sign \x2264 246-2356 # 8804 less-than or equal to ≤
+sign \x2265 135-2356 # 8805 greater-than or equal to ≥
+sign \x226a 246-246 # 8810 much less-than ≪
+sign \x226b 135-135 # 8811 much greater-than ≫
+sign \x2282 12346 # 8834 subset of ⊂
+sign \x2283 13456 # 8835 superset of ⊃
+sign \x2284 4-12346 # 8836 not a subset of ⊄
+sign \x2299 46-1235 # 8857 circled dot operator ⊙
+sign \x22a5 3456-3 # 8869 up tack ⊥
+sign \x22c5 3 # 8901 dot operator ⋅
+sign \x2300 456-1456 # 8960 diameter sign ⌀
+sign \x2502 4-16 # 9474 box drawings light vertical │
+sign \x25e1 45-256 # 9697 lower half circle ◡
+sign \xff01 12346 # 65281 fullwidth exclamation mark !
+sign \xff08 126 # 65288 fullwidth left parenthesis (
+sign \xff09 345 # 65289 fullwidth right parenthesis )
+
+# ------------------------------------------------------
+
+
+capsletter 46 # single capital letter indicator
+begcapsword 46-46 # a block of consecutive capital letters indicator
+
+
+numsign 3456 # number sign, just one operand
+midnum , 6
+midnum . 256
+midnum + 235
+# midnum - 36
+midnum / 256
+midnum : 25
+midnum = 2356
+
+# endnum # 56-3456
+
+prepunc " 236
+postpunc " 356
+
+prepunc ' 6-236
+postpunc ' 356-3
+postpunc '' 356
+postpunc ''' 356-3-356
+
+repeated *** 16-16-16
+
+prepunc `` 236
+prepunc ` 6-236
+
+
+repeated --- 36-36-36
+
+repeated ::: 25-25-25
+
+repeated ~~~ 156-156-156
+always \s-\s 36-36
+always \s-\scom 36-36-14-135-134
+always ... 3-3-3
+always .\s.\s. 3-3-3 . . .
+
+always \s\s 36-36
+
+# remove spaces after comma
+noback context _","[$s.]$l ?
+
+# special character sequences
+literal :// URLs
+literal www.
+
+literal .com
+literal .edu
+literal .gov
+literal .mil
+literal .net
+literal .org
+
+literal .doc
+literal .htm
+literal .html
+literal .tex
+literal .txt
+
+literal .gif
+literal .jpg
+literal .png
+literal .wav
+
+literal .tar
+literal .zip
diff --git a/tables/Makefile.am b/tables/Makefile.am
new file mode 100644
index 0000000..18d46dd
--- /dev/null
+++ b/tables/Makefile.am
@@ -0,0 +1,371 @@
+# generate the list of tables as follows:
+# $ ls | grep -v Makefile | grep -v README | grep -v maketablelist.sh | grep -v '.*~$' | sort -df | sed -e 's/$/ \\/' -e 's/^/ /' -e '$s/\\$//'
+table_files = \
+ afr-za-g1.ctb \
+ afr-za-g2.ctb \
+ ar-ar-g1.utb \
+ ar-ar-g2.ctb \
+ ar-ar-comp8.utb \
+ ar.tbl \
+ as-in-g1.utb \
+ as.tbl \
+ awa.tbl \
+ aw-in-g1.utb \
+ spaces.uti \
+ be-in-g1.utb \
+ bengali.cti \
+ bg.ctb \
+ bg.tbl \
+ bh.ctb \
+ bh.tbl \
+ bn.tbl \
+ bo.ctb \
+ bo.tbl \
+ boxes.ctb \
+ braille-patterns.cti \
+ bra.tbl \
+ br-in-g1.utb \
+ ca-chardefs.cti \
+ ca-g1.ctb \
+ ca.tbl \
+ en-chardefs.cti \
+ chr-us-g1.ctb \
+ ckb-chardefs.cti \
+ ckb-g1.ctb \
+ ckb.tbl \
+ ckb-translation.cti \
+ compress.cti \
+ controlchars.cti \
+ corrections.cti \
+ countries.cti \
+ cs-chardefs.cti \
+ cs-comp8.utb \
+ cs-g1.ctb \
+ cs-letterDef8Dots.uti \
+ cs.tbl \
+ cs-translation.cti \
+ cy-cy-g1.utb \
+ cy-cy-g2.ctb \
+ cy.tbl \
+ da-dk-6miscChars.cti \
+ da-dk-8miscChars.cti \
+ da-dk.dis \
+ da-dk-g08.ctb \
+ da-dk-g16.ctb \
+ da-dk-g16-lit.ctb \
+ da-dk-g18.ctb \
+ da-dk-g26.ctb \
+ da-dk-g26l.ctb \
+ da-dk-g26-lit.ctb \
+ da-dk-g26l-lit.ctb \
+ da-dk-g28.ctb \
+ da-dk-g28l.ctb \
+ da-dk-octobraille.dis \
+ da-lt.ctb \
+ de-accents.cti \
+ de-accents-detailed.cti \
+ de-chardefs6.cti \
+ de-chardefs8.cti \
+ de-chess.ctb \
+ de-de-comp8.ctb \
+ de-de.dis \
+ de-eurobrl6.dis \
+ de-eurobrl6u.dis \
+ de-g0-core.uti \
+ de-g0.utb \
+ de-g1-core.cti \
+ de-g1-core-patterns.dic \
+ de-g1.ctb \
+ de-g2-core.cti \
+ de-g2-core-patterns.dic \
+ de-g2.ctb \
+ devanagari.cti \
+ digits6DotsPlusDot6.uti \
+ digits6Dots.uti \
+ digits8Dots.uti \
+ dra.ctb \
+ dra.tbl \
+ el.ctb \
+ en_CA.ctb \
+ en_CA.tbl \
+ en-chess.ctb \
+ en-gb-comp8.ctb \
+ en-gb-g1.utb \
+ en-GB-g2.ctb \
+ en_GB.tbl \
+ en-in-g1.ctb \
+ en-nabcc.utb \
+ en-ueb-chardefs.uti \
+ en-ueb-g1.ctb \
+ en-ueb-g2.ctb \
+ en-ueb-math.ctb \
+ en-us-brf.dis \
+ en-us-comp6.ctb \
+ en-us-comp8.ctb \
+ en_US-comp8-ext.tbl \
+ en-us-comp8-ext.utb \
+ en-us-compbrl.uti \
+ en-us-g1.ctb \
+ en-us-g2.ctb \
+ en-us-interline.ctb \
+ en-us-mathtext.ctb \
+ en_US.tbl \
+ eo-g1.ctb \
+ eo-g1-x-system.ctb \
+ eo.tbl \
+ es-chardefs.cti \
+ Es-Es-G0.utb \
+ es-g1.ctb \
+ es-g2.ctb \
+ es-new.dis \
+ es-old.dis \
+ es.tbl \
+ et.ctb \
+ et-g0.utb \
+ ethio-g1.ctb \
+ et.tbl \
+ eurodefs.cti \
+ fa-ir-comp8.ctb \
+ fa-ir-g1.utb \
+ fi1.ctb \
+ fi2.ctb \
+ fi-fi-8dot.ctb \
+ fi.utb \
+ fr-bfu-comp68.cti \
+ fr-bfu-comp6.utb \
+ fr-bfu-comp8.utb \
+ fr-bfu-g2.ctb \
+ ga-g1.utb \
+ ga-g2.ctb \
+ gd.ctb \
+ gd.tbl \
+ gez.tbl \
+ gon.ctb \
+ gon.tbl \
+ grc-international-en.utb \
+ grc-international-common.uti \
+ grc-international-composed.uti \
+ grc-international-decomposed.uti \
+ gr-pl-comp8.uti \
+ gu-in-g1.utb \
+ gujarati.cti \
+ gurumuki.cti \
+ gu.tbl \
+ haw-us-g1.ctb \
+ he.ctb \
+ he.tbl \
+ hi-in-g1.utb \
+ hi.tbl \
+ hr-chardefs.cti \
+ hr-comp8.tbl \
+ hr-comp8.utb \
+ hr-digits.uti \
+ hr-g1.ctb \
+ hr-g1.tbl \
+ hr-translation.cti \
+ hu-backtranslate-correction.dis \
+ hu-chardefs.cti \
+ hu-exceptionwords.cti \
+ hu-hu-g1_braille_input.cti \
+ hu-hu-comp8.ctb \
+ hu-hu-g1.ctb \
+ hu-hu-g2.ctb \
+ hu-hu-g2_exceptions.cti \
+ hu.tbl \
+ hy.ctb \
+ hyph_brl_da_dk.dic \
+ hyph_cs_CZ.dic \
+ hyph_da_DK.dic \
+ hyph_de_DE.dic \
+ hyph_en_US.dic \
+ hyph_eo.dic \
+ hyph_es_ES.dic \
+ hyph_fr_FR.dic \
+ hyph_hu_HU.dic \
+ hyph_it_IT.dic \
+ hyph_nb_NO.dic \
+ hyph_nl_NL.dic \
+ hyph_nn_NO.dic \
+ hyph_pl_PL.dic \
+ hyph_pt_PT.dic \
+ hyph_ru.dic \
+ hyph_sv_SE.dic \
+ hy.tbl \
+ IPA-unicode-range.uti \
+ IPA.utb \
+ is-chardefs6.cti \
+ is-chardefs8.cti \
+ is.ctb \
+ is.tbl \
+ it-it-comp6.utb \
+ it-it-comp8.utb \
+ it.tbl \
+ iu-ca-g1.ctb \
+ ka-in-g1.utb \
+ kannada.cti \
+ kha.tbl \
+ kh-in-g1.utb \
+ kn.tbl \
+ ko-2006.cti \
+ ko-2006-g1.ctb \
+ ko-2006-g2.ctb \
+ ko-chars.cti \
+ ko.cti \
+ ko-g1.ctb \
+ ko-g1-rules.cti \
+ ko-g2.ctb \
+ ko-g2-rules.cti \
+ kok.ctb \
+ kok.tbl \
+ kru.ctb \
+ kru.tbl \
+ ks-in-g1.utb \
+ latinLetterDef6Dots.uti \
+ latinLetterDef8Dots.uti \
+ litdigits6DotsPlusDot6.uti \
+ litdigits6Dots.uti \
+ loweredDigits6Dots.uti \
+ loweredDigits8Dots.uti \
+ lt.ctb \
+ lt.tbl \
+ lt-6dot.utb \
+ lt-6dot.tbl \
+ Lv-Lv-g1.utb \
+ lv.tbl \
+ malayalam.cti \
+ mao-nz-g1.ctb \
+ marburg_single_cell_defs.cti \
+ marburg_unicode_defs.cti \
+ ml-in-g1.utb \
+ ml.tbl \
+ mn-in-g1.utb \
+ mni.tbl \
+ mn-MN-common.cti \
+ mn-MN-g1.utb \
+ mn-MN-g2.ctb \
+ mr-in-g1.utb \
+ mr.tbl \
+ mt.ctb \
+ mt.tbl \
+ mun.ctb \
+ mun.tbl \
+ mwr.ctb \
+ mwr.tbl \
+ ne.ctb \
+ nemethdefs.cti \
+ ne.tbl \
+ nl-BE.dis \
+ nl-BE-g0.utb \
+ nl_BE.tbl \
+ nl-chardefs.uti \
+ nl-g0.uti \
+ nl-NL-g0.utb \
+ nl.tbl \
+ nl-comp8.utb \
+ no-no-8dot-fallback-6dot-g0.utb \
+ no-no-8dot.utb \
+ no-no-braillo-047-01.dis \
+ no-no-chardefs6.uti \
+ no-no-comp8.ctb \
+ no-no.dis \
+ no-no-g0.utb \
+ no-no-g1.ctb \
+ no-no-g2.ctb \
+ no-no-g3.ctb \
+ no-no-generic.ctb \
+ no-no-generic.dis \
+ no-no-latinLetterDef6Dots_diacritics.uti \
+ no.tbl \
+ np-in-g1.utb \
+ or-in-g1.utb \
+ oriya.cti \
+ or.tbl \
+ pa.tbl \
+ pi.ctb \
+ pi.tbl \
+ pl-pl-comp8.ctb \
+ Pl-Pl-g1.utb \
+ pl.tbl \
+ printables.cti \
+ pt-pt-comp8.ctb \
+ pt-pt-g1.utb \
+ pt-pt-g2.ctb \
+ pt.tbl \
+ pu-in-g1.utb \
+ ro.ctb \
+ ro.tbl \
+ ru-chardefs.cti \
+ ru-compbrl.ctb \
+ ru.ctb \
+ ru-letters.dis \
+ ru-litbrl.ctb \
+ ru-ru.dis \
+ ru-ru-g1.utb \
+ ru-unicode.dis \
+ ru.tbl \
+ sa-in-g1.utb \
+ sa.tbl \
+ sd.tbl \
+ se-se.ctb \
+ se-se.dis \
+ Se-Se-g1.utb \
+ si-in-g1.utb \
+ sin.cti \
+ sin.utb \
+ sk-chardefs.cti \
+ sk-g1.ctb \
+ sk-sk-g1.utb \
+ sk-sk.utb \
+ sk.tbl \
+ sk-translation.cti \
+ sl-si-comp8.ctb \
+ sl-si-g1.utb \
+ sl.tbl \
+ sot-za-g1.ctb \
+ sr-chardefs.cti \
+ sr-g1.ctb \
+ sr.tbl \
+ sv-1989.ctb \
+ sv-1996.ctb \
+ sv.tbl \
+ ta.ctb \
+ tamil.cti \
+ ta-ta-g1.ctb \
+ ta.tbl \
+ te-in-g1.utb \
+ telugu.cti \
+ te.tbl \
+ text_nabcc.dis \
+ tr.ctb \
+ tr-g1.ctb \
+ tr-g2.ctb \
+ tr-g2.tbl \
+ tr.tbl \
+ tsn-za-g1.ctb \
+ uk.utb \
+ ukchardefs.cti \
+ ukmaths_single_cell_defs.cti \
+ ukmaths_unicode_defs.cti \
+ unicode-braille.utb \
+ unicode.dis \
+ unicode-without-blank.dis \
+ uni-text.dis \
+ ur-pk-g1.utb \
+ ur-pk-g2.ctb \
+ us-table.dis \
+ vi.ctb \
+ vi-g1.ctb \
+ vi.tbl \
+ wiskunde-chardefs.cti \
+ zh-chn.ctb \
+ zh_CHN.tbl \
+ zhcn-g1.ctb \
+ zhcn-g2.ctb \
+ zh-hk.ctb \
+ zh_HK.tbl \
+ zh-tw.ctb \
+ zh_TW.tbl
+
+tablesdir = $(datadir)/liblouis/tables
+tables_DATA = $(table_files)
+EXTRA_DIST = $(table_files)
diff --git a/tables/Pl-Pl-g1.utb b/tables/Pl-Pl-g1.utb
new file mode 100644
index 0000000..d33598b
--- /dev/null
+++ b/tables/Pl-Pl-g1.utb
@@ -0,0 +1,300 @@
+# liblouis: Polish Grade 1 Braille Table
+#
+# Copyright (C) 2004-2008 ViewPlus Technologies, Inc. www.viewplus.com
+# Copyright (C) 2004-2006 JJB Software, Inc. www.jjb-software.com
+# Copyright (C) 2012 Mesar Hameed <mesar.hameed@gmail.com>
+# Copyright (C) 2019 Łukasz Golonka <wulfryk1@gmail.com>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# Created & maintained by Leon Ungier <Leon.Ungier@ViewPlus.com>.
+
+space \x00a0 a
+include spaces.uti
+include text_nabcc.dis
+
+# ----------- define all chars --------------------------------------
+
+punctuation ! 235 exclamation sign x0021
+punctuation " 356 double quote x0022
+sign # 3456 number sign x0023
+sign $ 4-145 dollar sign x0024
+sign % 3456-245-356 percent sign x0025
+sign & 456-12346 ampersand z0026
+noback punctuation ' 3 apostrophe x0027
+nofor punctuation ' 4 apostrophe x0027
+punctuation ( 2356 left parenthesis x0028
+punctuation ) 2356 right parenthesis x0029
+sign * 35 asterisk x002A
+math + 235 plus 002B
+punctuation , 2 coma 002C
+punctuation - 36 hyphen-minus 002D
+punctuation . 3 point 002E
+math / 256 solidus 002F
+
+punctuation : 25 colon x003A
+punctuation ; 23 semicolon x003B
+punctuation < 5-13 less-than sign x003C
+math = 2356 equal sign x003D
+math > 46-2 greater-than sign x003E
+punctuation ? 26 question mark x003F
+sign @ 345 commercial at x0040
+
+include latinLetterDef6Dots.uti
+
+include digits6Dots.uti # Must come after letters.
+include litdigits6Dots.uti # Must come after letters.
+
+# all Polish diacritics must come before other symbols to make back-translation working.
+# the letter a with ogonek -----------------------------------
+uplow \x0104\x0105 16
+
+# the letter c with acute
+uplow \x0106\x0107 146
+
+# the letter e with ogonek
+uplow \x0118\x0119 156
+
+# the letter l with stroke
+uplow \x0141\x0142 126
+
+# the letter n with acute
+uplow \x0143\x0144 1456
+
+# the letter o with acute
+uplow \x00D3\x00F3 346 x00D3 / 00F3
+
+# the letter s with acute
+# always \x015A 246 x015A
+# always \x015B 246
+uplow \x015A\x015B 246
+
+# the letter z with acute
+# always \x0179 2346 x0179
+# always \x017A 2346
+uplow \x0179\x017A 2346
+
+# the letter z with dot above
+# always \x017B 12346 x017B
+# always \x017C 12346 x017C
+uplow \x017B\x017C 12346
+
+
+punctuation [ 12356 left square bracket x005B
+sign \\ 34 reverse solidus x005C
+punctuation ] 23456 right square bracket x005D
+sign ^ 5 circumflex accent x005E
+sign _ 46 low line x005F
+sign ` 4 grave accent x0060
+
+# a - z # 97 - 122 x0061-x007A
+
+punctuation { 246 left curly bracket x007B
+sign | 56 vertical line x007C
+punctuation } 12456 right curly bracket x007D
+math ~ 256 tilde x007E
+sign \x0080 15-136-1235-135 x0080
+
+sign ¢ 4-14 cent sign x00A2
+sign £ 45-123 pound sign x00A3
+sign ¤ 45-15 currency sign x00A4
+sign ¥ 45-13456 yen sign x00A5
+sign § 346 section sign x00A7
+sign © 2356-6-14-2356 copyright x00A9
+punctuation « 236 left-pointing double angle quotation x00AB
+punctuation \x00AD 36 soft hyphen
+sign ° 4-356 degree sign x00B0
+sign ² 4-6-126 superscript 2 sign x00B2
+sign ³ 4-6-146 superscript 3 sign x00B3
+sign µ 46-134 micro sign x00B5
+sign ¶ 4-1234-345 pilcrow sign (paragraph) x00B6
+sign ¹ 1-27 superscript 1 sign x00B9
+punctuation » 356 right-pointing double angle quotation x00BB
+math ¼ 6-16-34-1456 vulgar fraction one quarter x00BC
+math ½ 6-16-34-126 vulgar fraction one half x00BD
+math ¾ 6-126-34-1456 vulgar fraction 3 quarters x00BE
+
+uplow Åå 16 A with ring above x00C5 / 00E5
+uplow \x00C2\x00E2 16 letter a with circumflex x00E2
+
+uplow \x00C0\x00E0 12356 letter a with grave x00C0 / 00E0
+uplow \x00C1\x00E1 12356 letter a with acute x00E1
+uplow \x00C3\x00E3 126 letter a with tilde x00E3
+uplow Ää 345 A with diaeresis x00C4 / 00E4
+uplow \x00C6\x00E6 6-345 ae x00C6
+uplow Çç 12346 letter c with cedilla x00C7 / 00E7
+uplow Èè 2346 e with grave x00C8 / 00E8
+uplow \x00C9\x00E9 123456 e with acute x00E9
+uplow \x00CA\x00EA 126 e with circumflex x00EA
+uplow \x00CB\x00EB 1246 e with diaeresis x00EB
+uplow \x00CD\x00ED 34 i with acute x00ED
+uplow \x00CE\x00EE 146 i with circumflex x00EE
+uplow \x00CF\x00EF 12456 i with diaeresis x00CF / 00EF
+
+uplow \x00D4\x00F4 1456 o with circumflex x00F4
+uplow \x00D5\x00F5 246 o with tilde x00F5
+uplow Öö 246 O with diaeresis x00D6 / 00F6
+math × 3 multiplication sign x00D7
+uplow \x00D8\x00F8 246 o with stroke x00D8 / 00F8
+
+math ÷ 256 division sign x00F7
+
+uplow \x00DA\x00FA 23456 u with acute x00DA / 00FA
+uplow \x00DB\x00FB 156 u with circumflex x00FB
+uplow \x00DC\x00FC 1256 u with diaeresis x00FC
+uplow \x00DD\x00FD 12346 y with acute x00DD / 00FD
+
+
+punctuation \x2010 36 # 8208 hyphen
+punctuation \x2011 36 # 8209 non-breaking hyphen
+punctuation \x2013 36 # 8211 smart minus sign
+punctuation \x2018 3 # 8216 smart single left quotation mark
+punctuation \x2019 3 # 8217 smart single right quotation mark
+
+punctuation \x201C 236 # 8220 smart opening double quote
+punctuation \x201D 356 # 8221 smart closing double quote
+punctuation \x201E 236 # 8222 smart double low quotation mark
+punctuation \x201F 356 # 8223 smart double high reverse quotation mark
+punctuation \x2026 3-3-3 # 8230 smart ellipsis
+
+noback sign \x25CF 35-35 # 9679 black circle
+
+# ------------------------------------------------------
+
+
+capsletter 46 # single capital letter indicator
+begcapsword 46-46 # a block of consecutive capital letters indicator
+
+numsign 3456 # number sign, just one operand
+midnum , 2
+midnum . 3
+
+endnum # 56-3456
+
+prepunc " 236
+postpunc " 356
+
+prepunc ' 6-236
+postpunc ' 356-3
+postpunc '' 356
+postpunc ''' 356-3-356
+
+repeated *** 16-16-16
+
+prepunc `` 236
+prepunc ` 6-236
+
+
+repeated --- 36-36-36
+
+repeated ___ 46-46-46
+
+repeated ::: 25-25-25
+repeated === 46-13-46-13-46-13
+repeated ~~~ 4-156-4-156-4-156
+always \s-\scom 36-36-14-135-134
+always ... 3-3-3
+always .\s.\s. 3-3-3 . . .
+
+always \s\s 36-36
+
+# special character sequences
+literal :// URLs
+literal www.
+
+literal .com
+literal .edu
+literal .gov
+literal .mil
+literal .net
+literal .org
+
+literal .doc
+literal .htm
+literal .html
+literal .tex
+literal .txt
+
+literal .gif
+literal .jpg
+literal .png
+literal .wav
+
+literal .tar
+literal .zip
+
+# Greek letters
+
+noback letter \x0391 456-1 # Α
+noback letter \x0392 456-12 # Β
+noback letter \x0393 456-1245 # Γ
+noback letter \x0394 456-145 # Δ
+noback letter \x0395 456-15 # Ε
+noback letter \x0396 456-1356 # Ζ
+noback letter \x0397 456-156 # Η
+noback letter \x0398 456-1456 # Θ
+noback letter \x0399 456-24 # Ι
+noback letter \x039A 456-13 # Κ
+noback letter \x039B 456-123 # Λ
+noback letter \x039C 456-134 # Μ
+noback letter \x039D 456-1345 # Ν
+noback letter \x039E 456-1346 # Ξ
+noback letter \x039F 456-135 # Ο
+noback letter \x03A0 456-1234 # Π
+noback letter \x03A1 456-1235 # Ρ
+noback letter \x03A3 456-234 # Σ
+noback letter \x03A4 456-2345 # Τ
+noback letter \x03A5 456-136 # Υ
+noback letter \x03A6 456-124 # Φ
+noback letter \x03A7 456-12346 # Χ
+noback letter \x03A8 456-13456 # Ψ
+noback letter \x03A9 456-2456 # Ω
+
+noback letter \x03B1 56-1 # α
+noback letter \x03B2 56-12 # β
+noback letter \x03B3 56-1245 # γ
+noback letter \x03B4 56-145 # δ
+noback letter \x03B5 56-15 # ε
+noback letter \x03B6 56-1356 # ζ
+noback letter \x03B7 56-156 # η
+noback letter \x03B8 56-1456 # θ
+noback letter \x03B9 56-24 # ι
+noback letter \x03BA 56-13 # κ
+noback letter \x03BB 56-123 # λ
+noback letter \x03BC 56-134 # μ
+noback letter \x03BD 56-1345 # ν
+noback letter \x03BE 56-1346 # ξ
+noback letter \x03BF 56-135 # ο
+noback letter \x03C0 56-1234 # π
+noback letter \x03C1 56-1235 # ρ
+noback letter \x03C2 56-234 # ς
+noback letter \x03C3 56-234
+noback letter \x03C4 56-2345 # τ
+noback letter \x03C5 56-136 # υ
+noback letter \x03C6 56-124 # φ
+noback letter \x03C7 56-12346 # χ
+noback letter \x03C8 56-13456 # ψ
+noback letter \x03C9 56-2456 # ω
+
+# Arrows:
+
+noback sign \x2192 25-135
+noback sign \x2190 246-25
+
+
+noback sign \x2264 246-2356 # Less than or equal to
+noback sign \x2265 135-2356 # Greater than or equal to
diff --git a/tables/README b/tables/README
new file mode 100644
index 0000000..a96b876
--- /dev/null
+++ b/tables/README
@@ -0,0 +1,6 @@
+Most of the liblouis tables in this subdirectory were supplied by
+ViewPlus Technologies, Inc.
+
+The hyphenation tables are the ones used in TeX and OpenOffice.
+
+
diff --git a/tables/Se-Se-g1.utb b/tables/Se-Se-g1.utb
new file mode 100644
index 0000000..d1b92da
--- /dev/null
+++ b/tables/Se-Se-g1.utb
@@ -0,0 +1,142 @@
+# liblouis: Swedish Grade 1 Braille Table
+#
+# Copyright (C) 2004-2008 ViewPlus Technologies, Inc. www.viewplus.com
+# Copyright (C) 2004-2006 JJB Software, Inc. www.jjb-software.com
+# Copyright (C) 2012 Mesar Hameed <mesar.hameed@gmail.com>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# Created by Leon Ungier <Leon.Ungier@ViewPlus.com>.
+
+include se-se.dis
+
+space \x00a0 a
+include spaces.uti
+
+# ----------- define all chars --------------------------------------
+
+punctuation ! 235 exclamation mark x0021
+punctuation " 56 double quote x0022
+sign # 45-3456 number sign x0023
+sign $ 4-234 dollar x0024
+sign % 46-356 percent x0025
+sign & 5-346 ampersand x0026
+punctuation ' 5 apostrophe x0027
+punctuation ( 236 left parenthesis x0028
+punctuation ) 356 right parenthesis x0029
+sign * 35 asterisk x002A
+math + 256 plus x002B
+punctuation , 2 coma x002C
+punctuation - 36 hyphen-minus x002D
+punctuation . 3 point x002E
+math / 34 solidus x002F
+
+punctuation : 25 colon x003A
+punctuation ; 23 semicolon x003B
+math < 246-3 less-than sign x003C
+math = 2356 equal sign x003D
+math > 135-2 greater-than sign x003E
+punctuation ? 26 question mark x003F
+sign @ 45-12356 commercial at x0040
+
+include latinLetterDef6Dots.uti
+include digits6Dots.uti # must come after letters
+include litdigits6Dots.uti # Must come after letters
+
+
+punctuation [ 12356 left square bracket x005B
+sign \\ 45-34 reverse solidus x005C
+punctuation ] 23456 right square bracket x005D
+sign ^ 4 circumflex accent x005E
+sign _ 6 low line x005F
+sign ` 46 grave accent x0060
+
+# a - z # 97 - 122 x0061-x007A
+
+punctuation { 6-236 left curly bracket x007B
+sign | 456 vertical line x007C
+punctuation } 6-356 right curly bracket x007D
+math ~ 45-2 tilde x007E
+sign ¢ 4-14 cent sign x00A2
+sign £ 45-123 pound sign x00A3
+sign ¤ 45-15 currency sign x00A4
+sign ¥ 45-13456 yen x00A5
+sign § 346 paragraph x00A7
+
+sign © 6-14-135-1234-13456-1235-24-1245-125-2345 copyright x00A9
+punctuation « 45-2356 left pointing double angle x00AB
+
+sign ° 4-356 degree sign x00B0
+sign ² 4-6-126 superscript 2 x00B2
+sign ³ 4-6-146 superscript 3 x00B3
+sign ¹ 4-6-16 superscript 1 x00B9
+punctuation » 2356-12 right pointing double angle x00BB
+math ¼ 6-16-34-1456 vulgar fraction 1 quarter x00BC
+math ½ 6-16-34-126 vulgar fraction one half x00BD
+math ¾ 6-126-34-1456 vulgar fraction 3 quarters x00BE
+
+uplow \x00C0\x00E0 12356 A with grave x00C0
+uplow Ää 345 a with diaeresis x00C4
+uplow Åå 16 A with ring above x00C5
+uplow \x00C8\x00E8 2346 E with grave above x00C8
+uplow Éé 123456 E with acute above x00C9
+
+uplow Öö 246 x00D6
+math × 1346 multiplication sign x00D7
+
+uplow Üü 1256-1256 U with diaeresis x00DC
+
+math ÷ 34 division sign x00F7
+
+punctuation \x2010 46 # 8208 hyphen
+punctuation \x2011 46 # 8209 non-breaking hyphen
+punctuation \x2013 36 # 8211 smart minus sign
+punctuation \x2018 5 # 8216 smart single left quotation mark
+punctuation \x2019 5 # 8217 smart single right quotation mark
+
+punctuation \x201C 56 # 8220 smart opening double quote
+punctuation \x201D 56 # 8221 smart closing double quote
+punctuation \x201E 56 # 8222 smart double low quotation mark
+punctuation \x201F 56 # 8223 smart double high reverse quotation mark
+
+punctuation \x2026 3-3-3 # 8230 smart ellipsis
+
+sign \x20AC 15-136-1235-135 Euro sign
+noback sign \x25CF 35 # 9679 black circle
+
+# -----------------------
+
+capsletter 6
+begcapsword 6-6 # uncomment if you don't want capitalization
+
+sign \x00B7 3456 # so the line below compile
+numsign 3456
+midnum , 2
+midnum . 3
+midnum + 256
+midnum - 36
+midnum / 34
+midnum : 25
+
+endnum # 56-3456
+
+repeated ... 3-3-3 ellipsis
+repeated --- 36-36-36
+repeated ___ 6-6-6
+
+always \s--\s 36-36 tiret
+
diff --git a/tables/afr-za-g1.ctb b/tables/afr-za-g1.ctb
new file mode 100644
index 0000000..bc43c93
--- /dev/null
+++ b/tables/afr-za-g1.ctb
@@ -0,0 +1,96 @@
+#afr#1#Afrikaans Uncontracted#za#Afrikaans onverkort
+
+# liblouis: Afrikaans Braille Code (Grade 1)
+#
+# ------------
+#-name: Afrikaans onverkort
+#-index-name: Afrikaans, uncontracted
+#-display-name: Afrikaans uncontracted braille
+#
+#+locale:af
+#+type:literary
+#+contraction:no
+#+grade:1
+#+system:ubc-af
+#
+# "UBC" stands for "Unified Braille Code" and is a generalization of UEB.
+# See https://sabrailleauthority.org.za/unified-braille-code-ubc.
+# ------------
+#
+# Afrikaans is one of the 11 official languages in South Africa and is
+# among the top 3 most widely spoken local languages. It is a language
+# closely related to Dutch and uses the same alphabet, but in addition
+# it makes frequent use of the following diacritic marks on vowels:
+# acute and grave accent, circumflex and umlaut.
+#
+# The first braille system for Afrikaans was developed in about
+# 1935. After the adoption of the UEB in 2004 in Toronto, Canada, we
+# also unified the Afrikaans braille code according to the principles
+# of the UEB. The grade 1 code is identical to grade 1 UEB. Grade 2
+# has 183 contractions. Each letter of the alphabet except the letter
+# u (which is a word on its own) represents a contraction in grade
+# 2. As with UEB, we eliminated the contractions which could cause
+# ambiguity. In one respect Afrikaans braille is simpler than UEB, but
+# in another respect it is more complex: It is simpler in that it does
+# not have the complexity around shortforms found in UEB grade 2. It
+# is more complex because of linguistic reasons. In Afrikaans compound
+# words are frequently created on the fly and this can cause
+# contraction issues at word boundaries.
+#
+# We do not use additional codes such as Nemeth or computer braille
+# codes; we use our unified Afrikaans code also for technical
+# material.
+#
+# Copyright (C) 2014, 2019 Greg Kearney <gkearney@gmail.com>
+# Copyright (C) 2019 South African Braille Authority <http://www.sabrailleauthority.org.za>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+include en-ueb-g1.ctb
+
+# These are the old definitions of the accented letters that differ
+# from UEB. They are defined in World Braille Usage 2013
+# <http://liblouis.org/braille-specs/world-braille-usage-third-edition.pdf>. They
+# are commented out now that UEB has been adopted.
+
+#sign \x0302 45 COMBINING CIRCUMFLEX ACCENT
+#sign \x0308 56 COMBINING DIAERESIS
+#sign \x0301 4 COMBINING ACUTE ACCENT
+
+#uplow Áá 4-1
+#uplow Àà 45-16-1
+#uplow Ââ 45-1
+#uplow Ää 56-1
+
+#uplow Éé 4-15
+#uplow Èè 45-16-15
+#uplow Êê 45-15
+#uplow Ëë 56-15
+
+#uplow Íí 4-24
+#uplow Ïï 56-24
+#uplow Îî 45-24
+
+#uplow Óó 4-135
+#uplow Ôô 45-135
+#uplow Öö 56-135
+
+#uplow Úú 4-136
+#uplow Ûû 45-136
+#uplow Üü 56-136
+
+#uplow Ýý 4-13456
diff --git a/tables/afr-za-g2.ctb b/tables/afr-za-g2.ctb
new file mode 100644
index 0000000..a0d1f93
--- /dev/null
+++ b/tables/afr-za-g2.ctb
@@ -0,0 +1,1012 @@
+# liblouis: Afrikaans Braille Code (Grade 2)
+#
+# -----------
+#-name: Afrikaans verkort
+#-index-name: Afrikaans, contracted
+#-display-name: Afrikaans contracted braille
+#
+#+locale:af
+#+type:literary
+#+contraction:full
+#+grade:2
+#+system:ubc-af
+#
+# "UBC" stands for "Unified Braille Code" and is a generalization of UEB.
+# See https://sabrailleauthority.org.za/unified-braille-code-ubc.
+# ------------
+#
+# Afrikaans is one of the 11 official languages in South Africa and is
+# among the top 3 most widely spoken local languages. It is a language
+# closely related to Dutch and uses the same alphabet, but in addition
+# it makes frequent use of the following diacritic marks on vowels:
+# acute and grave accent, circumflex and umlaut.
+#
+# The first braille system for Afrikaans was developed in about
+# 1935. After the adoption of the UEB in 2004 in Toronto, Canada, we
+# also unified the Afrikaans braille code according to the principles
+# of the UEB. The grade 1 code is identical to grade 1 UEB. Grade 2
+# has 183 contractions. Each letter of the alphabet except the letter
+# u (which is a word on its own) represents a contraction in grade
+# 2. As with UEB, we eliminated the contractions which could cause
+# ambiguity. In one respect Afrikaans braille is simpler than UEB, but
+# in another respect it is more complex: It is simpler in that it does
+# not have the complexity around shortforms found in UEB grade 2. It
+# is more complex because of linguistic reasons. In Afrikaans compound
+# words are frequently created on the fly and this can cause
+# contraction issues at word boundaries.
+#
+# We do not use additional codes such as Nemeth or computer braille
+# codes; we use our unified Afrikaans code also for technical
+# material.
+#
+# Copyright (C) 2019 Greg Kearney <gkearney@gmail.com>
+# Copyright (C) 2019 South African Braille Authority <http://www.sabrailleauthority.org.za>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>
+#
+# Maintained by Christo de Klerk <cjdk@mweb.co.za>
+
+include afr-za-g1.ctb
+include IPA-unicode-range.uti
+
+# Begin entries
+
+multind 56-6 nocontractsign capsletter
+
+seqdelimiter -—
+seqdelimiter ‐ \x2010
+seqdelimiter ‑ \x2011
+seqdelimiter – \x2013
+seqdelimiter — \x2014
+seqbeforechars ([{"“'‘
+seqafterchars )]}"”'’.,;:.!?…
+
+noback correct "’" "'"
+
+attribute 1 AEIOUYÊËaeiouyêë vowels
+
+# Shape symbols require a grade 1 indicator (Section 3.22.1)
+contraction \x25a0 ■ filled (solid) square
+contraction \x25a1 □ square
+contraction \x25a7 ▧ shaded square (upper left to lower right)
+contraction \x25b2 ▲ filled (solid) (equilateral) triangle
+contraction \x25b3 △ regular (equilateral) triangle
+contraction \x25cb ○ circle
+contraction \x25cd ◍ shaded circle
+
+# match expressions
+
+# Low words
+match %[^_]|%[^_~]%<*[([{] deur %[^_]|[)}\\]]%>*%[^_~] 256
+match %[^_]|%[^_~]%<*[([{] en %[^_]|[)}\\]]%>*%[^_~] 26
+match %[^_]|%[^_~]%<*[([{] te %[^_]|[)}\\]]%>*%[^_~] 235
+match %[^_]|%[^_~]%<*[([{] se %[^_]|[)}\\]]%>*%[^_~] 2356
+match %[^_]|%[^_~]%<*[([{] hier %[^_]|[)}\\]]%>*%[^_~] 236
+match %[^_]|%[^_~]%<*[([{] in %[^_]|[)}\\]]%>*%[^_~] 35
+match %[^_]|%[^_~]%<*[([{] by %[^_]|[)}\\]]%>*%[^_~] 356
+
+#a
+noback match - al E%[^_.]|e%[^_.]|END|end|ER%[^_.]|er%[^_.]|EREG|ereg|ERS|ers|I%[^_.]|i%[^_.]|IAS|ias|IES|ies|IG|ig|ING|ing|IË|ië 1-123
+noback match %a al AAT|aat|AT|at|IE|ie 1-123
+noback match - an E%[^_.]|e%[^_.]|ER%[^_.]|er%[^_.]|ERS|ers|IAK|iak|IES|ies|IG|ig|US|us 1-1345
+noback match %[^_.](MEL|mel|Mel|[DdFfMm]) anie %[^_.] 1-1345-1456
+
+#b
+noback match - be FF|ff|KK|kk|KM|km|LL|ll|SS|ss|TT|tt|T%[^_.]|t%[^_.]|NE%[^_.]|ne%[^_.]|SIE%[^_.]|sie%[^_.]|SIES|sies|SIG%[^_.]|sig%[^_.]|SIG!T|sig!t|SWIL|swil|TH|th 12-15
+noback match %[^_.] be F%[^_.]|f%[^_.]|L%[^_.]|l%[^_.]|[Ll]!%1|S%[^_.]|s%[^_.]|T%[^_.]|t%[^_.] 12-15
+noback match - bed %[^_.]|E%[^_.]|e%[^_.]|EL%[^_.]|el%[^_.]|ELA|ela|ELT|elt|EV|ev|[BDFGHJKLMNPSTVbdfghjklmnpstv] 12-15-145
+noback match - bek %[^_.]|AF|af|ER|er|[Kk] 12-15-13
+noback match - ben %[^_.]|!%1 12-26
+noback match - beo fi|lo|gr 12-15
+noback match %a ber IES|ies|ING|ing|IË|ië 12-15-1235
+noback match - ber %[^_.]|AAL|aal|ALE|ale|ALES|ales|ALIS|alis|![AEIOUaeiou] 12-12456
+noback match - besig h 12-15-234-24-1245
+noback match - best E%[^_.]|e%[^_.]|ES|es 12-15-34
+noback match - betal e|ing 23-2345-1-123
+noback match - bew e%[^_.]|end|erasie|erig 12-15-2456
+noback match - binne %[^_.]|N!S|n!s|[AaBbDdFfGgHhJjKkLlMmOoPpRrSsTtVvWw] 12-35-1345-15
+
+#d
+noback match - dag END|end|ER|er|ING|ing|IO|io 145-1-1245
+noback match %[^_.] dan IEL|iel|IËL|iël 145-1-1345
+noback match - dani G|g 145-1-1345-24
+noback match - dat [aeiou] 145-1-2345
+noback match - de REG|reg 145-15
+noback match - die U|u 145-24-15
+noback match %[^_.] den [OoUu] 145-15-1345
+noback match AR|ar der END|end|ING|ing 145-15-1235
+noback match %a dit ASIE|asie|EER|eer|ERE|ere|ERI|eri|EUR|eur|Êr|êr|EIT|eit|ERR|err 145-24-2345
+
+#e
+noback match %[^_.] ek '[SsTt] 15-13
+noback match WES|wes en [Ee]%[^_.]|ES%[^_.]|es%[^_.] 26
+noback match [BbMmSs] en [Ee]%[^_.]|ES%[^_.]|es%[^_.] 15-1345
+noback match %a en AME|ame|AAM|aam|ESTE|este|IG|ig 15-1345
+noback match %[^_.] en E%[^_.]|e%[^_.]|ERS|ers|ETJIE|etjie|IG|ig|ORM|orm 15-1345
+noback match [Ss] en ING|ing|IOR|ior|[Uu] 15-1345
+noback match [LlMm] en ER%[^_.]|er%[^_.]|ER!G|er!g|IG|ig|ING|ing 15-1345
+noback match !%1 enag %[^_.]|TE|te 15-1345-1-1245
+noback match %a eni GEND|gend|GING|ging 15-1345-24
+noback match IMP|imp er [AEIOUaeiou] 15-1235
+noback match %a er EKENING|ekening|EKENA|ekena|EKENM|ekenm|ANGS|angs|OK%[^_.]|ok%[^_.]|OKK|okk|OSI|osi|ESERW|eserw|IOD|iod|OOS|oos|OSE|ose 15-1235
+noback match %[^_.] er [AaIiOo] 15-1235
+noback match FISK|fisk|ID|id|IN|in|ION|ion|IT|it|L|l|LU|lu|MK|mk|PARK|park|R|r|REG|reg|RN|rn|SOEN|soen|TRAST|trast|V|v er END|end|ING|ing 15-1235
+noback match SM|sm er END|end|IG|ig|ING|ing 15-1235
+noback match UM|um er IES|ies|ING|ing 15-1235
+
+#g
+noback match - ge MM|mm|NIA|nia|SPE%[^_.]|spe%[^_.]|SPES%[^_.]|spes%[^_.]|TE%[^_.]|te%[^_.]|TIES|ties|WEL%[^_.]|wel%[^_.]|WELS|wels|WER%[^_.]|wer%[^_.]|WERS%[^_.]|wers%[^_.] 1245-15
+noback match %[^_.] ge NE%[^_.]|ne%[^_.]|NER%[^_.]|ner%[^_.] 1245-15
+noback match OE|oe|[DdGgSsTt] ge WEND|wend|WING|wing 1245-15
+noback match BE|be ge REND|rend|RIG|rig 1245-15
+noback match - ge WE%[^_.]|we%[^_.]|WENE|wene|WER%[^_.]|wer%[^_.]WING|wing 1245-15
+noback match - gek %[^_.]|[HhKkSs] 1245-15-13
+noback match REN|ren gel [Dd] 123456-123
+noback match - gel D%[^_.]|d%[^_.]|DE%[^_.]|de%[^_.]|DELIK|delik|DEND|dend|DER|der|DIG|dig|DING|ding|DJIE|djie|DEENH|deenh|DOOR|door|DWAARD|dwaard|DWESE|dwese|[Dd][BbDdFfGgHhJjKkLlMmNnPpSsTtVv]|E%[^_.]|e%[^_.]|ER%[^_.]|er%[^_.]|LING|ling 1245-15-123
+noback match - gen IE%[^_.]|ie%[^_.]|![AEIOUaeiou] 1245-26
+noback match - gener A|a|EER|eer 1245-26-12456
+noback match - geo fi|gr|lo|m 1245-15-135
+noback match %a ger IË|ië 1245-15-1235
+noback match LE|le|NE|ne ger END|end|ING|ing 1245-15-1235
+noback match - ger %[^_.]|!%1 1245-12456
+noback match DRIN|drin|G|g|HON|hon ger IG|ig 1245-12456
+noback match %[^_.] gewel DAK|dak|[BbGgHhJjKkLlMmNnPpRrSsTtVv] 1245-15-2456-15-123
+noback match UIT|uit gewer [SsYy] 1245-15-2456-12456
+noback match - gron E|d 1245-1235-25
+
+#h
+noback match - hal end|er|ing 125-1-123
+noback match - her E%[^_.]|e%[^_.]|ALDIE|aldie|EREG|ereg|ETJIE|etjie 125-15-1235
+
+#k
+noback match %[^_.] kana %[^_.]|Ä|ä 13-1-1345-1
+noback match T|t ker END|end|ING|ing 13-15-1235
+noback match - kler ASIE|asie|E|e 13-123-15-1235
+noback match - kom [Aa]%[^_.]|AS%[^_.]|as%[^_.]|E|e|IE|ie|ING|ing 13-135-134
+
+#l
+noback match - lik AAN|aan|ANE|ane|ANT|ant|ASIE|asie|AAT|aat|ATE|ate|EIN|ein 123-24-13
+
+#m
+noback match - man e%[^_.]|end|ing 134-1-1345
+noback match A|a|OE|oe mens - 134-26-234
+noback match KAL|kal mer END|end|ING|ing 134-15-1235
+noback match %[^_.]|ND|nd mer E%[^_.]|e%[^_.]|EN|en 134-15-1235
+noback match - met A|a|E%[^_.]|e%[^_.]|END|end|EO|eo|ER|er|ING|ing|OD|od|REKK|rekk 134-15-2345
+noback match - mist ERI|eri|IES|ies|IG|ig 134-24-34
+noback match - mis - 134-24-234
+
+#o
+noback match %a of AKT|akt|EER|eer|EET|eet|ERING|ering|ESS|ess|ETE|ete|IE|ie|ISTIK|istik|OON|oon|ONE%[^_.]|one%[^_.]|YT|yt 135-124
+noback match %a on AAL|aal|ALE%[^_.]|ale%[^_.]|ALIS|alis|ALIT|alit|ARIS|aris|ASIE|asie|ATEUR|ateur|E%[^_.]|e%[^_.]|ES%[^_.]|es%[^_.]|EEL|eel|ELE%[^_.]|ele%[^_.]|EER|eer|EL%[^_.]|el%[^_.]|EREND|erend|ERING|ering|END|end|ENT|ent|IAAL|iaal|IALE|iale|IE|ie|IG|ig|IËLE|iële|IS|is|IUM|ium|ER%[^_.]|er%[^_.]|ERS|ers|ING%[^_.]|ing%[^_.]|INGS|ings|IS[MT]|is[mt] 135-1345
+noback match %a on OLO|olo 135-1345
+noback match l on e 135-1345
+noback match EK|ek on OM|om|OOM|oom 135-1345
+
+#p
+noback match %[^_.] pre [Rr] 1234-1235-15
+
+#r
+noback match - reg EER|eer|ENT|ent|EREND|erend|ERING|ering|IME|ime|ISEU|iseu|ISS|iss|IST|ist|LEM|lem|RESS|ress 1235-15-1245
+
+#s
+noback match %a ser end|ing 234-15-1235
+noback match [AaIi] sien - 234-1456-1345
+noback match [AaIi] sienet - 234-1456-45-1345
+noback match arbeid sk - 234-13
+noback match %a sk AJ|aj|AMER|amer|ANT|ant|APASI|apasi|ARTEL|artel|AS|as|ATALO|atalo|ELK|elk|EUS|eus|ETT|ett|N|n 234-13
+noback match ![AEIOUaeiou] sk [Rr][Ee][Ee][Tt]%[^_.]|[Rr][Ee][Tt][Ee]%[^_.] 234-13
+noback match %a sk AART|aart|AMP|amp|ANAAL|anaal|ANALE|anale|APTEIN|aptein 234-13
+noback match %a sk ANSEL|ansel|ANTO|anto|EURIG|eurig|IND%[^_.]|ind%[^_.]|INDERS|inders|NEG|neg|NOOP|noop|NOPE|nope|OEK|oek|OEP|oep|OER|oer|OETS|oets|OFFER|offer|OFFIE|offie|OLOM|olom|OOPK|oopk|ORPS|orps|ORREL|orrel 234-13
+noback match %a sk ODE|ode|OERS|oers|OLL|oll|OLONI|oloni|ONF|onf|ONS|ons|ONTIN|ontin|OOR%[^_.]|oor%[^_.]|ORPOR|orpor|ORTING|orting|OS|os|RAAN|raan|RANE|rane|RAFF|raff|RAG%[^_.]|rag%[^_.]|RAGTE|ragte|RAGTIG|ragtig|RING|ring|RISIS|risis|ROEG|roeg|RUI|rui|RYT|ryt|UIKEN|uiken|UIP|uip|UNS|uns|W|w 234-13
+noback match %a skler A|a|E|e 234-13-123-15-1235
+noback match %a skom [BbPpSs] 234-5-13
+noback match %a skry [GgTt] 234-5-13456
+noback match %a st AAK|aak|AAL|aal|AFEL|afel|AK%[^_.]|ak%[^_.]|AKK|akk|ALIG|alig|ARIE[FW]|arie[fw]|EATER|eater|AS%[^_.]|as%[^_.]|ASS|ass|EGN|egn|EKEN|eken|EMPER|emper|EMPO|empo|ENNIS|ennis|ERREIN|errein|ESOU|esou|ITEL|itel|J|j|ONEEL|oneel|ONELE|onele|ORING|oring|RANS|rans|RANT|rant|REIN|rein|ROEP|roep|ROTS|rots|RUST|rust|AKTI|akti|ALENT|alent|ENTOON|entoon|EORI|eori|OGA%[^_.]|oga%[^_.]|OGAS|ogas|RUI%[^_.]|rui%[^_.]|RUIE|ruie|UIN|uin|W|w|YE%[^_.]|ye%[^_.] 234-2345
+noback match ARBEID|arbeid st AND|and 34
+noback match ARBEID|arbeid st - 234-2345
+noback match KIE|kie st AND|and 234-2345
+noback match BO|bo|BOSSIE|bossie st EE|ee 234-2345
+noback match %a ste [Hh]|KORT|kort 234-235
+noback match ![aeiou]|%[^_.] stene %[^_.] 34-15-1345-15
+noback match %a ster m%[^_.]|me%[^_.]|min|myn 234-2345-12456
+noback match - ster IEL|iel|ILI|ili 34-15-1235
+noback match %a stoe LAAG|laag|LAE|lae|LAT|lat|NA|na|R|r|TS|ts|[BDGJKSVbdgjksv] 234-2345-246
+
+#t
+noback match AP|ap te KE%[^_.]|ke%[^_.]|KER|ker 2345-15
+noback match - te GIES|gies|GN|gn|GRIT|grit|KARES|kares|KARIS|karis|KK|kk|KS|ks|KT|kt|LEFO|lefo|LEGRA|legra|LEVI|levi|LLEND|llend|LLER|ller|LLING|lling|M%[^_.]|m%[^_.]|MB|mb|MM|mm|MP|mp|RIES|ries|SE%[^_.]|se%[^_.]|SES|ses|STAAT|staat|STATE|state|TIES|ties 2345-15
+noback match %[^_.] te OG|lg 2345-15
+noback match IN|in te LLEK|llek|LLIG|llig 2345-15
+noback match MON|mon|NO|no|TRAK|trak te RE|re|RI|ri 2345-15
+noback match - tea %[^_.]|S|s|TER|ter|TR|tr 2345-15-1
+noback match AN|an tedat E|e 2345-15-145-1-2345
+noback match %[^_.]|%[^_.]VER|%[^_.]ver teder - 2345-15-145-12456
+noback match - teken %[^_.]|END|end|ING|ing|[DFGHJKLMPRSTVWdfghjklmprstvw] 2345-15-13-26
+noback match - tema %[^_.]|S|s 2345-15-134-1
+noback match %[^_.] tema - 2345-15-134-1
+noback match - ten %[^_.]|aar|are|ENT|ent|OOR|oor|ORE|ore|![aeiou] 2345-26
+noback match - teo L|l|RET|ret|RIE|rie 2345-15-135
+noback match - ter %[^_.]|![AEIOUaeiou] 2345-12456
+noback match NUG|nug|T|t|WA|wa ter E%[^_.]|e%[^_.]|END|end|ING|ing 2345-12456
+noback match I|i|ON|on|REPE|repe|SPEK|spek|U|u|VER|ver ter END|end|ING|ing 2345-15-1235
+noback match BAK|bak ter I|i 2345-15-1235
+noback match ma ter i[aeë] 2345-15-1235
+noback match %a ter IG|ig 2345-12456
+noback match %a teria %[^_.]|W|w 2345-15-1235-24-1
+noback match - tog A%[^_.]|a%[^_.]|AS|as|AAM|aam|AME|ame|AMIE|maie|ER|er|ING|ing|RAAF|raaf|RAFEER|rafeer|RAFI|rafi|RAWE|rawe 2345-135-1245
+
+#v
+noback match - vaste ![AEIOUaeiou]|%[^_.] 1236-1-34-15
+noback match %[^_.] vere [BbGgHhJjKkLlMmPpSsTtVv] 1236-15-1235-15
+noback match - vol U![AEIOU]|u![aeiou] 1236-135-123
+
+#w
+noback match - waarder EN|en|ING|ing 2456-2-1235-145-15-1235
+noback match - was EMMER|emmer 346
+noback match %[^_.] was EM|em|IG|ig 2456-1-234
+noback match BE|be|GE|ge|!%1 wer E|e|ING|ing 2456-15-1235
+
+# Alphabet contractions (alone standing):
+
+word as 1
+word baie 12
+word sal 14
+word dan 145
+word ek 15
+word om 124
+word geen 1245
+word hy 125
+word is 24
+word jy 245
+word kan 13
+word liefde 123
+word my 134
+word nie 1345
+word ook 135
+word plek 1234
+word ons 12345
+word reeds 1235
+word so 234
+word tot 2345
+word van 1236
+word wil 2456
+word het 1346
+word sy 13456
+word 'n 1356
+
+# Alone-standing word sign contractions
+word ander 12346
+word want 123456
+word eindelik 146
+word iets 1456
+word een 156
+word erken 12456
+word wat 246
+word stil 34
+
+# Apostrophe followed by a letter at the end of words
+endword 's 3-234
+endword 't 3-2345
+
+# Higher group sign contractions not alone-standing
+partword an 12346
+partword ge 123456
+always of 12356
+always die 2346
+always met 23456
+always sk 16
+always aan 126
+partword ei 146
+partword ie 1456
+always ee 156
+always al 1246
+always er 12456
+always ou 1256
+partword oe 246
+always st 34
+always was 346
+always ui 345
+
+# Lower words when back translating
+
+# Lower sign group letter contractions
+midword aa 2
+begword be 23
+midword be 23
+begword on 25
+midword on 25
+begword deur 256
+partword en 26
+begmidword te 235
+midword oo 2356
+partword in 35
+begmidword by 356
+
+# Dot 5 contractions
+always dag 5-145
+always familie 5-124
+always goeie 5-1245
+always hul 5-125
+always jul 5-245
+always kom 5-13
+always lewe 5-123
+always moet 5-134
+always nooit 5-1345
+always onder 5-135
+always party 5-1234
+always reg 5-1235
+always sien 5-234
+always tyd 5-2345
+always uur 5-136
+always vol 5-1236
+always werk 5-2456
+always kry 5-13456
+always nog 5-1356
+always antwoord 5-12346
+always wanneer 5-123456
+always dieselfde 5-2346
+always iemand 5-1456
+
+# Dot 45 contractions
+always doen 45-145
+always graag 45-1245
+always hulle 45-125
+always julle 45-245
+always net 45-1345
+always self 45-234
+always tussen 45-2345
+word vir 45-1236
+always woord 45-2456
+always dit 45-2346
+
+# Dot 456 contractions
+always darem 456-145
+always hard 456-125
+always koning 456-13
+always mens 456-134
+always nuwe 456-1345
+always oor 456-135
+always praat 456-1234
+always seker 456-234
+always tog 456-2345
+always voor 456-1236
+always weer 456-2456
+always dat 456-2346
+
+# Dot 46 contractions
+midendword heid 46-145
+always tjie 46-15
+midendword agtig 46-1245
+midendword djie 46-1456
+
+# Dot 56 contractions
+midendword lik 56-13
+
+ # Words indicated by two or more signs
+word alhoewel 1246-125-2456
+word alles 1246-123
+word almal 1246-134
+word alreeds 1246-1235
+word begin 23-1245
+word behoort 23-125
+word besluit 23-234-123
+contraction BRL
+contraction brl
+word braille 12-1235-123
+contraction BR
+contraction br
+word brief 12-1235
+contraction DR
+contraction dr
+word daar 145-1235
+word daardie 145-2346
+word daarin 145-1235-35
+contraction DN
+contraction dn
+word daarna 145-1345
+contraction DM
+contraction dm
+word daarom 145-134
+contraction DP
+contraction dp
+word daarop 145-1234
+contraction DV
+contraction dv
+word daarvan 145-1236
+word daarvoor 145-456-1236
+word dadelik 145-56-13
+contraction DW
+contraction dw
+word dikwels 145-2456
+contraction DK
+contraction dk
+word duidelik 145-13
+word gebruik 123456-12
+word gedurende 123456-145
+word gemaak 123456-134-13
+word genoeg 123456-1345
+word gewees 123456-2456-234
+word geweet 123456-2456-2345
+word geword 123456-2456-145
+contraction GD
+contraction gd
+word goed 1245-145
+contraction GRT
+contraction grt
+word groot 1245-1235-2345
+word grootste 1245-1235-2345-34-15
+contraction HR
+contraction hr
+word haar 125-1235
+contraction HLT
+contraction hlt
+word heeltemal 125-123-2345
+word hierdie 125-2346
+contraction HW
+contraction hw
+word hoewel 125-2456
+contraction HM
+contraction hm
+word hom 125-134
+contraction JR
+contraction jr
+word jaar 245-1235
+contraction KD
+contraction kd
+word kind 13-145
+contraction KDS
+contraction kds
+word kinders 13-145-234
+contraction KT
+contraction kt
+word kort 13-2345
+contraction LT
+contraction lt
+word laat 123-2345
+contraction MK
+contraction mk
+word maak 134-13
+contraction MR
+contraction mr
+word maar 134-1235
+word miskien 134-16
+contraction MTK
+contraction mtk
+word moontlik 134-2345-13
+contraction NTK
+contraction ntk
+word natuurlik 1345-2345-13
+contraction MD
+contraction md
+word omdat 134-145
+word omstandighede 135-134-34-145-15
+contraction OMT
+contraction omt
+word omtrent 135-134-2345
+word ontvang 25-2345-1236
+contraction PR
+contraction pr
+word paar 1234-1235
+contraction PB
+contraction pb
+word probeer 1234-12
+word skryf 16-1235
+word sodat 234-456-2346
+contraction SS
+contraction ss
+word soos 234-234
+contraction TN
+contraction tn
+word teen 2345-1345
+contraction TW
+contraction tw
+word terwyl 2345-2456
+word totdat 2345-456-2346
+contraction VD
+contraction vd
+word vandag 1236-145
+contraction WR
+contraction wr
+word waar 2456-1235
+word waarheid 2456-1235-46-145
+word waarin 2456-1235-35
+contraction WM
+contraction wm
+word waarom 2456-134
+contraction WP
+contraction wp
+word waarop 2456-1234
+contraction WV
+contraction wv
+word waarvan 2456-1236
+word waarvoor 2456-456-1236
+contraction WS
+contraction ws
+word wees 2456-234
+contraction WT
+contraction wt
+word weet 2456-2345
+contraction WD
+contraction wd
+word word 2456-145
+
+# Specific rules:
+
+###'
+nofor midendword 'tjie 3-46-15
+
+###.
+word . 56-256
+
+###a
+contraction a
+contraction A
+midword aai 2-24
+sufword aal =
+always aandele 126-145-15-123-15
+always agter 1-1245-2345-12456
+always adres =
+begword afker =
+always afskort 1-124-16-135-1235-2345
+sufword aftel =
+endword ala =
+always aland 1-123-12346-145
+midendword aleryk =
+endword ales =
+always aliter 1-123-24-2345-12456
+word almiskie 1246-134-24-16-1456
+begword ameri =
+prfword ana =
+midendword anett 1-45-1345-2345
+always anger 12346-1245-12456 # aanhanger/bangerig/langer/visvangers/sangeres
+always anies 1-1345-1456-234
+always anomalie 12346-135-134-1246-1456
+always arbitrage =
+always argitek 1-1235-1245-24-2345-15-13
+begword arter =
+begword asbes 1-234-12-15-234
+always astrant 1-34-1235-12346-2345
+always as't =
+
+###b
+contraction b
+contraction B
+begword baie =
+always balie 12-1-123-1456
+always bber 12-12-12456
+begword beat 12-15-1-2345
+begword beau =
+always bedjie 12-15-46-1456
+always bee 12-156
+always beesk 12-156-234-13
+always beginsel 23-1245-35-234-15-123
+always begonia 23-1245-135-1345-24-1
+always beher 23-125-15-1235
+always bei 12-146
+always bekering 23-13-15-1235-35-1245
+begword beneri 12-15-1345-12456-24
+word bere =
+always besem =
+always beseten 23-234-15-2345-26
+always bestee 23-34-156
+always bestek 23-34-15-13
+sufword bester 12-15-34-12456
+always beter 12-15-2345-12456
+always beties 12-15-2345-1456-234
+always beu =
+always bewing 12-15-2456-35-1245
+always blaaskans 12-123-2-234-13-12346-234
+always bleskop =
+always blomerus =
+always boere 12-246-1235-15
+always bona =
+always bonus =
+always boskasie 12-135-16-1-234-1456
+always boskop =
+begword braille =
+always burger 12-136-1235-1245-12456
+
+###c
+contraction c
+contraction C
+always chloro =
+
+###d
+contraction d
+contraction D
+always daar's 145-2-1235-3-234
+always deposito =
+begword dereg =
+endword dge =
+always diabetes 145-24-1-12-15-235-234
+always diee 145-24-156
+always diegene 2346-1245-15-1345-15
+always dimens 145-24-134-26-234
+always diskoers 145-24-16-246-1235-234
+always diskonter 145-24-16-25-2345-15-1235
+always doeane 145-246-1-1345-15
+always dreiner 145-1235-146-1345-15-1235
+
+###e
+contraction e
+word eerstens 156-1235-34-26-234
+begmidword eerste 156-1235-34-15
+contraction E
+begword ekskl 15-13-16-123
+begword engel 26-123456-123
+midword enywer 15-1345-13456-2456-12456
+sufword ere =
+midendword ereg 15-5-1235
+endword eryk =
+always etienne 15-2345-24-26-1345-15
+
+###f
+contraction f
+contraction F
+sufword feniks =
+always fenomen =
+midendword feries 124-15-1235-1456-234
+always folio =
+always folter 124-135-123-2345-12456
+
+###g
+contraction g
+contraction G
+always ganery 1245-1-1345-12456-13456
+prfword gebel 123456-12-15-123
+always gee 1245-156
+always gei 1245-146
+always gegewens 123456-1245-15-2456-26-234
+always gemenebes 123456-134-15-1345-15-12-15-234
+endword gese =
+partword gest 123456-34
+prfword getel 123456-2345-15-123
+always geu =
+begword glas =
+begword globale =
+always gods =
+always grader =
+always grimer =
+always groeper 1245-1235-246-1234-15-1235
+always grotere 1245-1235-135-2345-12456-15
+always grys =
+always g'n 1245-3-1345
+
+###h
+contraction h
+contraction H
+always hane =
+always hanter 125-12346-2345-15-1235
+always hartstog 125-1-1235-2345-234-456-2345
+always hawereg 125-1-2456-15-5-1235
+always helikop =
+always herenig 125-12456-15-1345-24-1245
+always hister 125-24-34-15-1235
+always honger 125-25-1245-12456
+always honor =
+always hoog 125-2356-1245
+always hotel =
+always houtskool 125-1256-2345-234-13-2356-123
+always huis 125-345-234
+always hy's 125-13456-3-234
+always hy't 125-13456-3-2345
+always h'm 125-3-134
+
+###i
+contraction i
+contraction I
+always iee 24-156
+always ieu 24-15-136
+always ieui 1456-345
+always ingenieur 35-1245-26-24-15-136-1235
+always inter 35-2345-12456
+always item =
+
+###j
+contraction j
+contraction J
+always ja'k 245-1-3-13
+always julie 245-136-123-1456
+always jy's 245-13456-3-234
+always jy't 245-13456-3-2345
+
+###k
+contraction k
+contraction K
+always kabinet 13-1-12-24-45-1345
+always kalender 13-1246-26-145-12456
+always kalium =
+always kameralens 13-1-134-12456-1-123-26-234
+always kaner 13-1-1345-12456
+always karakter 13-1-1235-1-13-2345-12456
+begmidword karoo 13-1-1235-2356
+always kasty 13-1-34-13456
+begword kenter 13-26-2345-12456
+word kere =
+always kieue 13-1456-136-15
+begword kleinser 13-123-146-1345-234-15-1235
+always klere 13-123-15-1235-15
+begword klets =
+begword koelte 13-246-123-235
+always kompanie 5-13-1234-12346-1456
+always konink 13-135-1345-35-13
+always konstabel 13-25-34-1-23-123
+always konyn =
+always kosmetie 13-135-234-134-15-2345-1456
+always kriminer 13-1235-24-134-35-15-1235
+always kriskras =
+always kryk =
+always kwalik 13-2456-1-56-13
+
+###l
+contraction l
+contraction L
+word laaskeer 123-2-234-13-156-1235
+always laning 123-1-1345-35-1245
+always later 123-1-2345-12456
+always likwid =
+always literat 123-24-2345-12456-1-2345
+always lokomo =
+always leraar 123-15-1235-2-1235
+prfword lere =
+always liegery 123-1456-1245-12456-13456
+always lokale =
+begword los =
+always louter 123-1256-2345-12456
+always luitenan 123-345-2345-26-12346
+
+###m
+contraction m
+contraction M
+always maar's 134-2-1235-3-234
+always maaskaas 134-2-234-13-2-234
+always madagaskar 134-1-145-1-1245-1-16-1-1235
+always magnet =
+always makaber 134-1-13-1-12-12456
+word maskas 134-1-16-1-234
+begword mede =
+always menasie 134-15-1345-1-234-1456
+word menere 134-26-15-1235-15
+always mentering 134-26-2345-15-1235-35-1245
+always metjie 134-15-46-15
+midword metoe 134-15-2345-246
+begword metr =
+sufword midderif =
+always moedersknie 134-246-145-12456-234-13-1345-1456
+always moestas 134-246-34-1-234
+always monarg =
+always monder 134-25-145-15-1235
+begword monet =
+always monit =
+always mono =
+always monumen 134-135-1345-136-134-26
+
+###n
+contraction n
+contraction N
+word nanag =
+sufword nasien 1345-1-5-234
+word nete =
+midendword netjie 1345-15-46-15
+always nieu 1345-1456-136
+word nering 1345-15-1235-35-1245
+
+###o
+contraction o
+contraction O
+always oei 246-24
+always oeuvre =
+word ontering 25-2345-15-1235-35-1245
+always ofie 135-124-1456
+sufword onus =
+always onêr =
+midendword ooi 2356-24
+word ooie =
+begword oon =
+always oorlogs 456-135-123-135-1245-234
+always ooskus =
+always opbel =
+always optel =
+sufword outo 1256-2345-135
+
+###p
+contraction p
+contraction P
+begword perde 1234-12456-145-15
+word pere =
+always prestige 1234-1235-15-34-24-1245-15
+always protest 1234-1235-135-235-34
+always protes =
+always proteïen 1234-1235-135-2345-15-45-25-24-15-1345
+always puntener 1234-136-1345-2345-26-15-1235
+
+###q
+contraction q
+contraction Q
+
+###r
+contraction r
+contraction R
+always rebel =
+always redener 1235-15-145-26-15-1235
+always regul =
+always regter 5-1235-2345-12456
+always requiem =
+always riskant 1235-24-16-12346-2345
+always roskam =
+begword roter =
+always ruskans 1235-136-234-13-12346-234
+
+###s
+contraction s
+contraction S
+always s'n 234-3-1345
+always sameroep 234-1-134-15-1235-246-1234
+always salomo =
+always samen 234-1-134-26
+prfword sere =
+sufword serie 234-15-1235-1456
+endword serie 234-15-1235-1456
+always serum 234-15-1235-136-134
+begword ses =
+always sestig 234-15-34-24-1245
+always silwer 234-24-123-2456-12456
+always singery 234-35-1245-12456-13456
+always sirene =
+always skafee 234-13-1-124-156
+always skaker 16-1-13-15-1235
+always skapit =
+always skater 16-1-2345-12456
+midendword skeerkring 234-13-156-1235-13-1235-35-1245
+prfword skene 16-15-1345-15
+always skl =
+always skomen 234-13-135-134-26 # eerskomende/laaskomende
+always skomitee 234-5-13-24-2345-156
+always skommis 234-5-13-134-24-234
+always skontr 234-13-25-2345-1235
+always skoste 234-13-135-34-15
+always skredie 234-13-1235-15-2346
+midword skredit =
+always skrobber 16-1235-135-12-12-15-1235
+always skund =
+always skursus =
+always slanery 234-123-1-1345-12456-13456
+always slinger 234-123-35-1245-12456
+always sorter =
+always sous 234-1256-234
+always spinnerak 234-1234-35-1345-15-1235-1-13
+midendword stabel =
+prfword stanery 34-1-1345-12456-13456
+always stereo 34-15-1235-15-135
+always stralek 34-1235-1-123-15-13
+midword strekk =
+always strengel 34-1235-26-123456-123
+always strofe 34-1235-135-124-15
+always studer 34-136-145-15-1235
+always styd 234-5-2345
+begword sub =
+begword sugg 234-136-1245-1245
+prfword suite =
+sufword sultana =
+always sy's 234-13456-3-234
+always sy't 234-13456-3-2345
+
+###t
+contraction t
+contraction T
+always tabel =
+always tee 2345-156
+always tei 2345-146
+endword teke 2345-15-13-15
+always teken 2345-15-13-26
+word tel =
+sufword teleks =
+word teling 2345-15-123-35-1245
+begword telk =
+midendword tenis 2345-26-24-234
+always tepel =
+word tere =
+always terg 2345-12456-1245
+sufword tering 2345-15-1235-35-1245
+always terugker 235-1235-136-1245-13-15-1235
+word tes =
+begword tesour 2345-15-234-1256-1235
+begword test 2345-15-34
+always teu =
+word tewens 2345-15-2456-26-234
+begword tinger 2345-35-1245-12456
+always toonaangew 2345-2356-1345-126-1245-15-2456
+always tragedie 2345-1235-1-1245-15-2346
+always teë =
+always teï =
+
+###u
+always uiter 345-2345-12456
+always uitsteken 345-2345-34-15-13-26
+
+###v
+contraction v
+contraction V
+always vang 1236-12346-1245
+endword vange 1236-12346-123456
+endword vangeneming 1236-12346-123456-1345-15-134-35-1245
+begword vas =
+prfword vaster 1236-1-34-12456
+prfword vere =
+begword vergetel 1236-12456-1245-15-235-123
+begword vergeten 1236-12456-1245-15-2345-26
+always verkenningstog 1236-12456-13-26-1345-35-1245-234-456-2345
+always vermetel 1236-12456-134-15-235-123
+always vermiste 1236-12456-134-24-34-15
+always verskal 1236-12456-234-13-1246
+always vertel 1236-12456-2345-15-123
+always vester 1236-15-34-15-1235
+always veter 1236-15-2345-12456
+always vinger 1236-35-1245-12456
+always viskop =
+always viskuit 1236-24-234-13-345-2345
+always visteelt 1236-24-234-2345-156-123-2345
+endword vole =
+word volt =
+always vomer =
+always voornemens 456-1236-1345-15-134-26-234
+always vredestog 1236-1235-15-145-15-234-456-2345
+always vroue 1236-1235-1256-15
+always vrouens 1236-1235-1256-26-234
+always vrygewi 1236-1235-13456-1245-15-2456-24
+
+###w
+contraction w
+contraction W
+always waar's 2456-2-1235-3-234
+always wassen 346-234-26
+always water 2456-1-2345-12456
+always wat-s 2456-1-2345-3-234
+always wederker 2456-15-145-12456-13-15-1235
+always welterge 2456-15-123-2345-12456-123456
+always werkgew 5-2456-1245-15-2456
+always weskus =
+always wins 2456-35-234
+always winste 2456-35-34-15
+always wysger =
+
+###x
+contraction x
+contraction X
+
+###y
+contraction y
+contraction Y
+begword yskou 13456-234-13-1256
+
+###z
+contraction z
+contraction Z
+word zero =
+
+###á
+always ál =
+
+###ó
+always óf =
+
+###ë
+always ëe =
+always ëi 45-25-15-24
+always ënter =
+
diff --git a/tables/ar-ar-comp8.utb b/tables/ar-ar-comp8.utb
new file mode 100644
index 0000000..e7f9971
--- /dev/null
+++ b/tables/ar-ar-comp8.utb
@@ -0,0 +1,248 @@
+# liblouis: Arabic Computer Braille table
+# Copyright (C) 2018 by Ikrami Ahmad <ikrami.ahmad@gmail.com>
+
+# This file is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This file is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this file; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#-index-name: Arabic, computer
+#-display-name: Arabic computer braille
+#-author-name: Ikrami Ahmad
+#-author-email: ikrami.ahmad@gmail.com
+# with assistance from Hatoon Felemban <h.felemban@hotmail.com>
+
+#+locale: ar
+#+type: computer
+#+dots: 8
+
+include text_nabcc.dis All display opcodes
+include braille-patterns.cti # unicode braille.
+
+space \s 0 blank
+space \t 0 tab
+space \x000A 0
+space \x000D 0
+
+# Arabic characters
+letter ء 3 # arabic individual hamza (\x0621)
+letter آ 345 # arabic alef madd (\x0622)
+letter أ 34 # arabic hamza above alef (\x0623)
+letter ؤ 1256 # arabic hamza on waw (\x0624)
+letter إ 46 # arabic hamza below alef (\x0625)
+letter ئ 13456 # arabic hamza on iaa (\x0626)
+letter ا 1 # arabic Alef (\x0626)
+letter ب 12 # arabic baa (\x0628)
+letter ة 16 # arabic taa marbuta (\x0629)
+letter ث 1456 # arabic thaa (\x062B)
+letter ت 2345 # arabic Taa (\x062A)
+letter ج 245 # arabic jeem (\x062C)
+letter ح 156 # arabic strong haa (\x062D)
+letter خ 1346 # arabic Khaa (\x062E)
+letter د 145 # arabic dal (\x062F)
+letter ذ 2346 # arabic thal (\x0630)
+letter ر 1235 # arabic raa (\x0631)
+letter ز 1356 # arabic zaai (\x0632)
+letter س 234 # arabic seen (\x0633)
+letter ش 146 # arabic sheen (\x0634)
+letter ص 12346 # arabic saad (\x0635)
+letter ض 1246 # arabic dhaad (\x0636)
+letter ط 23456 # arabic strong taa (\x0637)
+letter ظ 123456 # arabic strong thaa (\x0638)
+letter ع 12356 # arabic ayn (\x0639)
+letter غ 126 # arabic ghayn (\x063A)
+letter ف 124 # arabic faa (\x0641)
+letter ق 12345 # arabic strong qaaf (\x0642)
+letter ك 13 # arabic kaaf (\x0643)
+letter ل 123 # arabic laam (\x0644)
+letter م 134 # arabic meem (\x0645)
+letter ن 1345 # arabic noon (\x0646)
+letter ه 125 # arabic soft haa (\x0647)
+letter و 2456 # arabic waaw (\x0648)
+letter ى 135 # arabic alef maqsoora (\x0649)
+letter ي 24 # arabic iaa (\x064A)
+letter َ 2 # arabic diacritic symbol fathah (\x064E)
+letter ِ 15 # arabic diacritic symbol kasrah (\x0650)
+letter ً 23 # arabic diacritic symbol tanween fath (\x064B)
+letter ٌ 26 # arabic diacritic symbol tanween dham (\x064C)
+letter ٍ 35 # arabic diacritic symbol tanween kasr (\x064D)
+letter ُ 136 # arabic diacritic symbol dhamma (\x064F)
+letter ّ 6 # arabic diacritic symbol shadda (\x0651)
+letter ْ 25 v# arabic diacritic symbol sukoon (\x0652)
+sign ـ 58 # arabic tatweel (\x0640)
+always \x0644\x0627 1236 # to join lam and alef together in one cell if they come in one word
+midendword \x0651 6 # to indicate that Shadda can never come at the beginning of a word
+
+#the following to correct Shadda symbol, which should be written before the character in Arabic braille code. this will consists of every arabic character followed by the Shadda diacritic symbol, and a dot pattern of the braille shadda followed by the character.
+noback always ءّ 6-3
+noback always آّ 6-345
+noback always أّ 6-34
+noback always ؤّ 6-1256
+noback always إّ 6-46
+noback always ئّ 6-13456
+noback always اّ 6-1
+noback always بّ 6-12
+noback always ةّ 6-16
+noback always ثّ 6-1456
+noback always تّ 6-2345
+noback always جّ 6-245
+noback always حّ 6-156
+noback always خّ 6-1346
+noback always دّ 6-145
+noback always ذّ 6-2346
+noback always رّ 6-1235
+noback always زّ 6-1356
+noback always سّ 6-234
+noback always شّ 6-146
+noback always صّ 6-12346
+noback always ضّ 6-1246
+noback always طّ 6-23456
+noback always ظّ 6-123456
+noback always عّ 6-12356
+noback always غّ 6-126
+noback always فّ 6-124
+noback always قّ 6-12345
+noback always كّ 6-13
+noback always لّ 6-123
+noback always مّ 6-134
+noback always نّ 6-1345
+noback always هّ 6-125
+noback always وّ 6-2456
+noback always يّ 6-24
+noback always لاّ 6-1236
+
+# Latin numerals
+digit 0 2458
+digit 1 18
+digit 2 128
+digit 3 148
+digit 4 1458
+digit 5 158
+digit 6 1248
+digit 7 12458
+digit 8 1258
+digit 9 248
+
+# Arabic numerals
+digit \x0660 2458 # 0 (٠)
+digit \x0661 18 # 1 (١)
+digit \x0662 128 # 2 (٢)
+digit \x0663 148 # 3 (٣)
+digit \x0664 1458 # 4 (٤)
+digit \x0665 158 # 5 (٥)
+digit \x0666 1248 # 6 (٦)
+digit \x0667 12458 # 7 (٧)
+digit \x0668 1258 # 8 (٨)
+digit \x0669 248 # 9 (٩)
+
+# English letters backward translation only
+nofor uplow Aa 17,178
+nofor uplow Bb 1278,1278
+nofor uplow Cc 147,1478
+nofor uplow Dd 1457,14578
+nofor uplow Ee 157,1578
+nofor uplow Ff 1247,12478
+nofor uplow Gg 12457,124578
+nofor uplow Hh 1257,12578
+nofor uplow Ii 247,2478
+nofor uplow Jj 2457,24578
+nofor uplow Kk 137,1378
+nofor uplow Ll 1237,12378
+nofor uplow Mm 1347,13478
+nofor uplow Nn 13457,134578
+nofor uplow Oo 1357,13578
+nofor uplow Pp 12347,123478
+nofor uplow Qq 123457,1234578
+nofor uplow Rr 12357,123578
+nofor uplow Ss 2347,23478
+nofor uplow Tt 23457,234578
+nofor uplow Uu 1367,13678
+nofor uplow Vv 12367,123678
+nofor uplow Ww 24567,245678
+nofor uplow Xx 13467,134678
+nofor uplow Yy 134567,1345678
+nofor uplow Zz 13567,135678
+
+#adding the standard 8-dot latin letters for proper forward translation
+include latinLetterDef8Dots.uti
+
+#punctuation symbols
+punctuation ، 5 # Arabic comma (\x060C)
+punctuation \x061B 56 # Arabic semiColon
+punctuation ; 56
+punctuation : 257
+punctuation \x061F 346 # Arabic question mark ؟
+punctuation ? 346
+punctuation \x06D4 256 # Arabic Full stop
+punctuation . 256
+punctuation , 27
+punctuation ! 235
+punctuation " 2356
+sign # 3456
+punctuation % 45
+sign & 123467
+noback punctuation ' 3 # apostrophe
+nofor punctuation ' 38 # apostrophe
+punctuation ) 356
+punctuation ( 236
+sign * 358
+math + 2358
+math \x00D7 2368 # × multiplication sign
+math \x00F7 2568 # ÷ division sign
+math > 1358
+math < 2467
+math / 348
+math = 235678
+punctuation - 36
+sign @ 4
+punctuation ‘ 378
+punctuation ’ 678
+punctuation [ 123567
+sign \\ 347
+punctuation ] 234568
+sign ^ 23468 # circumflex accent
+sign _ 568
+sign ` 34578 # grave accent
+punctuation { 23567
+sign | 3458
+punctuation } 23568
+math ~ 3457
+space \x00A0 0 # no-break space
+punctuation \x00Ad 36 # soft hyphen
+punctuation « 1234567 # left-pointing double angle quotation mark
+punctuation » 1234568 # right-pointing double angle quotation mark
+punctuation \x2018 2356 # smart single left quotation mark
+punctuation \x2019 2356 # smart single right quotation mark
+punctuation \x201C 2356 # smart opening double quote
+punctuation \x201D 2356 # smart closing double quote
+punctuation \x201E 2356 # smart double low quotation mark
+punctuation \x201F 2356 # smart double high reverse quotation mark
+
+sign \x00BF 346 # inverted question mark
+sign \x200C 9 # ZERO WIDTH NON-JOINER
+punctuation \x2010 36 # hyphen
+punctuation \x2011 36 # non-breaking hyphen
+punctuation \x2013 3678 # en dash
+punctuation \x2026 25678 # smart ellipsis
+sign $ 456
+sign \x20AC 4568 # Euro sign
+sign \x00A2 468 # ¢ cents sign
+sign \x00A3 467 # £ pounds sign
+sign \x00A5 4678 # ¥ yen sign
+sign \x00A7 2348 # section sign §
+sign \x00A9 123468 # © copyright sign
+sign \x00AE 12358 # ® Registered mark
+sign \x00B0 123458 # ° degrees sign
+sign \x00B5 1348 # µ micro sign
+sign \x00B6 12348 # ¶ pilcrow sign
+
+include countries.cti
diff --git a/tables/ar-ar-g1.utb b/tables/ar-ar-g1.utb
new file mode 100644
index 0000000..7f9f8d5
--- /dev/null
+++ b/tables/ar-ar-g1.utb
@@ -0,0 +1,299 @@
+# liblouis: Generic Arabic Grade 1 table
+#
+# Copyright (C) 1995-2004 by The BRLTTY Team.
+# Copyright (C) 2004 by ViewPlus Technologies, Inc., www.viewplustech.com
+# Copyright (C) 2004 by Computers to Help People, Inc., www.chpi.org
+# Copyright (C) 2011-2012 by Mesar Hameed <mesar.hameed@gmail.com>
+# Copyright (C) 2018 by Ikrami Ahmad <ikrami.ahmad@gmail.com>
+
+# This file is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This file is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this file; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# This table was originally built by Leon Ungier <Leon.Ungier@ViewPlus.com>
+# with help and guidance from Mohammed R. Ramadan <mramadan@nattiq.com>
+
+include text_nabcc.dis All display opcodes
+include spaces.uti
+include braille-patterns.cti # unicode braille.
+
+# Arabic characters
+letter ء 3 # arabic individual hamza (\x0621)
+letter آ 345 # arabic alef madd (\x0622)
+letter أ 34 # arabic hamza above alef (\x0623)
+letter ؤ 1256 # arabic hamza on waw (\x0624)
+letter إ 46 # arabic hamza below alef (\x0625)
+letter ئ 13456 # arabic hamza on iaa (\x0626)
+letter ا 1 # arabic Alef (\x0626)
+letter ب 12 # arabic baa (\x0628)
+letter ة 16 # arabic taa marbuta (\x0629)
+letter ث 1456 # arabic thaa (\x062B)
+letter ت 2345 # arabic Taa (\x062A)
+letter ج 245 # arabic jeem (\x062C)
+letter ح 156 # arabic strong haa (\x062D)
+letter خ 1346 # arabic Khaa (\x062E)
+letter د 145 # arabic dal (\x062F)
+letter ذ 2346 # arabic thal (\x0630)
+letter ر 1235 # arabic raa (\x0631)
+letter ز 1356 # arabic zaai (\x0632)
+letter س 234 # arabic seen (\x0633)
+letter ش 146 # arabic sheen (\x0634)
+letter ص 12346 # arabic saad (\x0635)
+letter ض 1246 # arabic dhaad (\x0636)
+letter ط 23456 # arabic strong taa (\x0637)
+letter ظ 123456 # arabic strong thaa (\x0638)
+letter ع 12356 # arabic ayn (\x0639)
+letter غ 126 # arabic ghayn (\x063A)
+letter ف 124 # arabic faa (\x0641)
+letter ق 12345 # arabic strong qaaf (\x0642)
+letter ك 13 # arabic kaaf (\x0643)
+letter ل 123 # arabic laam (\x0644)
+letter م 134 # arabic meem (\x0645)
+letter ن 1345 # arabic noon (\x0646)
+letter ه 125 # arabic soft haa (\x0647)
+letter و 2456 # arabic waaw (\x0648)
+letter ى 135 # arabic alef maqsoora (\x0649)
+letter ي 24 # arabic iaa (\x064A)
+letter َ 2 # arabic diacritic symbol fathah (\x064E)
+letter ِ 15 # arabic diacritic symbol kasrah (\x0650)
+letter ً 23 # arabic diacritic symbol tanween fath (\x064B)
+letter ٌ 26 # arabic diacritic symbol tanween dham (\x064C)
+letter ٍ 35 # arabic diacritic symbol tanween kasr (\x064D)
+letter ُ 136 # arabic diacritic symbol dhamma (\x064F)
+letter ّ 6 # arabic diacritic symbol shadda (\x0651)
+letter ْ 25 # arabic diacritic symbol sukoon (\x0652)
+noback sign ـ 2 # arabic tatweel (\x0640)
+
+always \x0644\x0627 1236 # to join lam and alef together in one cell if they come in one word
+midendword \x0651 6 # to indicate that Shadda can never come at the beginning of a word
+midendword \x0652 25 # arabic diacritic symbol sukoon (\x0652)
+midendword َ 2
+
+#the following to correct Shadda symbol, which should be written before the character in Arabic braille code. this will consists of every arabic character followed by the Shadda diacritic symbol, and a dot pattern of the braille shadda followed by the character.
+noback always ءّ 6-3
+noback always آّ 6-345
+noback always أّ 6-34
+noback always ؤّ 6-1256
+noback always إّ 6-46
+noback always ئّ 6-13456
+noback always اّ 6-1
+noback always بّ 6-12
+noback always ةّ 6-16
+noback always ثّ 6-1456
+noback always تّ 6-2345
+noback always جّ 6-245
+noback always حّ 6-156
+noback always خّ 6-1346
+noback always دّ 6-145
+noback always ذّ 6-2346
+noback always رّ 6-1235
+noback always زّ 6-1356
+noback always سّ 6-234
+noback always شّ 6-146
+noback always صّ 6-12346
+noback always ضّ 6-1246
+noback always طّ 6-23456
+noback always ظّ 6-123456
+noback always عّ 6-12356
+noback always غّ 6-126
+noback always فّ 6-124
+noback always قّ 6-12345
+noback always كّ 6-13
+noback always لّ 6-123
+noback always مّ 6-134
+noback always نّ 6-1345
+noback always هّ 6-125
+noback always وّ 6-2456
+noback always يّ 6-24
+noback always لاّ 6-1236
+
+punctuation ، 5 # Arabic comma (\x060C)
+punctuation \x061B 56 # Arabic semiColon
+punctuation ; 56
+punctuation : 5-2
+punctuation \x061F 236 # Arabic question mark ؟
+punctuation ? 236
+punctuation \x06D4 256 # Arabic Full stop
+punctuation . 256
+punctuation , 2
+punctuation ! 235
+punctuation " 2356
+sign # 3456
+sign $ 4-234
+punctuation % 25-1234
+sign & 4-12346
+punctuation ' 3 # apostrophe
+punctuation ) 356
+punctuation ( 236
+sign * 56-35
+math + 56-235
+punctuation - 36-36
+math / 456-36 # changed from the unified braille code, so that it does not conflict with the letter \x0623
+
+# Braille indicators
+numsign 3456 number sign, just a dots operand
+noback multind 56-6 letsign capsletter
+# letsign 56
+noback capsletter 6
+noback begcapsword 6-6
+noback endcapsword 6-3
+emphclass italic
+emphclass underline
+emphclass bold
+noback begemph italic 46
+noback endemph italic 46-46
+noback begemph bold 456
+noback endemph bold 456-456
+noback begcomp 456-346
+noback endcomp 456-156
+
+# Arabic numbers
+digit \x0660 245 # 0 (٠)
+digit \x0661 1 # 1 (١)
+digit \x0662 12 # 2 (٢)
+digit \x0663 14 # 3 (٣)
+digit \x0664 145 # 4 (٤)
+digit \x0665 15 # 5 (٥)
+digit \x0666 124 # 6 (٦)
+digit \x0667 1245 # 7 (٧)
+digit \x0668 125 # 8 (٨)
+digit \x0669 24 # 9 (٩)
+litdigit \x0660 245 # 0 (٠)
+litdigit \x0661 1 # 1 (١)
+litdigit \x0662 12 # 2 (٢)
+litdigit \x0663 14 # 3 (٣)
+litdigit \x0664 145 # 4 (٤)
+litdigit \x0665 15 # 5 (٥)
+litdigit \x0666 124 # 6 (٦)
+litdigit \x0667 1245 # 7 (٧)
+litdigit \x0668 125 # 8 (٨)
+litdigit \x0669 24 # 9 (٩)
+
+# Latin numbers
+include loweredDigits6Dots.uti
+include litdigits6Dots.uti
+
+math < 0-246-0
+math = 56-2356
+math > 0-135-0
+sign @ 4-1 # the unified braille code used dot 4 only to represent it. i changed it as it is written in the unified english code, so that it can be read in grade2 as well.
+
+include latinLetterDef6Dots.uti
+punctuation [ 6-236
+sign \\ 45-36 # not mentioned in the Unified arabic braille code.
+punctuation ] 356-3
+sign ^ 346 # circumflex accent
+sign _ 6-36 # underscore
+noback sign ` 4 # grave accent
+punctuation { 5-236
+sign | 5-25 # changed so that it is not confused with number seven or the latin letter g
+punctuation } 356-2
+math ~ 45-25 # changed so that it can be read in grade2 context
+sign \x00A2 4-14 # ¢ cents sign
+sign \x00A3 4-123 # £ pounds sign
+noback sign \x00A5 4-13456 # ¥ yen sign
+noback sign \x00A7 4-234-3 # section sign §
+noback sign \x00A9 2356-6-14-2356 # © copyright sign
+noback sign \x00AE 16-256 # ® Registered mark
+punctuation \x00Ad 36-36 # soft hyphen
+noback sign \x00B0 356 # ° degrees sign
+noback sign \x00B5 46-134 # µ micro sign
+noback sign \x00B6 4-1234-345 # ¶ pilcrow sign
+sign \x00AB 2356 # LEFT-POINTING DOUBLE ANGLE QUOTATION
+sign \x00BB 2356 # RIGHT-POINTING DOUBLE ANGLE QUOTATION
+punctuation \x2018 2356 # smart single left quotation mark
+punctuation \x2019 2356 # smart single right quotation mark
+punctuation \x201C 2356 # smart opening double quote
+punctuation \x201D 2356 # smart closing double quote
+punctuation \x201E 2356 # smart double low quotation mark
+punctuation \x201F 2356 # smart double high reverse quotation mark
+
+sign \x00BF 236 # inverted question mark
+math \x00D7 56-236 # × multiplication sign
+math \x00F7 56-256 # ÷ division sign
+sign \x200C 9 # ZERO WIDTH NON-JOINER
+punctuation \x2010 36-36 # hyphen
+punctuation \x2011 36-36 # non-breaking hyphen
+punctuation \x2013 4-36 # en dash
+punctuation \x2026 3-3-3 # smart ellipsis
+sign \x20AC 4-15 # Euro sign
+noback sign \x25CF 35 # BLACK CIRCLE
+
+include countries.cti
+postpunc ) 356
+prepunc ( 236
+prepunc " 2356
+postpunc " 2356
+word 'em =
+word 'tis =
+word 'twas =
+begnum # 3456-4 print number sign before number
+midnum . 46
+midnum , 2
+postpunc , 2
+decpoint . 46
+midnum - 36-36
+hyphen - 36-36
+#capsnocont
+postpunc ، 5 # Arabic comma (\x060C)
+postpunc . 256
+postpunc \x06D4 256 # Arabic Full stop
+postpunc ; 56
+postpunc \x061B 56 # Arabic semiColon
+midnum : 5-2
+postpunc : 5-2
+postpunc ! 235
+midnum / 456-36
+always / 456-36
+always < 0-246-0
+always > 0-135-0
+postpunc \x061F 236 # Arabic question mark ؟
+postpunc ? 236
+endnum % 25-1234
+midnum ^ 346
+noback always ^ 346
+always ~ 45-25
+always & 4-12346
+midnum * 56-35
+always * 56-35
+always [ 6-236
+always ] 356-3
+always { 5-236
+always } 356-2
+always @ 4-1
+always \\ 45-36
+always | 5-25
+always ... 3-3-3
+always $ 4-234
+
+# special character sequences
+compbrl :// URLs
+compbrl www.
+compbrl .com
+compbrl .edu
+compbrl .gov
+compbrl .mil
+compbrl .net
+compbrl .org
+# include countries.cti
+compbrl .doc
+compbrl .htm
+compbrl .html
+compbrl .tex
+compbrl .txt
+compbrl .gif
+compbrl .jpg
+compbrl .png
+compbrl .wav
+compbrl .tar
+compbrl .zip
diff --git a/tables/ar-ar-g2.ctb b/tables/ar-ar-g2.ctb
new file mode 100644
index 0000000..b786609
--- /dev/null
+++ b/tables/ar-ar-g2.ctb
@@ -0,0 +1,396 @@
+# liblouis: Arabic Grade 2 table
+
+# Copyright (C) 2018 by Ikrami Ahmad <ikrami.ahmad@gmail.com>
+
+# This file is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This file is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this file; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#-index-name: Arabic, contracted
+#-display-name: Arabic contracted braille
+#+locale: ar
+#+type: literary
+#+contraction: full
+#+grade: 2
+#-author-name: Ikrami Ahmad
+#-author-email: ikrami.ahmad@gmail.com
+
+include ar-ar-g1.utb
+
+# first rule: these should be abbriviated everywhere, whether as stand alone word or part of a bigger word.
+always برمج 4-12
+always بعد 5-12
+always بعيد 45-12
+always برنامج 456-12
+
+always تعليم 4-2345
+always تحت 5-2345
+always تدريب 45-2345
+always تدريج 456-2345
+
+always ثقاف 4-1456
+always أثناء 5-1456
+always ثاني 45-1456
+always ثالث 456-1456
+
+always جديد 4-245
+always جميع 5-245
+always جانب 45-245
+always جعل 456-245
+
+always أحيان 4-156
+always حياة 5-156
+always حقيق 45-156
+always حول 456-156
+
+always خروج 4-1346
+always خصوص 5-1346
+always خارج 45-1346
+always خاصة 456-1346
+
+always دقيق 4-145
+always دائم 5-145
+always داخل 45-145
+always دليل 456-145
+
+always ذاهب 4-2346
+always ذلك 5-2346
+always حينئذ 45-2346
+always عندئذ 456-2346
+
+always رياض 4-1235
+always روح 5-1235
+always رئيس 45-1235
+always رسول 456-1235
+
+always زواج 4-1356
+always زمان 5-1356
+always زمن 45-1356
+always زوج 456-1356
+
+always سياس 4-234
+always سريع 5-234
+always سائر 45-234
+always سبيل 456-234
+
+always شيئا 4-146
+always شديد 5-146
+always شاهد 45-146
+always شؤون 456-146
+
+always صديق 4-12346
+always صاحب 5-12346
+always صغير 45-12346
+always صور 456-12346
+
+always ضعيف 4-1246
+always ضمير 5-1246
+always بعض 45-1246
+always ضرور 456-1246
+
+always طبيع 4-23456
+always طريق 5-23456
+always طبع 45-23456
+always طويل 456-23456
+
+always حافظ 4-123456
+always ظاهر 5-123456
+always ظروف 45-123456
+always ظهور 456-123456
+
+always عادة 4-12356
+always عزيز 5-12356
+always عبارة 45-12356
+always عظيم 456-12356
+
+always غادر 4-126
+always غير 5-126
+always غالب 45-126
+always غريب 456-126
+
+always فراغ 4-124
+always فوق 5-124
+always فائدة 45-124
+always فعل 456-124
+
+always قطع 4-12345
+always قليل 5-12345
+always قريب 45-12345
+always قديم 456-12345 # previously partword
+
+always كتاب 4-13
+always كثير 5-13
+always كبير 45-13
+always كاتب 456-13
+
+always لطيف 4-123
+always لكن 5-123
+always لعل 45-123
+always لسان 456-123
+
+always مكفوف 4-134
+always مرة 5-134
+always معنى 45-134
+always معظم 456-134
+
+always ناسب 4-1345
+always نفس 5-1345
+always ناحية 45-1345
+always نعم 456-1345
+
+always هكذا 4-125
+always هذا 5-125
+always هذه 45-125
+always هؤلاء 456-125
+
+always وارد 4-2456
+always واحد 5-2456
+always واجب 45-2456
+always وجود 456-2456
+
+always \x0644\x0627\x0020\x0633\x064A\x0645\x0627 4-1236 # لا سيما
+always \x0644\x0627\x0020\x0634\x0643 5-1236 # لا شك
+always \x0644\x0627\x0020\x0628\x062F 45-1236 # لا بد
+always \x0644\x0627\x0020\x064A\x0632\x0627\x0644 456-1236 # لا يزال
+
+always يسير 4-24
+always أيام 5-24
+always يمكن 45-24
+always يقول 456-24
+
+always أعلى 4-135
+always أولى 5-135
+always أدنى 6-135
+always أخرى 45-135
+always أغنى 56-135
+always أقصى 456-135
+
+always جملة 4-16
+always ساعة 5-16
+always تارة 45-16
+always تربية 56-16
+always لحظة 456-16
+
+always أكبر 4-34
+always أحد 5-34
+always أسفل 6-34
+always أخير 45-34
+always أصغر 56-34
+always أكثر 456-34
+
+always مؤمن 4-1256
+always مسؤول 5-1256
+always مؤلف 6-1256
+always مؤسس 45-1256
+always مؤتمر 56-1256
+always مؤثر 456-1256
+
+always قائل 4-13456
+always لأجل 5-13456
+always سائل 6-13456
+always قائم 45-13456
+always شائع 56-13456
+always فائز 456-13456
+
+always آداب 4-345
+always آراء 5-345
+always آفاق 6-345
+always آخر 45-345
+always آثار 56-345
+always أيها 456-345
+
+always \x0644\x0645\x0020\x064A\x0639\x062F 4-15 # لم يعد
+always \x0644\x0645\x0020\x064A\x0643\x0646 5-15 # لم يكن
+always \x0644\x0645\x0020\x064A\x062A\x0645\x0643\x0646 6-15 # لم يتمكن
+always \x0644\x0645\x0020\x0020\x064A\x0644\x0628\x062B 45-15 # لم يلبث
+always \x0644\x0645\x0020\x064A\x0633\x062A\x0637\x0639 56-15 # لم يستطع
+always \x0644\x0645\x0020\x064A\x0632\x0644 456-15 # لم يزل
+
+always حقوق 4-136
+always حاسب 5-136
+always حاسوب 6-136
+always حروف 45-136
+always حدود 56-136
+always دنيا 456-136
+
+always ال 14
+always اللائي 4-14
+always الذي 5-14
+always الناس 6-14
+always التي 45-14
+always اللاتي 56-14
+always الذين 456-14
+
+always كان 1245
+always كون 4-1245
+always كائن 5-1245
+always كلم 6-1245
+always كريم 45-1245
+always تكوين 56-1245
+always تكنولوجي 456-1245
+
+always ما 1234
+always \x0645\x0627\x0020\x0632\x0627\x0644 4-1234 # ما زال
+always ماذا 5-1234
+always \x0645\x0627\x0020\x0627\x0646\x0641\x0643 6-1234 # ما انفك
+always \x0645\x0627\x0020\x0628\x0631\x062D 45-1234 # ما برح
+always \x0645\x0627\x0020\x062F\x0627\x0645 56-1234 # ما دام
+always \x0645\x0627\x0020\x0639\x062F\x0627 456-1234 # ما عدا
+
+always هم 12456
+always هاجر 4-12456
+always هاتف 5-12456
+always هامش 6-12456
+always هندس 45-12456
+always هيئة 56-12456
+always هيمن 456-12456
+
+always إحصاء 4-246
+always إنسان 5-246
+always إنتاج 6-246
+always إسلام 45-246
+always إخراج 56-246
+always إيمان 456-246
+
+always ين 346
+always ينطبق 4-346
+always ينمو 5-346
+always ينعكس 6-346
+always ينبغي 45-346
+always ينتشر 56-346
+always يندرج 456-346
+
+#Second rule: these should be abbriviated if they come as a single word only, they can't be abbriviated if part of bigger word.
+word أو 1
+word بل 12
+word ثم 1456
+word قد 3
+word كل 345
+
+#Third rule: these should be abbriviated if they are a word or at the beginning of a word only, because of their similarity with diacritic symbols.
+sufword لم 15
+sufword عن 35
+sufword إلى 26
+sufword حيث 136
+sufword مع 23
+sufword لل 25
+
+#fourth rule: these should be abbriviated if they came as a seperate word and if they came in the middle of words only, because of their similarity to punctuation marks.
+lowword هو 236
+lowword متى 2356
+midword هو 236
+midword متى 2356
+
+#fifth rule: these should be abbriviated if they come as a word or part of a word at the beginning or the middle, because of their similarity with punctuation marks that close sentences.
+lowword من 356
+lowword في 235
+lowword ست 256
+begmidword من 356
+begmidword في 235
+begmidword ست 256
+
+#sixth rule: if the following abbriviations come as single words, they should be abbriviated normally. but if they come as a part of bigger word, dots 36 must be placed before the character that represents the abbreviated word.
+#firstly we will identify them as part of bigger words.
+partword تلك 36-2345
+partword جدا 36-245
+partword حتى 36-156
+partword خير 36-1346
+partword إذا 36-246
+partword دخول 36-145
+partword ذاكر 36-2346
+partword ربما 36-1235
+partword زاول 36-1356
+partword سوف 36-234
+partword أيضا 36-1246
+partword شيء 36-146
+partword صار 36-12346
+partword فقط 36-23456
+partword ظهر 36-123456
+partword عسى 36-12356
+partword غاية 36-126
+partword فلما 36-124
+partword قرب 36-12345
+partword كيف 36-13
+partword ليس 36-123
+partword مثل 36-134
+partword نحو 36-1345
+partword هناك 36-125
+partword ولما 36-2456
+partword يوم 36-24
+partword على 36-135
+partword قبل 36-16
+partword أولئك 36-1256
+partword إلا 36-13456
+partword أسئلة 36-34
+
+#as a single word, no 36 placed before the character.
+word تلك 2345
+word جدا 245
+word حتى 156
+word خير 1346
+word إذا 246
+word دخول 145
+word ذاكر 2346
+word ربما 1235
+word زاول 1356
+word سوف 234
+word أيضا 1246
+word شيء 146
+word صار 12346
+word فقط 23456
+word ظهر 123456
+word عسى 12356
+word غاية 126
+word فلما 124
+word قرب 12345
+word كيف 13
+word ليس 123
+word مثل 134
+word نحو 1345
+word هناك 125
+word ولما 2456
+word يوم 24
+word على 135
+word قبل 16
+word أولئك 1256
+word إلا 13456
+word إسئلة 34
+
+#seventh rule: if the letter that procedes any of these abbreviations consists of dots 1 2 and 3 only, they should not be abbreviated.
+#here i will use the match opcode to define the 6 possible characters that can come before these contractions.
+match ل ون %[_.^] 2456-1345
+match ب ون %[_.^] 2456-1345
+match ا ون %[_.^] 2456-1345
+match ك ون %[_.^] 2456-1345
+match ء ون %[_.^] 2456-1345
+match َ ون %[_.^] 2456-1345
+
+match ل ات %[_.^] 1-2345
+match ب ات %[_.^] 1-2345
+match ا ات %[_.^] 1-2345
+match ك ات %[_.^] 1-2345
+match ء ات %[_.^] 1-2345
+match َ ات %[_.^] 1-2345
+
+match ل ية %[_.^] 24-16
+match ب ية %[_.^] 24-16
+match ا ية %[_.^] 24-16
+match ك ية %[_.^] 24-16
+match ء ية %[_.^] 24-16
+match َ ية %[_.^] 24-16
+
+#eighth rule: those should be abbreviated only at the end of word.
+endword ات 46
+endword ون 456
+endword ية 45
+endword وا 3456
diff --git a/tables/ar.tbl b/tables/ar.tbl
new file mode 100644
index 0000000..03570e7
--- /dev/null
+++ b/tables/ar.tbl
@@ -0,0 +1,19 @@
+#-index-name: Arabic, uncontracted
+#-display-name: Arabic uncontracted braille
+
+#+locale:ar
+#+type:literary
+#+contraction:no
+#+grade:1
+
+# TODO: Please correct the metadata above. It is not meant to be
+# accurate nor complete. It hasn't been verified by the table
+# author yet. It is merely an attempt by the liblouis maintainers
+# to get some sensible initial values in place.
+
+# TODO: Please add a reference to official documentation about
+# the implemented braille code. Preferably submit the documents
+# to https://github.com/liblouis/braille-specs.
+
+include ar-ar-g1.utb
+include braille-patterns.cti
diff --git a/tables/as-in-g1.utb b/tables/as-in-g1.utb
new file mode 100644
index 0000000..42bd319
--- /dev/null
+++ b/tables/as-in-g1.utb
@@ -0,0 +1,27 @@
+# This table contains braille codes and rules for Assamese Grade 1 and includes English grade 1
+#
+# Copyright (C) 2014 National Institute for Visually Handicapped, 116, Rajpur Road, Dehradun, Uttrakhand, India
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# This table is built and maintained under an activity of Braille Council of India
+# Contributors: Dipendra Manocha, Sreeja, Dinesh Kaushal, Mesar Hameed
+# Last updated on May 5, 2014
+# To report any bugs or any suggestion, please write to d@saksham.org and sreeja.param@gmail.com
+
+include bengali.cti
+include en-in-g1.ctb
diff --git a/tables/as.tbl b/tables/as.tbl
new file mode 100644
index 0000000..16da521
--- /dev/null
+++ b/tables/as.tbl
@@ -0,0 +1,18 @@
+#-index-name: Assamese
+#-display-name: Assamese braille
+
+#+locale:as
+#+type:literary
+#+grade:1
+
+# TODO: Please correct the metadata above. It is not meant to be
+# accurate nor complete. It hasn't been verified by the table
+# author yet. It is merely an attempt by the liblouis maintainers
+# to get some sensible initial values in place.
+
+# TODO: Please add a reference to official documentation about
+# the implemented braille code. Preferably submit the documents
+# to https://github.com/liblouis/braille-specs.
+
+include as-in-g1.utb
+include braille-patterns.cti
diff --git a/tables/aw-in-g1.utb b/tables/aw-in-g1.utb
new file mode 100644
index 0000000..8a68e48
--- /dev/null
+++ b/tables/aw-in-g1.utb
@@ -0,0 +1,27 @@
+# This table contains braille codes and rules for Awadhi Grade 1 and includes English grade 1
+#
+# Copyright (C) 2014 National Institute for Visually Handicapped, 116, Rajpur Road, Dehradun, Uttrakhand, India
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# This table is built and maintained under an activity of Braille Council of India
+# Contributors: Dipendra Manocha, Sreeja, Dinesh Kaushal, Mesar Hamid
+# Last updated on May 5, 2014
+# To report any bugs or any suggestion, please write to d@saksham.org and sreeja.param@gmail.com
+
+include devanagari.cti
+include en-in-g1.ctb
diff --git a/tables/awa.tbl b/tables/awa.tbl
new file mode 100644
index 0000000..ed3bf26
--- /dev/null
+++ b/tables/awa.tbl
@@ -0,0 +1,18 @@
+#-index-name: Awadhi
+#-display-name: Awadhi braille
+
+#+locale:awa
+#+type:literary
+#+grade:1
+
+# TODO: Please correct the metadata above. It is not meant to be
+# accurate nor complete. It hasn't been verified by the table
+# author yet. It is merely an attempt by the liblouis maintainers
+# to get some sensible initial values in place.
+
+# TODO: Please add a reference to official documentation about
+# the implemented braille code. Preferably submit the documents
+# to https://github.com/liblouis/braille-specs.
+
+include aw-in-g1.utb
+include braille-patterns.cti
diff --git a/tables/be-in-g1.utb b/tables/be-in-g1.utb
new file mode 100644
index 0000000..e8a8cb2
--- /dev/null
+++ b/tables/be-in-g1.utb
@@ -0,0 +1,27 @@
+# This table contains braille codes and rules for Bengali Grade 1 and includes English grade 1
+#
+# Copyright (C) 2014 National Institute for Visually Handicapped, 116, Rajpur Road, Dehradun, Uttrakhand, India
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# This table is built and maintained under an activity of Braille Council of India
+# Contributors: Dipendra Manocha, Sreeja, Dinesh Kaushal, Mesar Hameed
+# Last updated on May 5, 2014
+# To report any bugs or any suggestion, please write to d@saksham.org and sreeja.param@gmail.com
+
+include bengali.cti
+include en-in-g1.ctb
diff --git a/tables/bengali.cti b/tables/bengali.cti
new file mode 100644
index 0000000..6e68d43
--- /dev/null
+++ b/tables/bengali.cti
@@ -0,0 +1,242 @@
+# This table contains braille codes and rules for Bengali script.
+#
+# Copyright (C) 2014 National Institute for Visually Handicapped, 116, Rajpur Road, Dehradun, Uttrakhand, India
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# This table is built and maintained under an activity of Braille Council of India
+# Contributors: Dipendra Manocha, Sreeja, Dinesh Kaushal, Mesar Hameed
+# Last updated on May 5, 2014
+# To report any bugs or any suggestion, please write to d@saksham.org and sreeja.param@gmail.com
+
+include braille-patterns.cti
+
+letter \x0981 3 # Bengali Sign Candrabindu
+letter \x0982 56 # Bengali Sign Anusvara
+letter \x0983 6 # Bengali Sign Visarga
+letter \x0985 1 # Bengali Letter A
+letter \x0986 345 # Bengali Letter AA
+letter \x0987 24 # Bengali Letter I
+letter \x0988 35 # Bengali Letter II
+letter \x0989 136 # Bengali Letter U
+letter \x098A 1256 # Bengali Letter UU
+letter \x098B 5-1235 # Bengali Letter Vocalic R
+letter \x098C 5-123 # Bengali Letter Vocalic L
+letter \x098F 15 # Bengali Letter E
+letter \x0990 34 # Bengali Letter AI
+letter \x0993 135 # Bengali Letter O
+letter \x0994 246 # Bengali Letter AU
+
+# Consonents
+
+letter \x0995 13 # Bengali Letter KA
+letter \x0996 46 # Bengali Letter KHA
+letter \x0997 1245 # Bengali Letter GA
+letter \x0998 126 # Bengali Letter GHA
+letter \x0999 346 # Bengali Letter NGA
+
+letter \x099A 14 # Bengali Letter CA
+letter \x099B 16 # Bengali Letter CHA
+letter \x099C 245 # Bengali Letter JA
+letter \x099D 356 # Bengali Letter JHA
+letter \x099E 25 # Bengali Letter NYA
+
+letter \x099F 23456 # Bengali Letter TTA
+letter \x09A0 2456 # Bengali Letter TTHA
+letter \x09A1 1246 # Bengali Letter DDA
+letter \x09A2 123456 # Bengali Letter DDHA
+letter \x09A3 3456 # Bengali Letter NNA
+
+letter \x09A4 2345 # Bengali Letter TA
+letter \x09A5 1456 # Bengali Letter THA
+letter \x09A6 145 # Bengali Letter DA
+letter \x09A7 2346 # Bengali Letter DHA
+letter \x09A8 1345 # Bengali Letter NA
+
+letter \x09AA 1234 # Bengali Letter PA
+letter \x09AB 235 # Bengali Letter PHA
+letter \x09AC 12 # Bengali Letter BA = Bengali va, wa
+letter \x09AD 45 # Bengali Letter BHA
+letter \x09AE 134 # Bengali Letter MA
+letter \x09AF 13456 # Bengali Letter YA
+letter \x09B0 1235 # Bengali Letter RA
+letter \x09B2 123 # Bengali Letter LA
+letter \x09B6 146 # Bengali Letter SHA
+letter \x09B7 12346 # Bengali Letter SSA
+letter \x09B8 234 # Bengali Letter SA
+letter \x09B9 125 # Bengali Letter HA
+
+letter \x09BD 2 # Bengali Sign Avagraha
+
+# vowel sign
+
+letter \x09BE 345 # Bengali vowel sign AA
+letter \x09BF 24 # Bengali vowel sign I (Stands To The Left Of The Consonant)
+letter \x09C0 35 # Bengali vowel sign II
+letter \x09C1 136 # Bengali vowel sign U
+letter \x09C2 1256 # Bengali vowel sign UU
+letter \x09C3 5-1235 # Bengali vowel sign VOCALIC R
+letter \x09C4 6-1235 # Bengali vowel sign VOCALIC RR
+letter \x09C7 15 # Bengali vowel sign E (stands to the left of the consonant)
+letter \x09C8 34 # Bengali vowel sign AI (stands to the left of the consonant)
+letter \x09CB 135 # Bengali vowel sign O = 09C7 and 09BE
+letter \x09CC 246 # Bengali vowel sign AU = 09C7 and 09D7
+
+letter \x09CD 4 # Bengali sign VIRAMA
+
+letter \x09CE 4-2345 # Bengali letter Khanda TA (a dead consonant form of ta, without implicit vowel, used in some sequences)
+letter \x09DC 12456 # Bengali letter RRA = 09A1 and 09BC
+letter \x09DD 5-12456 # BENGALI LETTER RHA = 09A2 AND 09BC
+letter \x09DF 26 # BENGALI LETTER YYA = 09AF AND 09BC
+
+letter \x09E0 6-1235 # BENGALI LETTER VOCALIC RR
+letter \x09E1 6-123 # BENGALI LETTER VOCALIC LL
+letter \x09E2 5-123 # BENGALI LETTER VOCALIC L
+letter \x09E3 6-123 # BENGALIC LETTER VOCALIC LL
+
+# Digits
+
+litdigit \x09E6 245 # BENGALI DIGIT ZERO
+litdigit \x09E7 1 # BENGALI DIGIT ONE
+litdigit \x09E8 12 # BENGALI DIGIT TWO
+litdigit \x09E9 14 # BENGALI DIGIT THREE
+litdigit \x09EA 145 # BENGALI DIGIT FOUR
+litdigit \x09EB 15 # BENGALI DIGIT FIVE
+litdigit \x09EC 124 # BENGALI DIGIT SIX
+litdigit \x09ED 1245 # BENGALI DIGIT SEVEN
+litdigit \x09EE 125 # BENGALI DIGIT EIGHT
+litdigit \x09EF 24 # BENGALI DIGIT NINE
+
+letter \x09F0 1235 # BENGALI LETTER RA WITH MIDDLE DIAGONAL (ASSAMESE)
+letter \x09F1 1236 # BENGALI LETTER RA WITH LOWER DIAGONAL = BENGALI LETTER VA WITH LOWER DIAGONAL (1.0) ASSAMESE
+
+replace \x200d
+
+# Half characters
+always \x0995\x09cD 4-13 # Bengali Letter KA
+always \x0996\x09cD 4-46 # Bengali Letter KHA
+always \x0997\x09cD 4-1245 # Bengali Letter GA
+always \x0998\x09cD 4-126 # Bengali Letter GHA
+always \x0999\x09cD 4-346 # Bengali Letter NGA
+
+always \x099A\x09cD 4-14 # Bengali Letter CA
+always \x099B\x09cD 4-16 # Bengali Letter CHA
+always \x099C\x09cD 4-245 # Bengali Letter JA
+always \x099D\x09cD 4-356 # Bengali Letter JHA
+always \x099E\x09cD 4-25 # Bengali Letter NYA
+
+always \x099F\x09cD 4-23456 # Bengali Letter TTA
+always \x09A0\x09cD 4-2456 # Bengali Letter TTHA
+always \x09A1\x09cD 4-1246 # Bengali Letter DDA
+always \x09A2\x09cD 4-123456 # Bengali Letter DDHA
+always \x09A3\x09cD 4-3456 # Bengali Letter NNA
+
+always \x09A4\x09cD 4-2345 # Bengali Letter TA
+always \x09A5\x09cD 4-1456 # Bengali Letter THA
+always \x09A6\x09cD 4-145 # Bengali Letter DA
+always \x09A7\x09cD 4-2346 # Bengali Letter DHA
+always \x09A8\x09cD 4-1345 # Bengali Letter NA
+
+always \x09AA\x09cD 4-1234 # Bengali Letter PA
+always \x09AB\x09cD 4-235 # Bengali Letter PHA
+always \x09AC\x09cD 4-12 # Bengali Letter BA = Bengali va, wa
+always \x09AD\x09cD 4-45 # Bengali Letter BHA
+always \x09AE\x09cD 4-134 # Bengali Letter MA
+
+always \x09AF\x09cD 4-13456 # Bengali Letter YA
+always \x09B0\x09cD 4-1235 # Bengali Letter RA
+always \x09B2\x09cD 4-123 # Bengali Letter LA
+always \x09B6\x09cD 4-146 # Bengali Letter SHA
+always \x09B7\x09cD 4-12346 # Bengali Letter SSA
+always \x09B8\x09cD 4-234 # Bengali Letter SA
+always \x09B9\x09cD 4-125 # Bengali Letter HA
+
+
+always \x09C4\x09cD 4-6-1235 # Bengali vowel sign VOCALIC RR
+always \x09CE\x09cD 4-4-2345 # Bengali letter Khanda TA (a dead consonant form of ta, without implicit vowel, used in some sequences)
+always \x09DC\x09cD 4-12456 # Bengali letter RRA = 09A1 and 09BC
+always \x09DF\x09cD 4-26 # BENGALI LETTER YYA = 09AF AND 09BC
+always \x09E0\x09cD 4-6-1235 # BENGALI LETTER VOCALIC RR
+always \x09E1\x09cD 4-6-123 # BENGALI LETTER VOCALIC LL
+always \x09E2\x09cD 4-5-123 # BENGALI LETTER VOCALIC L
+always \x09E3\x09cD 4-6-123 # BENGALIC LETTER VOCALIC LL
+always \x09F0\x09cD 4-1235 # BENGALI LETTER RA WITH MIDDLE DIAGONAL (ASSAMESE)
+always \x09F1\x09cD 4-1236 # BENGALI LETTER RA WITH LOWER DIAGONAL = BENGALI LETTER VA WITH LOWER DIAGONAL (1.0) ASSAMESE
+
+ # ksha and gya
+
+
+
+ always \x0995\x09CD\x09B7\x09CD 4-12345 #"ksha"
+ always \x099C\x09CD\x099E 156 #"gyan"
+ always \x0995\x09CD\x09B7 12345 #"ksha"
+
+ # consonent followed by vowel but not matra
+
+ class BengaliVowel \x0985\x0986\x0987\x0988\x0989\x0985\x098A\x098B\x098C\x098F\x0990\x0993\x0994
+ class HALANT \x09CD
+
+
+
+
+before BengaliVowel always \x0995 13-1 # Bengali ka
+before BengaliVowel always \x0996 46-1 # Bengali kha
+before BengaliVowel always \x0997 1245-1 # Bengali ga
+before BengaliVowel always \x0998 126-1 # Bengali gha
+
+#before HALANT always \x0995 4-13 # Bengali ka
+
+before BengaliVowel always \x099A 14-1 # Bengali ca
+before BengaliVowel always \x099B 16-1 # Bengali cha
+before BengaliVowel always \x099C 245-1 # Bengali ja
+before BengaliVowel always \x099D 356-1 # Bengali jha
+
+before BengaliVowel always \x099F 23456-1 # Bengali ta
+before BengaliVowel always \x09A0 2456-1 # Bengali tha
+before BengaliVowel always \x09A1 1246-1 # Bengali da
+before BengaliVowel always \x09A2 123456-1 # Bengali dha
+before BengaliVowel always \x09A3 3456-1 #Bengali nna
+
+before BengaliVowel always \x09A4 2345-1 # Bengali ta
+before BengaliVowel always \x09A5 1456-1 # Bengali tha
+before BengaliVowel always \x09A6 145-1 # Bengali da
+before BengaliVowel always \x09A7 2346-1 # Bengali dha
+before BengaliVowel always \x09A8 1345-1 #Bengali na
+
+before BengaliVowel always \x09AA 1234-1 # Bengali pa
+before BengaliVowel always \x09AB 235-1 # Bengali pha
+before BengaliVowel always \x09AC 12-1 # Bengali ba
+before BengaliVowel always \x09AD 45-1 # Bengali bha
+before BengaliVowel always \x09AE 134-1 #Bengali ma
+
+before BengaliVowel always \x09AF 13456-1 # Bengali yaa
+before BengaliVowel always \x09B0 1235-1 # Bengali ra
+before BengaliVowel always \x09B2 123-1 # Bengali la
+before BengaliVowel always \x09B6 146-1 #Bengali sha
+before BengaliVowel always \x09B7 12346-1 #Bengali ssha
+before BengaliVowel always \x09B8 234-1 #Bengali sa
+before BengaliVowel always \x09B9 125-1 #Bengali ha
+
+ before BengaliVowel always \x09C4 6-1235-1 # Bengali vowel sign VOCALIC RR
+ before BengaliVowel always \x09CE 2345-1 # Bengali letter Khanda TA (a dead consonant form of ta, without implicit vowel, used in some sequences)
+ before BengaliVowel always \x09DC 12456-1 # Bengali letter RRA = 09A1 and 09BC
+ before BengaliVowel always \x09DF 26-1 # BENGALI LETTER YYA = 09AF AND 09BC
+ before BengaliVowel always \x09E0 6-1235-1 # BENGALI LETTER VOCALIC RR
+ before BengaliVowel always \x09E1 6-123-1 # BENGALI LETTER VOCALIC LL
+ before BengaliVowel always \x09E3 6-123-1 # BENGALIC LETTER VOCALIC LL
+ before BengaliVowel always \x09F0 1235-1 # BENGALI LETTER RA WITH MIDDLE DIAGONAL (ASSAMESE)
+ before BengaliVowel always \x09F1 1236-1 # BENGALI LETTER RA WITH LOWER DIAGONAL = BENGALI LETTER VA WITH LOWER DIAGONAL (1.0) ASSAMESE
diff --git a/tables/bg.ctb b/tables/bg.ctb
new file mode 100644
index 0000000..9532424
--- /dev/null
+++ b/tables/bg.ctb
@@ -0,0 +1,189 @@
+#
+# Copyright (C) 1995-2008 by The BRLTTY Developers.
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+# BRLTTY Text Table - Bulgarian
+#
+# Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# This table is based on the Unesco report on the progress of unification of
+# braille writing « L'ÉCRITURE BRAILLE DANS LE MONDE », by Sir Clutha
+# MACKENZIE: http://unesdoc.unesco.org/images/0013/001352/135251fo.pdf
+# The document is dated 1954, so this table may be quite outdated.
+# Edited on Mar 10 2013 by Rumiana Kamenska <rkamenska@gmail.com>
+# to meet modern standards.
+# Added latinn letters.
+#
+# generated by ttbtest
+
+#Punctuation and symbols
+space \s 0 SPACE
+space \t 9 tab
+space \s 0 blank
+space \x00a0 a unbreakable space
+sign \x000a 78 newline
+space \x000d 0 carriage return
+punctuation ! 235 EXCLAMATION MARK
+punctuation " 236 QUOTATION MARK
+punctuation ' 3 APOSTROPHE
+punctuation ( 126 LEFT PARENTHESIS
+punctuation ) 345 RIGHT PARENTHESIS
+punctuation , 2 COMMA
+punctuation - 36 HYPHEN-MINUS
+punctuation . 256 FULL STOP
+punctuation : 25 COLON
+punctuation ; 23 SEMICOLON
+punctuation ? 26 QUESTION MARK
+punctuation \x00a0 0 NO-BREAK SPACE
+sign _ 456
+math < 246
+math = 2345
+math > 135
+sign % 356
+math + 235
+math ~ 346
+sign ` 4
+sign & 12346
+sign $ 1246
+punctuation { 246
+punctuation [ 1235678
+punctuation } 135
+punctuation ] 2345678
+sign ^ 34
+sign @ 2346
+sign # 346
+sign \\ 16
+sign | 1456
+math / 34
+sign * 35
+
+# Digits
+digit 0 3568 DIGIT ZERO
+digit 1 28 DIGIT ONE
+digit 2 238 DIGIT TWO
+digit 3 258 DIGIT THREE
+digit 4 2568 DIGIT FOUR
+digit 5 268 DIGIT FIVE
+digit 6 2358 DIGIT SIX
+digit 7 23568 DIGIT SEVEN
+digit 8 2368 DIGIT EIGHT
+digit 9 358 DIGIT NINE
+
+#Cyrillic letters
+uppercase \x0401 167 CYRILLIC CAPITAL LETTER IO
+uppercase \x0410 17 CYRILLIC CAPITAL LETTER A
+uppercase \x0411 127 CYRILLIC CAPITAL LETTER BE
+uppercase \x0412 24567 CYRILLIC CAPITAL LETTER VE
+uppercase \x0413 12457 CYRILLIC CAPITAL LETTER GHE
+uppercase \x0414 1457 CYRILLIC CAPITAL LETTER DE
+uppercase \x0415 157 CYRILLIC CAPITAL LETTER IE
+uppercase \x0416 2457 CYRILLIC CAPITAL LETTER ZHE
+uppercase \x0417 13567 CYRILLIC CAPITAL LETTER ZE
+uppercase \x0418 247 CYRILLIC CAPITAL LETTER I
+uppercase \x0419 134567 CYRILLIC CAPITAL LETTER SHORT I
+uppercase \x041a 137 CYRILLIC CAPITAL LETTER KA
+uppercase \x041b 1237 CYRILLIC CAPITAL LETTER EL
+uppercase \x041c 1347 CYRILLIC CAPITAL LETTER EM
+uppercase \x041d 13457 CYRILLIC CAPITAL LETTER EN
+uppercase \x041e 1357 CYRILLIC CAPITAL LETTER O
+uppercase \x041f 12347 CYRILLIC CAPITAL LETTER PE
+uppercase \x0420 12357 CYRILLIC CAPITAL LETTER ER
+uppercase \x0421 2347 CYRILLIC CAPITAL LETTER ES
+uppercase \x0422 23457 CYRILLIC CAPITAL LETTER TE
+uppercase \x0423 1367 CYRILLIC CAPITAL LETTER U
+uppercase \x0424 1247 CYRILLIC CAPITAL LETTER EF
+uppercase \x0425 1257 CYRILLIC CAPITAL LETTER HA
+uppercase \x0426 147 CYRILLIC CAPITAL LETTER TSE
+uppercase \x0427 123457 CYRILLIC CAPITAL LETTER CHE
+uppercase \x0428 1567 CYRILLIC CAPITAL LETTER SHA
+uppercase \x0429 13467 CYRILLIC CAPITAL LETTER SHCHA
+uppercase \x042a 123567 CYRILLIC CAPITAL LETTER HARD SIGN
+uppercase \x042b 23467 CYRILLIC CAPITAL LETTER YERU
+uppercase \x042c 234567 CYRILLIC CAPITAL LETTER SOFT SIGN
+uppercase \x042d 2467 CYRILLIC CAPITAL LETTER E
+uppercase \x042e 12567 CYRILLIC CAPITAL LETTER YU
+uppercase \x042f 12467 CYRILLIC CAPITAL LETTER YA
+lowercase \x0430 1 CYRILLIC SMALL LETTER A
+lowercase \x0431 12 CYRILLIC SMALL LETTER BE
+lowercase \x0432 2456 CYRILLIC SMALL LETTER VE
+lowercase \x0433 1245 CYRILLIC SMALL LETTER GHE
+lowercase \x0434 145 CYRILLIC SMALL LETTER DE
+lowercase \x0435 15 CYRILLIC SMALL LETTER IE
+lowercase \x0436 245 CYRILLIC SMALL LETTER ZHE
+lowercase \x0437 1356 CYRILLIC SMALL LETTER ZE
+lowercase \x0438 24 CYRILLIC SMALL LETTER I
+lowercase \x0439 13456 CYRILLIC SMALL LETTER SHORT I
+lowercase \x043a 13 CYRILLIC SMALL LETTER KA
+lowercase \x043b 123 CYRILLIC SMALL LETTER EL
+lowercase \x043c 134 CYRILLIC SMALL LETTER EM
+lowercase \x043d 1345 CYRILLIC SMALL LETTER EN
+lowercase \x043e 135 CYRILLIC SMALL LETTER O
+lowercase \x043f 1234 CYRILLIC SMALL LETTER PE
+lowercase \x0440 1235 CYRILLIC SMALL LETTER ER
+lowercase \x0441 234 CYRILLIC SMALL LETTER ES
+lowercase \x0442 2345 CYRILLIC SMALL LETTER TE
+lowercase \x0443 136 CYRILLIC SMALL LETTER U
+lowercase \x0444 124 CYRILLIC SMALL LETTER EF
+lowercase \x0445 125 CYRILLIC SMALL LETTER HA
+lowercase \x0446 14 CYRILLIC SMALL LETTER TSE
+lowercase \x0447 12345 CYRILLIC SMALL LETTER CHE
+lowercase \x0448 156 CYRILLIC SMALL LETTER SHA
+lowercase \x0449 1346 CYRILLIC SMALL LETTER SHCHA
+lowercase \x044a 12356 CYRILLIC SMALL LETTER HARD SIGN
+lowercase \x044b 2346 CYRILLIC SMALL LETTER YERU
+lowercase \x044c 23456 CYRILLIC SMALL LETTER SOFT SIGN
+lowercase \x044d 246 CYRILLIC SMALL LETTER E
+lowercase \x044e 1256 CYRILLIC SMALL LETTER YU
+lowercase \x044f 1246 CYRILLIC SMALL LETTER YA
+lowercase \x0451 16 CYRILLIC SMALL LETTER IO
+uppercase \x0462 3457 CYRILLIC CAPITAL LETTER YAT
+lowercase \x0463 345 CYRILLIC SMALL LETTER YAT
+uppercase \x046a 2467 CYRILLIC CAPITAL LETTER BIG YUS
+lowercase \x046b 246 CYRILLIC SMALL LETTER BIG YUS
+
+# Latin letters
+uplow Aa 178,18
+uplow Bb 1278,128
+uplow Cc 1478,148
+uplow Dd 14578,1458
+uplow Ee 1578,158
+uplow Ff 12478,1248
+uplow Gg 124578,12458
+uplow Hh 12578,1258
+uplow Ii 2478,248
+uplow Jj 24578,2458
+uplow Kk 1378,138
+uplow Ll 12378,1238
+uplow Mm 13478,1348
+uplow Nn 134578,13458
+uplow Oo 13578,1358
+uplow Pp 123478,12348
+uplow Qq 1234578,123458
+uplow Rr 123578,12358
+uplow Ss 23478,2348
+uplow Tt 234578,23458
+uplow Uu 13678,1368
+uplow Vv 123678,12368
+uplow Ww 245678,24568
+uplow Xx 134678,13468
+uplow Yy 1345678,134568
+uplow Zz 135678,13568
+
+# Miscellaneous
+noback sign \x25CF 35 BLACK CIRCLE
diff --git a/tables/bg.tbl b/tables/bg.tbl
new file mode 100644
index 0000000..6ee69b8
--- /dev/null
+++ b/tables/bg.tbl
@@ -0,0 +1,18 @@
+#-index-name: Bulgarian, computer
+#-display-name: Bulgarian computer braille
+
+#+locale:bg
+#+type:computer
+#+dots:8
+
+# TODO: Please correct the metadata above. It is not meant to be
+# accurate nor complete. It hasn't been verified by the table
+# author yet. It is merely an attempt by the liblouis maintainers
+# to get some sensible initial values in place.
+
+# TODO: Please add a reference to official documentation about
+# the implemented braille code. Preferably submit the documents
+# to https://github.com/liblouis/braille-specs.
+
+include bg.ctb
+include braille-patterns.cti
diff --git a/tables/bh.ctb b/tables/bh.ctb
new file mode 100644
index 0000000..ab622ba
--- /dev/null
+++ b/tables/bh.ctb
@@ -0,0 +1,24 @@
+# Copyright (C) 2010 Leon Ungier <Leon.Ungier@ViewPlus.com>,
+# Copyright (C) 2010 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# Table for Bihari
+space \x00a0 a
+include spaces.uti
+include devanagari.cti
+include text_nabcc.dis
diff --git a/tables/bh.tbl b/tables/bh.tbl
new file mode 100644
index 0000000..a84361f
--- /dev/null
+++ b/tables/bh.tbl
@@ -0,0 +1,17 @@
+#-index-name: Bihari
+#-display-name: Bihari braille
+
+#+locale:bh
+#+type:literary
+
+# TODO: Please correct the metadata above. It is not meant to be
+# accurate nor complete. It hasn't been verified by the table
+# author yet. It is merely an attempt by the liblouis maintainers
+# to get some sensible initial values in place.
+
+# TODO: Please add a reference to official documentation about
+# the implemented braille code. Preferably submit the documents
+# to https://github.com/liblouis/braille-specs.
+
+include bh.ctb
+include braille-patterns.cti
diff --git a/tables/bn.tbl b/tables/bn.tbl
new file mode 100644
index 0000000..e942414
--- /dev/null
+++ b/tables/bn.tbl
@@ -0,0 +1,18 @@
+#-index-name: Bengali
+#-display-name: Bengali braille
+
+#+locale:bn
+#+type:literary
+#+grade:1
+
+# TODO: Please correct the metadata above. It is not meant to be
+# accurate nor complete. It hasn't been verified by the table
+# author yet. It is merely an attempt by the liblouis maintainers
+# to get some sensible initial values in place.
+
+# TODO: Please add a reference to official documentation about
+# the implemented braille code. Preferably submit the documents
+# to https://github.com/liblouis/braille-specs.
+
+include be-in-g1.utb
+include braille-patterns.cti
diff --git a/tables/bo.ctb b/tables/bo.ctb
new file mode 100644
index 0000000..0e6758c
--- /dev/null
+++ b/tables/bo.ctb
@@ -0,0 +1,184 @@
+#
+# Copyright (C) 1995-2009 by The BRLTTY Developers.
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# BRLTTY Text Table - Tibetan
+#
+# Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# From "Braille without borders"
+
+# generated by ttbtest
+space \s 0 # SPACE
+punctuation ! 2358 # EXCLAMATION MARK
+punctuation " 23568 # QUOTATION MARK
+punctuation # 34568 # NUMBER SIGN
+punctuation $ 12468 # DOLLAR SIGN
+punctuation % 1468 # PERCENT SIGN
+punctuation & 23468 # AMPERSAND
+punctuation ' 3 # APOSTROPHE
+punctuation ( 2368 # LEFT PARENTHESIS
+punctuation ) 3568 # RIGHT PARENTHESIS
+punctuation * 358 # ASTERISK
+punctuation + 3468 # PLUS SIGN
+punctuation , 28 # COMMA
+punctuation - 36 # HYPHEN-MINUS
+punctuation . 2568 # FULL STOP
+punctuation / 348 # SOLIDUS
+include loweredDigits6Dots.uti
+punctuation : 258 # COLON
+punctuation ; 238 # SEMICOLON
+punctuation < 1268 # LESS-THAN SIGN
+punctuation = 1234568 # EQUALS SIGN
+punctuation > 3458 # GREATER-THAN SIGN
+punctuation ? 268 # QUESTION MARK
+punctuation @ 47 # COMMERCIAL AT
+uppercase A 178 # LATIN CAPITAL LETTER A
+uppercase B 1278 # LATIN CAPITAL LETTER B
+uppercase C 1478 # LATIN CAPITAL LETTER C
+uppercase D 14578 # LATIN CAPITAL LETTER D
+uppercase E 1578 # LATIN CAPITAL LETTER E
+uppercase F 12478 # LATIN CAPITAL LETTER F
+uppercase G 124578 # LATIN CAPITAL LETTER G
+uppercase H 12578 # LATIN CAPITAL LETTER H
+uppercase I 2478 # LATIN CAPITAL LETTER I
+uppercase J 24578 # LATIN CAPITAL LETTER J
+uppercase K 1378 # LATIN CAPITAL LETTER K
+uppercase L 12378 # LATIN CAPITAL LETTER L
+uppercase M 13478 # LATIN CAPITAL LETTER M
+uppercase N 134578 # LATIN CAPITAL LETTER N
+uppercase O 13578 # LATIN CAPITAL LETTER O
+uppercase P 123478 # LATIN CAPITAL LETTER P
+uppercase Q 1234578 # LATIN CAPITAL LETTER Q
+uppercase R 123578 # LATIN CAPITAL LETTER R
+uppercase S 23478 # LATIN CAPITAL LETTER S
+uppercase T 234578 # LATIN CAPITAL LETTER T
+uppercase U 13678 # LATIN CAPITAL LETTER U
+uppercase V 123678 # LATIN CAPITAL LETTER V
+uppercase W 245678 # LATIN CAPITAL LETTER W
+uppercase X 134678 # LATIN CAPITAL LETTER X
+uppercase Y 1345678 # LATIN CAPITAL LETTER Y
+uppercase Z 135678 # LATIN CAPITAL LETTER Z
+punctuation [ 123568 # LEFT SQUARE BRACKET
+punctuation \\ 168 # REVERSE SOLIDUS
+punctuation ] 234568 # RIGHT SQUARE BRACKET
+punctuation ^ 457 # CIRCUMFLEX ACCENT
+punctuation _ 456 # LOW LINE
+punctuation ` 4 # GRAVE ACCENT
+lowercase a 18 # LATIN SMALL LETTER A
+lowercase b 128 # LATIN SMALL LETTER B
+lowercase c 148 # LATIN SMALL LETTER C
+lowercase d 1458 # LATIN SMALL LETTER D
+lowercase e 158 # LATIN SMALL LETTER E
+lowercase f 1248 # LATIN SMALL LETTER F
+lowercase g 12458 # LATIN SMALL LETTER G
+lowercase h 1258 # LATIN SMALL LETTER H
+lowercase i 248 # LATIN SMALL LETTER I
+lowercase j 2458 # LATIN SMALL LETTER J
+lowercase k 138 # LATIN SMALL LETTER K
+lowercase l 1238 # LATIN SMALL LETTER L
+lowercase m 1348 # LATIN SMALL LETTER M
+lowercase n 13458 # LATIN SMALL LETTER N
+lowercase o 1358 # LATIN SMALL LETTER O
+lowercase p 12348 # LATIN SMALL LETTER P
+lowercase q 123458 # LATIN SMALL LETTER Q
+lowercase r 12358 # LATIN SMALL LETTER R
+lowercase s 2348 # LATIN SMALL LETTER S
+lowercase t 23458 # LATIN SMALL LETTER T
+lowercase u 1368 # LATIN SMALL LETTER U
+lowercase v 12368 # LATIN SMALL LETTER V
+lowercase w 24568 # LATIN SMALL LETTER W
+lowercase x 13468 # LATIN SMALL LETTER X
+lowercase y 134568 # LATIN SMALL LETTER Y
+lowercase z 13568 # LATIN SMALL LETTER Z
+punctuation { 23678 # LEFT CURLY BRACKET
+punctuation | 12568 # VERTICAL LINE
+punctuation } 35678 # RIGHT CURLY BRACKET
+punctuation ~ 45 # TILDE
+punctuation \x00a0 0 # NO-BREAK SPACE
+letter \x0f40 13 # TIBETAN LETTER KA
+letter \x0f41 14 # TIBETAN LETTER KHA
+letter \x0f42 1245 # TIBETAN LETTER GA
+letter \x0f44 2356 # TIBETAN LETTER NGA
+letter \x0f45 1456 # TIBETAN LETTER CA
+letter \x0f46 13456 # TIBETAN LETTER CHA
+letter \x0f47 12345 # TIBETAN LETTER JA
+letter \x0f49 345 # TIBETAN LETTER NYA
+letter \x0f4f 2345 # TIBETAN LETTER TA
+letter \x0f50 23456 # TIBETAN LETTER THA
+letter \x0f51 145 # TIBETAN LETTER DA
+letter \x0f53 1345 # TIBETAN LETTER NA
+letter \x0f54 1234 # TIBETAN LETTER PA
+letter \x0f55 12346 # TIBETAN LETTER PHA
+letter \x0f56 12 # TIBETAN LETTER BA
+letter \x0f58 134 # TIBETAN LETTER MA
+letter \x0f59 1346 # TIBETAN LETTER TSA
+letter \x0f5a 1356 # TIBETAN LETTER TSHA
+letter \x0f5b 123456 # TIBETAN LETTER DZA
+letter \x0f5d 2456 # TIBETAN LETTER WA
+letter \x0f5e 146 # TIBETAN LETTER ZHA
+letter \x0f5f 234 # TIBETAN LETTER ZA
+letter \x0f60 1246 # TIBETAN LETTER -A
+letter \x0f61 245 # TIBETAN LETTER YA
+letter \x0f62 1235 # TIBETAN LETTER RA
+letter \x0f63 123 # TIBETAN LETTER LA
+letter \x0f64 156 # TIBETAN LETTER SHA
+letter \x0f66 2346 # TIBETAN LETTER SA
+letter \x0f67 125 # TIBETAN LETTER HA
+letter \x0f68 1 # TIBETAN LETTER A
+letter \x0f90 13 # TIBETAN SUBJOINED LETTER KA
+letter \x0f91 14 # TIBETAN SUBJOINED LETTER KHA
+letter \x0f92 1245 # TIBETAN SUBJOINED LETTER GA
+letter \x0f94 2356 # TIBETAN SUBJOINED LETTER NGA
+letter \x0f95 1456 # TIBETAN SUBJOINED LETTER CA
+letter \x0f96 13456 # TIBETAN SUBJOINED LETTER CHA
+letter \x0f97 12345 # TIBETAN SUBJOINED LETTER JA
+letter \x0f99 345 # TIBETAN SUBJOINED LETTER NYA
+letter \x0f9f 2345 # TIBETAN SUBJOINED LETTER TA
+letter \x0fa0 23456 # TIBETAN SUBJOINED LETTER THA
+letter \x0fa1 145 # TIBETAN SUBJOINED LETTER DA
+letter \x0fa3 1345 # TIBETAN SUBJOINED LETTER NA
+letter \x0fa4 1234 # TIBETAN SUBJOINED LETTER PA
+letter \x0fa5 12346 # TIBETAN SUBJOINED LETTER PHA
+letter \x0fa6 12 # TIBETAN SUBJOINED LETTER BA
+letter \x0fa8 134 # TIBETAN SUBJOINED LETTER MA
+letter \x0fa9 1346 # TIBETAN SUBJOINED LETTER TSA
+letter \x0faa 1356 # TIBETAN SUBJOINED LETTER TSHA
+letter \x0fab 123456 # TIBETAN SUBJOINED LETTER DZA
+letter \x0fad 2456 # TIBETAN SUBJOINED LETTER WA
+letter \x0fae 146 # TIBETAN SUBJOINED LETTER ZHA
+letter \x0faf 234 # TIBETAN SUBJOINED LETTER ZA
+letter \x0fb0 1246 # TIBETAN SUBJOINED LETTER -A
+letter \x0fb1 245 # TIBETAN SUBJOINED LETTER YA
+letter \x0fb2 1235 # TIBETAN SUBJOINED LETTER RA
+letter \x0fb3 123 # TIBETAN SUBJOINED LETTER LA
+letter \x0fb4 156 # TIBETAN SUBJOINED LETTER SHA
+letter \x0fb6 2346 # TIBETAN SUBJOINED LETTER SA
+letter \x0fb7 125 # TIBETAN SUBJOINED LETTER HA
+letter \x0fb8 1 # TIBETAN SUBJOINED LETTER A
+space \x2002 0 # EN SPACE
+space \x2003 0 # EM SPACE
+space \x2004 0 # THREE-PER-EM SPACE
+space \x2005 0 # FOUR-PER-EM SPACE
+space \x2006 0 # SIX-PER-EM SPACE
+punctuation \x2007 0 # FIGURE SPACE
+space \x2008 0 # PUNCTUATION SPACE
+space \x2009 0 # THIN SPACE
+space \x200a 0 # HAIR SPACE
+punctuation \x202f 0 # NARROW NO-BREAK SPACE
+space \x205f 0 # MEDIUM MATHEMATICAL SPACE
diff --git a/tables/bo.tbl b/tables/bo.tbl
new file mode 100644
index 0000000..22d7551
--- /dev/null
+++ b/tables/bo.tbl
@@ -0,0 +1,18 @@
+#-index-name: Tibetan, computer
+#-display-name: Tibetan computer braille
+
+#+locale:bo
+#+type:computer
+#+dots:8
+
+# TODO: Please correct the metadata above. It is not meant to be
+# accurate nor complete. It hasn't been verified by the table
+# author yet. It is merely an attempt by the liblouis maintainers
+# to get some sensible initial values in place.
+
+# TODO: Please add a reference to official documentation about
+# the implemented braille code. Preferably submit the documents
+# to https://github.com/liblouis/braille-specs.
+
+include bo.ctb
+include braille-patterns.cti
diff --git a/tables/boxes.ctb b/tables/boxes.ctb
new file mode 100644
index 0000000..b4ee015
--- /dev/null
+++ b/tables/boxes.ctb
@@ -0,0 +1,162 @@
+#
+# Copyright (C) 1995-2008 by The BRLTTY Developers.
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# This BRLTTY text subtable implements a portable representation of the box
+# drawing characters.aNo distinction is made between the three types of boxes:
+# light, heavy, and double. Characters with no vertical component (horizontal
+# edges) are represented by the four middle dots [2356]. Those with a vertical
+# component above the center (e.g. bottom corners) add the two top dots [14],
+# and those with a vertical component below the center (e.g. top corners) add
+# the two bottom dots [78]. This means, for example, that side edges and the
+# cross are represented by a full cell [12345678].
+
+# For diagonals within boxes, the top-left and bottom-right dots [18] are used
+# to represent the line which descends toward the right, and the top-right and
+# bottom-left dots [47] are used to represent the line which ascends toward the
+# right. The X is represented by all four of these dots [1478].
+
+# generated by ttbtest
+punctuation \x2500 2356 BOX DRAWINGS LIGHT HORIZONTAL
+punctuation \x2501 2356 BOX DRAWINGS HEAVY HORIZONTAL
+punctuation \x2502 12345678 BOX DRAWINGS LIGHT VERTICAL
+punctuation \x2503 12345678 BOX DRAWINGS HEAVY VERTICAL
+punctuation \x2504 2356 BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL
+punctuation \x2505 2356 BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL
+punctuation \x2506 12345678 BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL
+punctuation \x2507 12345678 BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL
+punctuation \x2508 2356 BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL
+punctuation \x2509 2356 BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL
+punctuation \x250a 12345678 BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL
+punctuation \x250b 12345678 BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL
+punctuation \x250c 235678 BOX DRAWINGS LIGHT DOWN AND RIGHT
+punctuation \x250d 235678 BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY
+punctuation \x250e 235678 BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT
+punctuation \x250f 235678 BOX DRAWINGS HEAVY DOWN AND RIGHT
+punctuation \x2510 235678 BOX DRAWINGS LIGHT DOWN AND LEFT
+punctuation \x2511 235678 BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY
+punctuation \x2512 235678 BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT
+punctuation \x2513 235678 BOX DRAWINGS HEAVY DOWN AND LEFT
+punctuation \x2514 123456 BOX DRAWINGS LIGHT UP AND RIGHT
+punctuation \x2515 123456 BOX DRAWINGS UP LIGHT AND RIGHT HEAVY
+punctuation \x2516 123456 BOX DRAWINGS UP HEAVY AND RIGHT LIGHT
+punctuation \x2517 123456 BOX DRAWINGS HEAVY UP AND RIGHT
+punctuation \x2518 123456 BOX DRAWINGS LIGHT UP AND LEFT
+punctuation \x2519 123456 BOX DRAWINGS UP LIGHT AND LEFT HEAVY
+punctuation \x251a 123456 BOX DRAWINGS UP HEAVY AND LEFT LIGHT
+punctuation \x251b 123456 BOX DRAWINGS HEAVY UP AND LEFT
+punctuation \x251c 12345678 BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+punctuation \x251d 12345678 BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
+punctuation \x251e 12345678 BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT
+punctuation \x251f 12345678 BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT
+punctuation \x2520 12345678 BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
+punctuation \x2521 12345678 BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY
+punctuation \x2522 12345678 BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY
+punctuation \x2523 12345678 BOX DRAWINGS HEAVY VERTICAL AND RIGHT
+punctuation \x2524 12345678 BOX DRAWINGS LIGHT VERTICAL AND LEFT
+punctuation \x2525 12345678 BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
+punctuation \x2526 12345678 BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT
+punctuation \x2527 12345678 BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT
+punctuation \x2528 12345678 BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
+punctuation \x2529 12345678 BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY
+punctuation \x252a 12345678 BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY
+punctuation \x252b 12345678 BOX DRAWINGS HEAVY VERTICAL AND LEFT
+punctuation \x252c 235678 BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+punctuation \x252d 235678 BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT
+punctuation \x252e 235678 BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT
+punctuation \x252f 235678 BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
+punctuation \x2530 235678 BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
+punctuation \x2531 235678 BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY
+punctuation \x2532 235678 BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY
+punctuation \x2533 235678 BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
+punctuation \x2534 123456 BOX DRAWINGS LIGHT UP AND HORIZONTAL
+punctuation \x2535 123456 BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT
+punctuation \x2536 123456 BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT
+punctuation \x2537 123456 BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
+punctuation \x2538 123456 BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
+punctuation \x2539 123456 BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY
+punctuation \x253a 123456 BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY
+punctuation \x253b 123456 BOX DRAWINGS HEAVY UP AND HORIZONTAL
+punctuation \x253c 12345678 BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+punctuation \x253d 12345678 BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT
+punctuation \x253e 12345678 BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT
+punctuation \x253f 12345678 BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
+punctuation \x2540 12345678 BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT
+punctuation \x2541 12345678 BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT
+punctuation \x2542 12345678 BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
+punctuation \x2543 12345678 BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT
+punctuation \x2544 12345678 BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT
+punctuation \x2545 12345678 BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT
+punctuation \x2546 12345678 BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT
+punctuation \x2547 12345678 BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY
+punctuation \x2548 12345678 BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY
+punctuation \x2549 12345678 BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY
+punctuation \x254a 12345678 BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY
+punctuation \x254b 12345678 BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+punctuation \x254c 2356 BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL
+punctuation \x254d 2356 BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL
+punctuation \x254e 12345678 BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL
+punctuation \x254f 12345678 BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL
+punctuation \x2550 2356 BOX DRAWINGS DOUBLE HORIZONTAL
+punctuation \x2551 12345678 BOX DRAWINGS DOUBLE VERTICAL
+punctuation \x2552 235678 BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+punctuation \x2553 235678 BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+punctuation \x2554 235678 BOX DRAWINGS DOUBLE DOWN AND RIGHT
+punctuation \x2555 235678 BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+punctuation \x2556 235678 BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+punctuation \x2557 235678 BOX DRAWINGS DOUBLE DOWN AND LEFT
+punctuation \x2558 123456 BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+punctuation \x2559 123456 BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+punctuation \x255a 123456 BOX DRAWINGS DOUBLE UP AND RIGHT
+punctuation \x255b 123456 BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+punctuation \x255c 123456 BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+punctuation \x255d 123456 BOX DRAWINGS DOUBLE UP AND LEFT
+punctuation \x255e 12345678 BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+punctuation \x255f 12345678 BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+punctuation \x2560 12345678 BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+punctuation \x2561 12345678 BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+punctuation \x2562 12345678 BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+punctuation \x2563 12345678 BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+punctuation \x2564 235678 BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+punctuation \x2565 235678 BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+punctuation \x2566 235678 BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+punctuation \x2567 123456 BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+punctuation \x2568 123456 BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+punctuation \x2569 123456 BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+punctuation \x256a 12345678 BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+punctuation \x256b 12345678 BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+punctuation \x256c 12345678 BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+punctuation \x256d 235678 BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+punctuation \x256e 235678 BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+punctuation \x256f 123456 BOX DRAWINGS LIGHT ARC UP AND LEFT
+punctuation \x2570 123456 BOX DRAWINGS LIGHT ARC UP AND RIGHT
+punctuation \x2571 47 BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+punctuation \x2572 18 BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+punctuation \x2573 1478 BOX DRAWINGS LIGHT DIAGONAL CROSS
+punctuation \x2574 2356 BOX DRAWINGS LIGHT LEFT
+punctuation \x2575 123456 BOX DRAWINGS LIGHT UP
+punctuation \x2576 2356 BOX DRAWINGS LIGHT RIGHT
+punctuation \x2577 235678 BOX DRAWINGS LIGHT DOWN
+punctuation \x2578 2356 BOX DRAWINGS HEAVY LEFT
+punctuation \x2579 123456 BOX DRAWINGS HEAVY UP
+punctuation \x257a 2356 BOX DRAWINGS HEAVY RIGHT
+punctuation \x257b 235678 BOX DRAWINGS HEAVY DOWN
+punctuation \x257c 2356 BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT
+punctuation \x257d 12345678 BOX DRAWINGS LIGHT UP AND HEAVY DOWN
+punctuation \x257e 2356 BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT
+punctuation \x257f 12345678 BOX DRAWINGS HEAVY UP AND LIGHT DOWN
diff --git a/tables/br-in-g1.utb b/tables/br-in-g1.utb
new file mode 100644
index 0000000..2259fdb
--- /dev/null
+++ b/tables/br-in-g1.utb
@@ -0,0 +1,27 @@
+# This table contains braille codes and rules for Braj Grade 1 and includes English grade 1
+#
+# Copyright (C) 2014 National Institute for Visually Handicapped, 116, Rajpur Road, Dehradun, Uttrakhand, India
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# This table is built and maintained under an activity of Braille Council of India
+# Contributors: Dipendra Manocha, Sreeja, Dinesh Kaushal, Mesar Hamid
+# Last updated on May 5, 2014
+# To report any bugs or any suggestion, please write to d@saksham.org and sreeja.param@gmail.com
+
+include devanagari.cti
+include en-in-g1.ctb
diff --git a/tables/bra.tbl b/tables/bra.tbl
new file mode 100644
index 0000000..77b7d45
--- /dev/null
+++ b/tables/bra.tbl
@@ -0,0 +1,18 @@
+#-index-name: Braj
+#-display-name: Braj braille
+
+#+locale:bra
+#+type:literary
+#+grade:1
+
+# TODO: Please correct the metadata above. It is not meant to be
+# accurate nor complete. It hasn't been verified by the table
+# author yet. It is merely an attempt by the liblouis maintainers
+# to get some sensible initial values in place.
+
+# TODO: Please add a reference to official documentation about
+# the implemented braille code. Preferably submit the documents
+# to https://github.com/liblouis/braille-specs.
+
+include br-in-g1.utb
+include braille-patterns.cti
diff --git a/tables/braille-patterns.cti b/tables/braille-patterns.cti
new file mode 100644
index 0000000..1cb7df6
--- /dev/null
+++ b/tables/braille-patterns.cti
@@ -0,0 +1,287 @@
+#
+# Copyright (C) 2010, 2011 DocArch <http://www.docarch.be>.
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# ----------------------------------------------------------------------------------------------
+# odt2braille - Braille authoring in OpenOffice.org.
+# ----------------------------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 2800..28FF Braille Patterns
+# ----------------------------------------------------------------------------------------------
+
+noback sign \x2800 0 # ⠀ BRAILLE PATTERN DOTS-0
+noback sign \x2801 1 # ⠁ BRAILLE PATTERN DOTS-1
+noback sign \x2802 2 # ⠂ BRAILLE PATTERN DOTS-2
+noback sign \x2803 12 # ⠃ BRAILLE PATTERN DOTS-12
+noback sign \x2804 3 # ⠄ BRAILLE PATTERN DOTS-3
+noback sign \x2805 13 # ⠅ BRAILLE PATTERN DOTS-13
+noback sign \x2806 23 # ⠆ BRAILLE PATTERN DOTS-23
+noback sign \x2807 123 # ⠇ BRAILLE PATTERN DOTS-123
+noback sign \x2808 4 # ⠈ BRAILLE PATTERN DOTS-4
+noback sign \x2809 14 # ⠉ BRAILLE PATTERN DOTS-14
+noback sign \x280A 24 # ⠊ BRAILLE PATTERN DOTS-24
+noback sign \x280B 124 # ⠋ BRAILLE PATTERN DOTS-124
+noback sign \x280C 34 # ⠌ BRAILLE PATTERN DOTS-34
+noback sign \x280D 134 # ⠍ BRAILLE PATTERN DOTS-134
+noback sign \x280E 234 # ⠎ BRAILLE PATTERN DOTS-234
+noback sign \x280F 1234 # ⠏ BRAILLE PATTERN DOTS-1234
+noback sign \x2810 5 # ⠐ BRAILLE PATTERN DOTS-5
+noback sign \x2811 15 # ⠑ BRAILLE PATTERN DOTS-15
+noback sign \x2812 25 # ⠒ BRAILLE PATTERN DOTS-25
+noback sign \x2813 125 # ⠓ BRAILLE PATTERN DOTS-125
+noback sign \x2814 35 # ⠔ BRAILLE PATTERN DOTS-35
+noback sign \x2815 135 # ⠕ BRAILLE PATTERN DOTS-135
+noback sign \x2816 235 # ⠖ BRAILLE PATTERN DOTS-235
+noback sign \x2817 1235 # ⠗ BRAILLE PATTERN DOTS-1235
+noback sign \x2818 45 # ⠘ BRAILLE PATTERN DOTS-45
+noback sign \x2819 145 # ⠙ BRAILLE PATTERN DOTS-145
+noback sign \x281A 245 # ⠚ BRAILLE PATTERN DOTS-245
+noback sign \x281B 1245 # ⠛ BRAILLE PATTERN DOTS-1245
+noback sign \x281C 345 # ⠜ BRAILLE PATTERN DOTS-345
+noback sign \x281D 1345 # ⠝ BRAILLE PATTERN DOTS-1345
+noback sign \x281E 2345 # ⠞ BRAILLE PATTERN DOTS-2345
+noback sign \x281F 12345 # ⠟ BRAILLE PATTERN DOTS-12345
+noback sign \x2820 6 # ⠠ BRAILLE PATTERN DOTS-6
+noback sign \x2821 16 # ⠡ BRAILLE PATTERN DOTS-16
+noback sign \x2822 26 # ⠢ BRAILLE PATTERN DOTS-26
+noback sign \x2823 126 # ⠣ BRAILLE PATTERN DOTS-126
+noback sign \x2824 36 # ⠤ BRAILLE PATTERN DOTS-36
+noback sign \x2825 136 # ⠥ BRAILLE PATTERN DOTS-136
+noback sign \x2826 236 # ⠦ BRAILLE PATTERN DOTS-236
+noback sign \x2827 1236 # ⠧ BRAILLE PATTERN DOTS-1236
+noback sign \x2828 46 # ⠨ BRAILLE PATTERN DOTS-46
+noback sign \x2829 146 # ⠩ BRAILLE PATTERN DOTS-146
+noback sign \x282A 246 # ⠪ BRAILLE PATTERN DOTS-246
+noback sign \x282B 1246 # ⠫ BRAILLE PATTERN DOTS-1246
+noback sign \x282C 346 # ⠬ BRAILLE PATTERN DOTS-346
+noback sign \x282D 1346 # ⠭ BRAILLE PATTERN DOTS-1346
+noback sign \x282E 2346 # ⠮ BRAILLE PATTERN DOTS-2346
+noback sign \x282F 12346 # ⠯ BRAILLE PATTERN DOTS-12346
+noback sign \x2830 56 # ⠰ BRAILLE PATTERN DOTS-56
+noback sign \x2831 156 # ⠱ BRAILLE PATTERN DOTS-156
+noback sign \x2832 256 # ⠲ BRAILLE PATTERN DOTS-256
+noback sign \x2833 1256 # ⠳ BRAILLE PATTERN DOTS-1256
+noback sign \x2834 356 # ⠴ BRAILLE PATTERN DOTS-356
+noback sign \x2835 1356 # ⠵ BRAILLE PATTERN DOTS-1356
+noback sign \x2836 2356 # ⠶ BRAILLE PATTERN DOTS-2356
+noback sign \x2837 12356 # ⠷ BRAILLE PATTERN DOTS-12356
+noback sign \x2838 456 # ⠸ BRAILLE PATTERN DOTS-456
+noback sign \x2839 1456 # ⠹ BRAILLE PATTERN DOTS-1456
+noback sign \x283A 2456 # ⠺ BRAILLE PATTERN DOTS-2456
+noback sign \x283B 12456 # ⠻ BRAILLE PATTERN DOTS-12456
+noback sign \x283C 3456 # ⠼ BRAILLE PATTERN DOTS-3456
+noback sign \x283D 13456 # ⠽ BRAILLE PATTERN DOTS-13456
+noback sign \x283E 23456 # ⠾ BRAILLE PATTERN DOTS-23456
+noback sign \x283F 123456 # ⠿ BRAILLE PATTERN DOTS-123456
+noback sign \x2840 7 # ⡀ BRAILLE PATTERN DOTS-7
+noback sign \x2841 17 # ⡁ BRAILLE PATTERN DOTS-17
+noback sign \x2842 27 # ⡂ BRAILLE PATTERN DOTS-27
+noback sign \x2843 127 # ⡃ BRAILLE PATTERN DOTS-127
+noback sign \x2844 37 # ⡄ BRAILLE PATTERN DOTS-37
+noback sign \x2845 137 # ⡅ BRAILLE PATTERN DOTS-137
+noback sign \x2846 237 # ⡆ BRAILLE PATTERN DOTS-237
+noback sign \x2847 1237 # ⡇ BRAILLE PATTERN DOTS-1237
+noback sign \x2848 47 # ⡈ BRAILLE PATTERN DOTS-47
+noback sign \x2849 147 # ⡉ BRAILLE PATTERN DOTS-147
+noback sign \x284A 247 # ⡊ BRAILLE PATTERN DOTS-247
+noback sign \x284B 1247 # ⡋ BRAILLE PATTERN DOTS-1247
+noback sign \x284C 347 # ⡌ BRAILLE PATTERN DOTS-347
+noback sign \x284D 1347 # ⡍ BRAILLE PATTERN DOTS-1347
+noback sign \x284E 2347 # ⡎ BRAILLE PATTERN DOTS-2347
+noback sign \x284F 12347 # ⡏ BRAILLE PATTERN DOTS-12347
+noback sign \x2850 57 # ⡐ BRAILLE PATTERN DOTS-57
+noback sign \x2851 157 # ⡑ BRAILLE PATTERN DOTS-157
+noback sign \x2852 257 # ⡒ BRAILLE PATTERN DOTS-257
+noback sign \x2853 1257 # ⡓ BRAILLE PATTERN DOTS-1257
+noback sign \x2854 357 # ⡔ BRAILLE PATTERN DOTS-357
+noback sign \x2855 1357 # ⡕ BRAILLE PATTERN DOTS-1357
+noback sign \x2856 2357 # ⡖ BRAILLE PATTERN DOTS-2357
+noback sign \x2857 12357 # ⡗ BRAILLE PATTERN DOTS-12357
+noback sign \x2858 457 # ⡘ BRAILLE PATTERN DOTS-457
+noback sign \x2859 1457 # ⡙ BRAILLE PATTERN DOTS-1457
+noback sign \x285A 2457 # ⡚ BRAILLE PATTERN DOTS-2457
+noback sign \x285B 12457 # ⡛ BRAILLE PATTERN DOTS-12457
+noback sign \x285C 3457 # ⡜ BRAILLE PATTERN DOTS-3457
+noback sign \x285D 13457 # ⡝ BRAILLE PATTERN DOTS-13457
+noback sign \x285E 23457 # ⡞ BRAILLE PATTERN DOTS-23457
+noback sign \x285F 123457 # ⡟ BRAILLE PATTERN DOTS-123457
+noback sign \x2860 67 # ⡠ BRAILLE PATTERN DOTS-67
+noback sign \x2861 167 # ⡡ BRAILLE PATTERN DOTS-167
+noback sign \x2862 267 # ⡢ BRAILLE PATTERN DOTS-267
+noback sign \x2863 1267 # ⡣ BRAILLE PATTERN DOTS-1267
+noback sign \x2864 367 # ⡤ BRAILLE PATTERN DOTS-367
+noback sign \x2865 1367 # ⡥ BRAILLE PATTERN DOTS-1367
+noback sign \x2866 2367 # ⡦ BRAILLE PATTERN DOTS-2367
+noback sign \x2867 12367 # ⡧ BRAILLE PATTERN DOTS-12367
+noback sign \x2868 467 # ⡨ BRAILLE PATTERN DOTS-467
+noback sign \x2869 1467 # ⡩ BRAILLE PATTERN DOTS-1467
+noback sign \x286A 2467 # ⡪ BRAILLE PATTERN DOTS-2467
+noback sign \x286B 12467 # ⡫ BRAILLE PATTERN DOTS-12467
+noback sign \x286C 3467 # ⡬ BRAILLE PATTERN DOTS-3467
+noback sign \x286D 13467 # ⡭ BRAILLE PATTERN DOTS-13467
+noback sign \x286E 23467 # ⡮ BRAILLE PATTERN DOTS-23467
+noback sign \x286F 123467 # ⡯ BRAILLE PATTERN DOTS-123467
+noback sign \x2870 567 # ⡰ BRAILLE PATTERN DOTS-567
+noback sign \x2871 1567 # ⡱ BRAILLE PATTERN DOTS-1567
+noback sign \x2872 2567 # ⡲ BRAILLE PATTERN DOTS-2567
+noback sign \x2873 12567 # ⡳ BRAILLE PATTERN DOTS-12567
+noback sign \x2874 3567 # ⡴ BRAILLE PATTERN DOTS-3567
+noback sign \x2875 13567 # ⡵ BRAILLE PATTERN DOTS-13567
+noback sign \x2876 23567 # ⡶ BRAILLE PATTERN DOTS-23567
+noback sign \x2877 123567 # ⡷ BRAILLE PATTERN DOTS-123567
+noback sign \x2878 4567 # ⡸ BRAILLE PATTERN DOTS-4567
+noback sign \x2879 14567 # ⡹ BRAILLE PATTERN DOTS-14567
+noback sign \x287A 24567 # ⡺ BRAILLE PATTERN DOTS-24567
+noback sign \x287B 124567 # ⡻ BRAILLE PATTERN DOTS-124567
+noback sign \x287C 34567 # ⡼ BRAILLE PATTERN DOTS-34567
+noback sign \x287D 134567 # ⡽ BRAILLE PATTERN DOTS-134567
+noback sign \x287E 234567 # ⡾ BRAILLE PATTERN DOTS-234567
+noback sign \x287F 1234567 # ⡿ BRAILLE PATTERN DOTS-1234567
+noback sign \x2880 8 # ⢀ BRAILLE PATTERN DOTS-8
+noback sign \x2881 18 # ⢁ BRAILLE PATTERN DOTS-18
+noback sign \x2882 28 # ⢂ BRAILLE PATTERN DOTS-28
+noback sign \x2883 128 # ⢃ BRAILLE PATTERN DOTS-128
+noback sign \x2884 38 # ⢄ BRAILLE PATTERN DOTS-38
+noback sign \x2885 138 # ⢅ BRAILLE PATTERN DOTS-138
+noback sign \x2886 238 # ⢆ BRAILLE PATTERN DOTS-238
+noback sign \x2887 1238 # ⢇ BRAILLE PATTERN DOTS-1238
+noback sign \x2888 48 # ⢈ BRAILLE PATTERN DOTS-48
+noback sign \x2889 148 # ⢉ BRAILLE PATTERN DOTS-148
+noback sign \x288A 248 # ⢊ BRAILLE PATTERN DOTS-248
+noback sign \x288B 1248 # ⢋ BRAILLE PATTERN DOTS-1248
+noback sign \x288C 348 # ⢌ BRAILLE PATTERN DOTS-348
+noback sign \x288D 1348 # ⢍ BRAILLE PATTERN DOTS-1348
+noback sign \x288E 2348 # ⢎ BRAILLE PATTERN DOTS-2348
+noback sign \x288F 12348 # ⢏ BRAILLE PATTERN DOTS-12348
+noback sign \x2890 58 # ⢐ BRAILLE PATTERN DOTS-58
+noback sign \x2891 158 # ⢑ BRAILLE PATTERN DOTS-158
+noback sign \x2892 258 # ⢒ BRAILLE PATTERN DOTS-258
+noback sign \x2893 1258 # ⢓ BRAILLE PATTERN DOTS-1258
+noback sign \x2894 358 # ⢔ BRAILLE PATTERN DOTS-358
+noback sign \x2895 1358 # ⢕ BRAILLE PATTERN DOTS-1358
+noback sign \x2896 2358 # ⢖ BRAILLE PATTERN DOTS-2358
+noback sign \x2897 12358 # ⢗ BRAILLE PATTERN DOTS-12358
+noback sign \x2898 458 # ⢘ BRAILLE PATTERN DOTS-458
+noback sign \x2899 1458 # ⢙ BRAILLE PATTERN DOTS-1458
+noback sign \x289A 2458 # ⢚ BRAILLE PATTERN DOTS-2458
+noback sign \x289B 12458 # ⢛ BRAILLE PATTERN DOTS-12458
+noback sign \x289C 3458 # ⢜ BRAILLE PATTERN DOTS-3458
+noback sign \x289D 13458 # ⢝ BRAILLE PATTERN DOTS-13458
+noback sign \x289E 23458 # ⢞ BRAILLE PATTERN DOTS-23458
+noback sign \x289F 123458 # ⢟ BRAILLE PATTERN DOTS-123458
+noback sign \x28A0 68 # ⢠ BRAILLE PATTERN DOTS-68
+noback sign \x28A1 168 # ⢡ BRAILLE PATTERN DOTS-168
+noback sign \x28A2 268 # ⢢ BRAILLE PATTERN DOTS-268
+noback sign \x28A3 1268 # ⢣ BRAILLE PATTERN DOTS-1268
+noback sign \x28A4 368 # ⢤ BRAILLE PATTERN DOTS-368
+noback sign \x28A5 1368 # ⢥ BRAILLE PATTERN DOTS-1368
+noback sign \x28A6 2368 # ⢦ BRAILLE PATTERN DOTS-2368
+noback sign \x28A7 12368 # ⢧ BRAILLE PATTERN DOTS-12368
+noback sign \x28A8 468 # ⢨ BRAILLE PATTERN DOTS-468
+noback sign \x28A9 1468 # ⢩ BRAILLE PATTERN DOTS-1468
+noback sign \x28AA 2468 # ⢪ BRAILLE PATTERN DOTS-2468
+noback sign \x28AB 12468 # ⢫ BRAILLE PATTERN DOTS-12468
+noback sign \x28AC 3468 # ⢬ BRAILLE PATTERN DOTS-3468
+noback sign \x28AD 13468 # ⢭ BRAILLE PATTERN DOTS-13468
+noback sign \x28AE 23468 # ⢮ BRAILLE PATTERN DOTS-23468
+noback sign \x28AF 123468 # ⢯ BRAILLE PATTERN DOTS-123468
+noback sign \x28B0 568 # ⢰ BRAILLE PATTERN DOTS-568
+noback sign \x28B1 1568 # ⢱ BRAILLE PATTERN DOTS-1568
+noback sign \x28B2 2568 # ⢲ BRAILLE PATTERN DOTS-2568
+noback sign \x28B3 12568 # ⢳ BRAILLE PATTERN DOTS-12568
+noback sign \x28B4 3568 # ⢴ BRAILLE PATTERN DOTS-3568
+noback sign \x28B5 13568 # ⢵ BRAILLE PATTERN DOTS-13568
+noback sign \x28B6 23568 # ⢶ BRAILLE PATTERN DOTS-23568
+noback sign \x28B7 123568 # ⢷ BRAILLE PATTERN DOTS-123568
+noback sign \x28B8 4568 # ⢸ BRAILLE PATTERN DOTS-4568
+noback sign \x28B9 14568 # ⢹ BRAILLE PATTERN DOTS-14568
+noback sign \x28BA 24568 # ⢺ BRAILLE PATTERN DOTS-24568
+noback sign \x28BB 124568 # ⢻ BRAILLE PATTERN DOTS-124568
+noback sign \x28BC 34568 # ⢼ BRAILLE PATTERN DOTS-34568
+noback sign \x28BD 134568 # ⢽ BRAILLE PATTERN DOTS-134568
+noback sign \x28BE 234568 # ⢾ BRAILLE PATTERN DOTS-234568
+noback sign \x28BF 1234568 # ⢿ BRAILLE PATTERN DOTS-1234568
+noback sign \x28C0 78 # ⣀ BRAILLE PATTERN DOTS-78
+noback sign \x28C1 178 # ⣁ BRAILLE PATTERN DOTS-178
+noback sign \x28C2 278 # ⣂ BRAILLE PATTERN DOTS-278
+noback sign \x28C3 1278 # ⣃ BRAILLE PATTERN DOTS-1278
+noback sign \x28C4 378 # ⣄ BRAILLE PATTERN DOTS-378
+noback sign \x28C5 1378 # ⣅ BRAILLE PATTERN DOTS-1378
+noback sign \x28C6 2378 # ⣆ BRAILLE PATTERN DOTS-2378
+noback sign \x28C7 12378 # ⣇ BRAILLE PATTERN DOTS-12378
+noback sign \x28C8 478 # ⣈ BRAILLE PATTERN DOTS-478
+noback sign \x28C9 1478 # ⣉ BRAILLE PATTERN DOTS-1478
+noback sign \x28CA 2478 # ⣊ BRAILLE PATTERN DOTS-2478
+noback sign \x28CB 12478 # ⣋ BRAILLE PATTERN DOTS-12478
+noback sign \x28CC 3478 # ⣌ BRAILLE PATTERN DOTS-3478
+noback sign \x28CD 13478 # ⣍ BRAILLE PATTERN DOTS-13478
+noback sign \x28CE 23478 # ⣎ BRAILLE PATTERN DOTS-23478
+noback sign \x28CF 123478 # ⣏ BRAILLE PATTERN DOTS-123478
+noback sign \x28D0 578 # ⣐ BRAILLE PATTERN DOTS-578
+noback sign \x28D1 1578 # ⣑ BRAILLE PATTERN DOTS-1578
+noback sign \x28D2 2578 # ⣒ BRAILLE PATTERN DOTS-2578
+noback sign \x28D3 12578 # ⣓ BRAILLE PATTERN DOTS-12578
+noback sign \x28D4 3578 # ⣔ BRAILLE PATTERN DOTS-3578
+noback sign \x28D5 13578 # ⣕ BRAILLE PATTERN DOTS-13578
+noback sign \x28D6 23578 # ⣖ BRAILLE PATTERN DOTS-23578
+noback sign \x28D7 123578 # ⣗ BRAILLE PATTERN DOTS-123578
+noback sign \x28D8 4578 # ⣘ BRAILLE PATTERN DOTS-4578
+noback sign \x28D9 14578 # ⣙ BRAILLE PATTERN DOTS-14578
+noback sign \x28DA 24578 # ⣚ BRAILLE PATTERN DOTS-24578
+noback sign \x28DB 124578 # ⣛ BRAILLE PATTERN DOTS-124578
+noback sign \x28DC 34578 # ⣜ BRAILLE PATTERN DOTS-34578
+noback sign \x28DD 134578 # ⣝ BRAILLE PATTERN DOTS-134578
+noback sign \x28DE 234578 # ⣞ BRAILLE PATTERN DOTS-234578
+noback sign \x28DF 1234578 # ⣟ BRAILLE PATTERN DOTS-1234578
+noback sign \x28E0 678 # ⣠ BRAILLE PATTERN DOTS-678
+noback sign \x28E1 1678 # ⣡ BRAILLE PATTERN DOTS-1678
+noback sign \x28E2 2678 # ⣢ BRAILLE PATTERN DOTS-2678
+noback sign \x28E3 12678 # ⣣ BRAILLE PATTERN DOTS-12678
+noback sign \x28E4 3678 # ⣤ BRAILLE PATTERN DOTS-3678
+noback sign \x28E5 13678 # ⣥ BRAILLE PATTERN DOTS-13678
+noback sign \x28E6 23678 # ⣦ BRAILLE PATTERN DOTS-23678
+noback sign \x28E7 123678 # ⣧ BRAILLE PATTERN DOTS-123678
+noback sign \x28E8 4678 # ⣨ BRAILLE PATTERN DOTS-4678
+noback sign \x28E9 14678 # ⣩ BRAILLE PATTERN DOTS-14678
+noback sign \x28EA 24678 # ⣪ BRAILLE PATTERN DOTS-24678
+noback sign \x28EB 124678 # ⣫ BRAILLE PATTERN DOTS-124678
+noback sign \x28EC 34678 # ⣬ BRAILLE PATTERN DOTS-34678
+noback sign \x28ED 134678 # ⣭ BRAILLE PATTERN DOTS-134678
+noback sign \x28EE 234678 # ⣮ BRAILLE PATTERN DOTS-234678
+noback sign \x28EF 1234678 # ⣯ BRAILLE PATTERN DOTS-1234678
+noback sign \x28F0 5678 # ⣰ BRAILLE PATTERN DOTS-5678
+noback sign \x28F1 15678 # ⣱ BRAILLE PATTERN DOTS-15678
+noback sign \x28F2 25678 # ⣲ BRAILLE PATTERN DOTS-25678
+noback sign \x28F3 125678 # ⣳ BRAILLE PATTERN DOTS-125678
+noback sign \x28F4 35678 # ⣴ BRAILLE PATTERN DOTS-35678
+noback sign \x28F5 135678 # ⣵ BRAILLE PATTERN DOTS-135678
+noback sign \x28F6 235678 # ⣶ BRAILLE PATTERN DOTS-235678
+noback sign \x28F7 1235678 # ⣷ BRAILLE PATTERN DOTS-1235678
+noback sign \x28F8 45678 # ⣸ BRAILLE PATTERN DOTS-45678
+noback sign \x28F9 145678 # ⣹ BRAILLE PATTERN DOTS-145678
+noback sign \x28FA 245678 # ⣺ BRAILLE PATTERN DOTS-245678
+noback sign \x28FB 1245678 # ⣻ BRAILLE PATTERN DOTS-1245678
+noback sign \x28FC 345678 # ⣼ BRAILLE PATTERN DOTS-345678
+noback sign \x28FD 1345678 # ⣽ BRAILLE PATTERN DOTS-1345678
+noback sign \x28FE 2345678 # ⣾ BRAILLE PATTERN DOTS-2345678
+noback sign \x28FF 12345678 # ⣿ BRAILLE PATTERN DOTS-12345678
+
+
+# ----------------------------------------------------------------------------------------------
+
diff --git a/tables/ca-chardefs.cti b/tables/ca-chardefs.cti
new file mode 100644
index 0000000..6446abc
--- /dev/null
+++ b/tables/ca-chardefs.cti
@@ -0,0 +1,195 @@
+# ----------------------------------------------------------------------------------------------
+# odt2braille - Braille authoring in OpenOffice.org.
+# Copyright (c) 2010 by DocArch <http://www.docarch.be>.
+# ----------------------------------------------------------------------------------------------
+#
+# Catalan Braille
+# Created and maintained by Bert Frees <bertfrees@gmail.com>
+# with the assistance of Carles Sadurní Anguita <http://www.transcriptor.net/>
+#
+# ----------------------------------------------------------------------------------------------
+
+space \x0009 9 <control> HORIZONTAL TABULATION
+space \x001B 1b <control> ESCAPE
+space \x00A0 a NO-BREAK SPACE
+include spaces.uti
+
+# ==============================================================================================
+# SINGLE-CELL
+# ==============================================================================================
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 0000..007F C0 Controls and Basic Latin
+# ----------------------------------------------------------------------------------------------
+
+include latinLetterDef6Dots.uti
+
+uplow \x00C0\x00E0 12356,12356 Àà LATIN CAPITAL LETTER A WITH GRAVE - LATIN SMALL LETTER A WITH GRAVE
+uplow \x00C7\x00E7 12346,12346 Çç LATIN CAPITAL LETTER C WITH CEDILLA - LATIN SMALL LETTER C WITH CEDILLA
+uplow \x00C8\x00E8 2346,2346 Èè LATIN CAPITAL LETTER E WITH GRAVE - LATIN SMALL LETTER E WITH GRAVE
+uplow \x00C9\x00E9 123456,123456 Éé LATIN CAPITAL LETTER E WITH ACUTE - LATIN SMALL LETTER E WITH ACUTE
+uplow \x00CD\x00ED 34,34 Íí LATIN CAPITAL LETTER I WITH ACUTE - LATIN SMALL LETTER I WITH ACUTE
+uplow \x00CF\x00EF 12456,12456 Ïï LATIN CAPITAL LETTER I WITH DIAERESIS - LATIN SMALL LETTER I WITH DIAERESIS
+uplow \x00D2\x00F2 346,346 Òò LATIN CAPITAL LETTER O WITH GRAVE - LATIN SMALL LETTER O WITH GRAVE
+uplow \x00D3\x00F3 246,246 Óó LATIN CAPITAL LETTER O WITH ACUTE - LATIN SMALL LETTER O WITH ACUTE
+uplow \x00DA\x00FA 23456,23456 Úú LATIN CAPITAL LETTER U WITH ACUTE - LATIN SMALL LETTER U WITH ACUTE
+uplow \x00DC\x00FC 1256,1256 Üü LATIN CAPITAL LETTER U WITH DIAERESIS - LATIN SMALL LETTER U WITH DIAERESIS
+
+punctuation \x0021 256 ! EXCLAMATION MARK
+punctuation \x0022 236 " QUOTATION MARK
+punctuation \x0027 3 ' APOSTROPHE
+punctuation \x0028 126 ( LEFT PARENTHESIS
+punctuation \x0029 345 ) RIGHT PARENTHESIS
+sign \x002A 35 * ASTERISK
+math \x002B 235 + PLUS SIGN
+punctuation \x002C 2 , COMMA
+punctuation \x002D 36 - HYPHEN-MINUS
+punctuation \x002E 3 . FULL STOP
+include loweredDigits6Dots.uti
+punctuation \x003A 25 : COLON
+punctuation \x003B 23 ; SEMICOLON
+math \x003C 246 < LESS-THAN SIGN
+math \x003D 2356 = EQUALS SIGN
+math \x003E 135 > GREATER-THAN SIGN
+punctuation \x003F 26 ? QUESTION MARK
+punctuation \x005B 12356 [ LEFT SQUARE BRACKET
+punctuation \x005D 23456 ] RIGHT SQUARE BRACKET
+sign \x007C 456 | VERTICAL LINE
+
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 0080..00FF C1 Controls and Latin-1 Supplement
+# ----------------------------------------------------------------------------------------------
+
+punctuation \x0082 2 ‚ <control> BREAK PERMITTED HERE - ANSI: SINGLE LOW-9 QUOTATION MARK - MACROMAN: C CEDILLA
+punctuation \x0084 236 „ <control> - ANSI: DOUBLE LOW-9 QUOTATION MARK - MACROMAN: N TILDE
+punctuation \x0093 236 “ <control> SET TRANSMIT STATE - ANSI: LEFT DOUBLE QUOTATION MARK - MACROMAN: I GRAVE
+punctuation \x0094 236 ” <control> CANCEL CHARACTER - ANSI: RIGHT DOUBLE QUOTATION MARK - MACROMAN: I CIRCUMFLEX
+punctuation \x0096 36 – <control> START OF GUARDED AREA - ANSI: EN DASH - MACROMAN: N TILDE
+punctuation \x00A1 235 ¡ INVERTED EXCLAMATION MARK
+punctuation \x00AB 236 « LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+punctuation \x00AD 36 SOFT HYPHEN
+sign \x00B8 2 ¸ CEDILLA
+punctuation \x00BB 236 » RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+punctuation \x00B7 5 · MIDDLE DOT
+punctuation \x00BF 26 ¿ INVERTED QUESTION MARK
+math \x00D7 236 × MULTIPLICATION SIGN
+math \x00F7 256 ÷ DIVISION SIGN
+
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 2000..206F General Punctuation
+# ----------------------------------------------------------------------------------------------
+
+punctuation \x2010 36 ‐ HYPHEN
+punctuation \x2011 36 ‑ NON-BREAKING HYPHEN
+punctuation \x2012 36 ‒ FIGURE DASH
+punctuation \x2013 36 – EN DASH
+punctuation \x2018 236 ‘ LEFT SINGLE QUOTATION MARK
+punctuation \x2019 236 ’ RIGHT SINGLE QUOTATION MARK
+punctuation \x201A 236 ‚ SINGLE LOW-9 QUOTATION MARK
+punctuation \x201B 236 ‛ SINGLE HIGH-REVERSED-9 QUOTATION MARK
+punctuation \x201C 236 “ LEFT DOUBLE QUOTATION MARK
+punctuation \x201D 236 ” RIGHT DOUBLE QUOTATION MARK
+punctuation \x201E 236 „ DOUBLE LOW-9 QUOTATION MARK
+punctuation \x201F 236 ‟ DOUBLE HIGH-REVERSED-9 QUOTATION MARK
+punctuation \x2043 36 ⁃ HYPHEN BULLET
+
+include braille-patterns.cti
+
+# ==============================================================================================
+# MULTI-CELL
+# ==============================================================================================
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 0000..007F C0 Controls and Basic Latin
+# ----------------------------------------------------------------------------------------------
+
+sign \x0024 345-234 $ DOLLAR SIGN
+math \x0025 456-356 % PERCENT SIGN
+sign \x0026 6-12346 & AMPERSAND
+math \x002F 6-2 / SOLIDUS
+sign \x0040 56-16 @ COMMERCIAL AT
+sign \x005C 5-3 \ REVERSE SOLIDUS
+math \x007B 5-123 { LEFT CURLY BRACKET
+math \x007D 456-2 } RIGHT CURLY BRACKET
+
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 0080..00FF C1 Controls and Latin-1 Supplement
+# ----------------------------------------------------------------------------------------------
+
+sign \x0080 456-15 € <control> - ANSI: EURO-CURRENCY SIGN - MACROMAN: A DIAERESIS
+punctuation \x0085 3-3-3 … <control> NEXT LINE (NEL) - ANSI: HORIZONTAL ELLIPSIS - MACROMAN: O DIAERESIS
+sign \x0089 456-356-356 ‰ <control> CHARACTER TABULATION WITH JUSTIFICATION - ANSI: PER MILLE SIGN - MACROMAN: A CIRCUMFLEX
+punctuation \x0097 36-36 — <control> END OF GUARDED AREA - ANSI: EM DASH - MACROMAN: O ACUTE
+sign \x00A2 45-14 ¢ CENT SIGN
+sign \x00A3 5-2346 £ POUND SIGN
+sign \x00A5 456-13456 ¥ YEN SIGN
+sign \x00A9 126-46-14-345 © COPYRIGHT SIGN
+sign \x00AA 56-16 ª FEMININE ORDINAL INDICATOR
+sign \x00AE 126-46-1235-345 ® REGISTERED SIGN
+math \x00B1 235-25-36 ± PLUS-MINUS SIGN
+sign \x00B2 16-3456-12 ² SUPERSCRIPT TWO
+sign \x00B3 16-3456-14 ³ SUPERSCRIPT THREE
+sign \x00B5 4-134 µ MICRO SIGN
+math \x00BC 1456-2-145 ¼ VULGAR FRACTION ONE QUARTER
+math \x00BD 1456-2-12 ½ VULGAR FRACTION ONE HALF
+math \x00BE 1456-25-145 ¾ VULGAR FRACTION THREE QUARTERS
+
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 0100..017F Latin Extended-A
+# ----------------------------------------------------------------------------------------------
+
+uplow \x013F\x0140 123-5,123-5 Ŀŀ LATIN CAPITAL LETTER L WITH MIDDLE DOT - LATIN SMALL LETTER L WITH MIDDLE DOT
+
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 0370..03FF Greek and Coptic
+# ----------------------------------------------------------------------------------------------
+
+lowercase \x03B1 4-1 α GREEK SMALL LETTER ALPHA
+lowercase \x03B2 4-12 β GREEK SMALL LETTER BETA
+lowercase \x03B3 4-1245 γ GREEK SMALL LETTER GAMMA
+lowercase \x03B4 4-145 δ GREEK SMALL LETTER DELTA
+lowercase \x03B5 4-15 ε GREEK SMALL LETTER EPSILON
+lowercase \x03B6 4-1356 ζ GREEK SMALL LETTER ZETA
+lowercase \x03B7 4-156 η GREEK SMALL LETTER ETA
+lowercase \x03B8 4-1456 θ GREEK SMALL LETTER THETA
+lowercase \x03B9 4-24 ι GREEK SMALL LETTER IOTA
+lowercase \x03BA 4-13 κ GREEK SMALL LETTER KAPPA
+lowercase \x03BB 4-123 λ GREEK SMALL LETTER LAMDA
+lowercase \x03BC 4-134 μ GREEK SMALL LETTER MU
+lowercase \x03BD 4-1345 ν GREEK SMALL LETTER NU
+lowercase \x03BE 4-1346 ξ GREEK SMALL LETTER XI
+lowercase \x03BF 4-135 ο GREEK SMALL LETTER OMICRON
+lowercase \x03C0 4-1234 π GREEK SMALL LETTER PI
+lowercase \x03C1 4-1235 ρ GREEK SMALL LETTER RHO
+lowercase \x03C2 4-234 ς GREEK SMALL LETTER FINAL SIGMA
+lowercase \x03C3 4-234 σ GREEK SMALL LETTER SIGMA
+lowercase \x03C4 4-2345 τ GREEK SMALL LETTER TAU
+lowercase \x03C5 4-136 υ GREEK SMALL LETTER UPSILON
+lowercase \x03C6 4-124 φ GREEK SMALL LETTER PHI
+lowercase \x03C7 4-12346 χ GREEK SMALL LETTER CHI
+lowercase \x03C8 4-13456 ψ GREEK SMALL LETTER PSI
+lowercase \x03C9 4-2456 ω GREEK SMALL LETTER OMEGA
+
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 2000..206F General Punctuation
+# ----------------------------------------------------------------------------------------------
+
+punctuation \x2014 36-36 — EM DASH
+punctuation \x2015 36-36 ― HORIZONTAL BAR
+punctuation \x2026 3-3-3 … HORIZONTAL ELLIPSIS
+
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 20A0..20CF Currency Symbols
+# ----------------------------------------------------------------------------------------------
+
+sign \x20AC 456-15 € EURO SIGN
+
+
+# ----------------------------------------------------------------------------------------------
diff --git a/tables/ca-g1.ctb b/tables/ca-g1.ctb
new file mode 100644
index 0000000..07ddd37
--- /dev/null
+++ b/tables/ca-g1.ctb
@@ -0,0 +1,28 @@
+# ----------------------------------------------------------------------------------------------
+# odt2braille - Braille authoring in OpenOffice.org.
+# Copyright (c) 2010 by DocArch <http://www.docarch.be>.
+# ----------------------------------------------------------------------------------------------
+#
+# Catalan Braille
+# Created and maintained by Bert Frees <bertfrees@gmail.com>
+# with the assistance of Carles Sadurní Anguita <http://www.transcriptor.net/>
+#
+# ----------------------------------------------------------------------------------------------
+
+include ca-chardefs.cti
+
+# ---------------------------------------
+# Digits
+# ---------------------------------------
+
+include litdigits6Dots.uti
+
+# ---------------------------------------
+# Braille indicator opcodes
+# ---------------------------------------
+
+numsign 3456
+capsletter 46
+begcapsword 46-46
+
+# ----------------------------------------------------------------------------------------------
diff --git a/tables/ca.tbl b/tables/ca.tbl
new file mode 100644
index 0000000..baa6d1b
--- /dev/null
+++ b/tables/ca.tbl
@@ -0,0 +1,18 @@
+#-index-name: Catalan
+#-display-name: Catalan braille
+
+#+locale:ca
+#+type:literary
+#+grade:1
+
+# TODO: Please correct the metadata above. It is not meant to be
+# accurate nor complete. It hasn't been verified by the table
+# author yet. It is merely an attempt by the liblouis maintainers
+# to get some sensible initial values in place.
+
+# TODO: Please add a reference to official documentation about
+# the implemented braille code. Preferably submit the documents
+# to https://github.com/liblouis/braille-specs.
+
+include ca-g1.ctb
+include braille-patterns.cti
diff --git a/tables/chr-us-g1.ctb b/tables/chr-us-g1.ctb
new file mode 100644
index 0000000..3e95a47
--- /dev/null
+++ b/tables/chr-us-g1.ctb
@@ -0,0 +1,177 @@
+#chr##1#Cherokee Uncontracted#
+# liblouis: Cherokee Braille Table
+#
+# ------------
+#-index-name: Cherokee
+#-display-name: Cherokee braille
+#
+#+locale:chr
+#+type:literary
+#+contraction:no
+#+grade:1
+#
+# TODO: Please correct the metadata above. It is not meant to be
+# accurate nor complete. It hasn't been verified by the table
+# author yet. It is merely an attempt by the liblouis maintainers
+# to get some sensible initial values in place.
+# ------------
+#
+# Based on the Cherokee (ᏣᎳᎩ) syllabary Braille code developed by
+# Tamara Johnson Kearney <https://www.cbtbc.org/braille/cherokee/>.
+#
+# Copyright (C) 2014, Greg Kearney, gkearney@gmail.com
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+#include text_nabcc.dis All display opcodes
+
+include en-ueb-g1.ctb
+
+# letsign 456 ink letter sign
+
+# The Vowels
+
+letter \x13A0 1 CHEROKEE LETTER A
+letter \x13A1 15 CHEROKEE LETTER E
+letter \x13A2 24 CHEROKEE LETTER I
+letter \x13A3 135 CHEROKEE LETTER O
+letter \x13A4 136 CHEROKEE LETTER U
+letter \x13A5 1236 CHEROKEE LETTER V
+
+# The Consonants
+# G
+
+letter \x13A6 1245-1 CHEROKEE LETTER GA
+letter \x13A7 13-1 CHEROKEE LETTER KA
+letter \x13A8 1245-15 CHEROKEE LETTER GE
+letter \x13A9 1245-24 CHEROKEE LETTER GI
+letter \x13AA 1245-135 CHEROKEE LETTER GO
+letter \x13AB 1245-136 CHEROKEE LETTER GU
+letter \x13AC 1245-1236 CHEROKEE LETTER GV
+
+# H
+
+letter \x13AD 125-1 CHEROKEE LETTER HA
+letter \x13AE 125-15 CHEROKEE LETTER HE
+letter \x13AF 125-24 CHEROKEE LETTER HI
+letter \x13B0 125-135 CHEROKEE LETTER HO
+letter \x13B1 125-136 CHEROKEE LETTER HU
+letter \x13B2 125-1236 CHEROKEE LETTER HV
+
+# L
+
+letter \x13B3 123-1 CHEROKEE LETTER LA
+letter \x13B4 123-15 CHEROKEE LETTER LE
+letter \x13B5 123-24 CHEROKEE LETTER LI
+letter \x13B6 123-135 CHEROKEE LETTER LO
+letter \x13B7 123-136 CHEROKEE LETTER LU
+letter \x13B8 123-1236 CHEROKEE LETTER LV
+
+# M
+
+letter \x13B9 134-1 CHEROKEE LETTER MA
+letter \x13BA 134-15 CHEROKEE LETTER ME
+letter \x13BB 134-24 CHEROKEE LETTER MI
+letter \x13BC 134-135 CHEROKEE LETTER MO
+letter \x13BD 134-136 CHEROKEE LETTER MU
+# SPACE RESERVED FOR CHEROKEE LETTER MV
+
+# N
+
+letter \x13BE 1345-1 CHEROKEE LETTER NA
+letter \x13BF 12-1 CHEROKEE LETTER HNA
+letter \x13C0 14-1 CHEROKEE LETTER NAH
+letter \x13C1 1345-15 CHEROKEE LETTER NE
+letter \x13C2 1345-24 CHEROKEE LETTER NI
+letter \x13C3 1345-135 CHEROKEE LETTER NO
+letter \x13C4 1345-136 CHEROKEE LETTER NU
+letter \x13C5 1345-1236 CHEROKEE LETTER NV
+
+# Q
+
+letter \x13C6 12345-1 CHEROKEE LETTER QA
+letter \x13C7 12345-15 CHEROKEE LETTER QE
+letter \x13C8 12345-24 CHEROKEE LETTER QI
+letter \x13C9 12345-135 CHEROKEE LETTER QO
+letter \x13CA 12345-136 CHEROKEE LETTER QU
+letter \x13CB 12345-1236 CHEROKEE LETTER QV
+
+# S
+
+letter \x13CD 234 CHEROKEE LETTER S
+letter \x13CC 234-1 CHEROKEE LETTER SA
+letter \x13CE 234-15 CHEROKEE LETTER SE
+letter \x13CF 234-24 CHEROKEE LETTER SI
+letter \x13D0 234-135 CHEROKEE LETTER SO
+letter \x13D1 234-136 CHEROKEE LETTER SU
+letter \x13D2 234-1236 CHEROKEE LETTER SV
+
+# D T
+
+letter \x13D3 145-1 CHEROKEE LETTER DA
+letter \x13D4 2345-1 CHEROKEE LETTER SA
+letter \x13D5 145-15 CHEROKEE LETTER DE
+letter \x13D6 2345-15 CHEROKEE LETTER SE
+letter \x13D7 145-24 CHEROKEE LETTER DI
+letter \x13D8 2345-24 CHEROKEE LETTER SI
+
+letter \x13D9 145-135 CHEROKEE LETTER DO
+letter \x13DA 145-136 CHEROKEE LETTER DU
+letter \x13DB 145-1236 CHEROKEE LETTER DV
+
+# R F
+
+letter \x13DC 124-1 CHEROKEE LETTER DLA
+letter \x13DD 1235-1 CHEROKEE LETTER TLA
+letter \x13DE 1235-15 CHEROKEE LETTER TLE
+letter \x13DF 1235-24 CHEROKEE LETTER TLI
+letter \x13E0 1235-135 CHEROKEE LETTER TLO
+letter \x13E1 1235-136 CHEROKEE LETTER TLU
+letter \x13E2 1235-1236 CHEROKEE LETTER TLV
+
+
+# Z
+
+letter \x13E3 1356-1 CHEROKEE LETTER TSA
+letter \x13E4 1356-15 CHEROKEE LETTER TSE
+letter \x13E5 1356-24 CHEROKEE LETTER TSI
+letter \x13E6 1356-135 CHEROKEE LETTER TSO
+letter \x13E7 1356-136 CHEROKEE LETTER TSU
+letter \x13E8 1356-1236 CHEROKEE LETTER TSV
+
+# W
+
+letter \x13E9 2456-1 CHEROKEE LETTER WA
+letter \x13EA 2456-15 CHEROKEE LETTER WE
+letter \x13EB 2456-24 CHEROKEE LETTER WI
+letter \x13EC 2456-135 CHEROKEE LETTER WO
+letter \x13ED 2456-136 CHEROKEE LETTER WU
+letter \x13EE 2456-1236 CHEROKEE LETTER WV
+
+# Y
+
+letter \x13EF 13456-1 CHEROKEE LETTER YA
+letter \x13F0 13456-15 CHEROKEE LETTER YE
+letter \x13F1 13456-24 CHEROKEE LETTER YI
+letter \x13F2 13456-135 CHEROKEE LETTER YO
+letter \x13F3 13456-136 CHEROKEE LETTER YU
+letter \x13F4 13456-1236 CHEROKEE LETTER YV
+
+letter \x0323 5 COMBINING DOT BELOW
+letter \x0331 156 COMBINING MACRON BELOW
+letter \x0324 56 COMBINING DIAERESIS BELOW
+letter \x0330 12456 COMBINING TILDE BELOW
diff --git a/tables/ckb-chardefs.cti b/tables/ckb-chardefs.cti
new file mode 100644
index 0000000..4d08b77
--- /dev/null
+++ b/tables/ckb-chardefs.cti
@@ -0,0 +1,219 @@
+#
+# Copyright (C) 2011 by Peter Engström <peter.engstrom@indexbraille.com>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# -----------------------------------------------------------------------------
+#
+# SORANI (KURDISH)
+# ================
+# Author: Peter Engström
+# Company: Index Braille
+#
+# Date: Note:
+# 2011-02-08 Initial release based on _chardefs_ar.cti
+# 2011-03-15 Updated
+# 2011-03-22 Removing U+200C from text. New braille code for Heh.
+# Arabic letters where coded as signs.
+# 2011-03-23 New handling of U+200C. Letter Heh changed again.
+#
+#
+
+# Remove U+200C three-per-em space = thick space but let it be a virtual space.
+space \x200C 9 # Assign x200C to virtual dot 9. [Peter Engström 2011-03-23]
+noback pass2 @9 ? # Remove virtual dot 9 during second pass. [Peter Engström 2011-03-23]
+space \x00a0 a
+include spaces.uti
+
+# ----------- define all chars ------------------------------------------------
+
+punctuation ! 235 # 33
+punctuation " 236 # 34 [Peter Engström 2011-03-15]
+sign # 3456 # 35
+sign $ 1246 # 36 [Peter Engström 2011-03-15]
+sign % 1234 # 37 [Peter Engström 2011-03-15]
+sign & 12346 # 38 [Peter Engström 2011-03-15]
+punctuation ' 3 # 39 apostrophe
+punctuation ) 356 # 40
+punctuation ( 236 # 41
+sign * 16 # 42 [Peter Engström 2011-03-15]
+math + 346 # 43 [Peter Engström 2011-03-15]
+punctuation , 46 # 44
+punctuation - 36 # 45
+punctuation \x06D4 256 # Arabic Full stop
+punctuation . 256 # 46 [Peter Engström 2011-03-15]
+math / 34 # 47
+include loweredDigits6Dots.uti
+punctuation : 5-2 # 58 [Peter Engström 2011-03-15]
+punctuation ; 5 # 59 [Peter Engström 2011-03-15]
+math < 0-126-0 # 60 [Peter Engström 2011-03-15]
+math = 123456 # 61 [Peter Engström 2011-03-15]
+letter > 0-246-0
+math > 0-345-0 # 62 [Peter Engström 2011-03-15]
+punctuation ? 1456 # 63
+sign @ 4 # 64
+
+include latinLetterDef6Dots.uti
+
+punctuation [ 13456 # 91 [Peter Engström 2011-03-15]
+sign \\ 1256 # 92 [Peter Engström 2011-03-15]
+punctuation ] 12346 # 93 [Peter Engström 2011-03-15]
+sign ^ 45 # 94 circumflex accent [Peter Engström 2011-03-15]
+sign _ 456 # 95 underscore
+sign ` 4 # 96 grave accent
+# a - z # 97 - 122
+punctuation { 135 # 123 [Peter Engström 2011-03-15]
+sign | 1245 # 124
+punctuation } 246 # 125 [Peter Engström 2011-03-15]
+math ~ 45 # 126
+sign \x00A2 4-14 # 162 ¢ cents sign
+sign \x00A3 4-123 # 163 £ pounds sign
+sign \x00A5 4-13456 # 165 ¥ yen sign
+sign § 4-234-3 # 167 section sign \x00A7
+sign \x00A9 2356-6-14-2356 # 169 © copyright sign
+sign \x00AE 16-256 # ® Registered mark
+punctuation \x00Ad 36 # 173 soft hyphen
+sign \x00B0 356 # 176 ° degrees sign
+sign \x00B5 46-134 # 181 µ micro sign
+sign \x00B6 4-1234-345 # 182 ¶ pilcrow sign
+sign \x00BF 236 # 191 inverted question mark
+math \x00D7 56-236 # 215 × multiplication sign
+math \x00F7 56-256 # 247 ÷ division sign
+
+punctuation \x2010 36 # 8208 hyphen
+punctuation \x2011 23478 # 8209 non-breaking hyphen
+punctuation \x2013 246 # 8211 en dash [Peter Engström 2011-03-15]
+punctuation \x2014 246 # 8212 [Peter Engström 2011-03-15]
+punctuation \x2018 3 # 8216 smart single left quotation mark
+punctuation \x2019 3 # 8217 smart single right quotation mark
+punctuation \x201C 2356 # 8220 smart opening double quote
+punctuation \x201D 2356 # 8221 smart closing double quote
+punctuation \x201E 2356 # 8222 smart double low quotation mark
+punctuation \x201F 2356 # 8223 smart double high reverse quotation mark
+punctuation \x2026 3-3-3 # 8230 smart ellipsis
+sign \x20AC 4-15 # 8364 Euro sign
+noback sign \x25CF 16 # 9679 black circle
+
+#-------------------------- Arabic characters ---------------------------------
+sign \x060C 5 # Arabic comma
+sign \x061B 56 # Arabic semicolon
+sign \x061F 236 # Arabic question mark
+
+letter \x0621 345 # Hamza [Peter Engström 2011-03-15]
+letter \x0622 345 # Alef with madda above
+letter \x0623 34 # Alef with hamza above
+letter \x0624 1256 # Waw with hamza above
+letter \x0625 34 # Alef with hamza below [Peter Engström 2011-03-15]
+letter \x0626 345 # Yeh with hamza above
+letter \x0627 1 # Alef
+letter \x0628 12 # Beh
+letter \x0629 16 # Teh marbutha
+letter \x062A 2345 # Teh
+letter \x062B 1456 # Theh
+letter \x062C 245 # Jeem
+letter \x062D 156 # Hah
+letter \x062E 1346 # Khah
+letter \x062F 145 # Dal
+letter \x0630 2346 # Thal
+letter \x0631 246 # Reh [Peter Engström 2011-03-15]
+letter \x0632 1356 # Zain
+letter \x0633 234 # Seen
+letter \x0634 146 # Sheen
+letter \x0635 12346 # Sad
+letter \x0636 1246 # Dad
+letter \x0637 23456 # Tah
+letter \x0638 123456 # Zah
+letter \x0639 12356 # Ain
+letter \x063A 126 # Ghain
+letter \x0640 2 # Tatweel (=kashida inserted to stretch characters).
+letter \x0641 124 # Feh
+letter \x0642 12345 # Qaf
+letter \x0643 13 # Kaf
+letter \x0644 123 # Lam
+letter \x0645 134 # Meem
+letter \x0646 1345 # Noon
+
+#--BEGIN--------------------------------------------[Peter Engström 2011-02-08]
+letter \x0647 15 # Heh
+begword \x0647 125
+midword \x0647 125
+endword \x0647 15
+#--END----------------------------------------------[Peter Engström 2011-02-08]
+
+letter \x0648 2456 # Waw
+letter \x0649 135 # Alef maksura
+letter \x064A 24 # Yeh
+letter \x064B 23 # Fathatan
+letter \x064C 26 # Dammatan
+letter \x064D 35 # Kasratan
+letter \x064E 2 # Fatha
+letter \x064F 136 # Damma
+letter \x0650 15 # Kasra
+letter \x0651 6 # Shadda
+letter \x0652 25 # Sukun
+
+#--BEGIN--------------------------------------------[Peter Engström 2011-02-08]
+sign \x02C7 456 # Caron (=hacek)
+sign \x032C 56 # Combinding caron below
+sign \x065A 456 # Vowel sign small v above
+sign \x0660 356 # 0 Arabic numbers
+sign \x0661 2 # 1
+sign \x0662 23 # 2
+sign \x0663 25 # 3
+sign \x0664 256 # 4
+sign \x0665 26 # 5
+sign \x0666 235 # 6
+sign \x0667 2356 # 7
+sign \x0668 236 # 8
+sign \x0669 35 # 9
+sign \x066C 5 # Arabic thousands separator
+
+letter \x067E 1234 # Peh
+letter \x0686 14 # Tcheh
+letter \x0695 1235 # Reh with small v below
+letter \x0698 346 # Jeh
+letter \x06A4 1236 # Veh
+letter \x06A9 13 # Keheh
+letter \x06AF 1245 # Gaf
+letter \x06B5 123456 # Lam with small v
+letter \x06BE 125 # Heh doachashmee
+letter \x06C1 15 # Heh goal
+letter \x06C6 135 # Oe
+letter \x06CB 1236 # Ve
+letter \x06CC 24 # Farsi Yeh
+letter \x06CE 34 # Yeh with small v
+letter \x06D5 15 # Ae
+letter \xFB8A 346 # Jeh isolated form
+letter \xFBA6 15 # Heh goal isolated form
+letter \xFBAA 125 # Heh doachashmee isolated form
+letter \xFBAB 15 # Heh doachashmee final form
+letter \xFBAC 125 # Heh doachashmee initial form
+letter \xFBAD 125 # Heh doachashmee medial form
+letter \xFBFC 24 # Farsi yeh isolated form
+letter \xFEAD 246 # Reh isolated form
+letter \xFEAE 246 # Reh final form
+letter \xFEDD 123 # Lam isolated form
+letter \xFEDE 123 # Lam final form
+letter \xFEE9 15 # Heh isolated form
+letter \xFEEA 15 # Heh final form
+letter \xFEEB 125 # Heh initial form
+letter \xFEEC 125 # Heh medial form
+letter \xFEEF 24 # Alef maksura isolated form
+letter \xFEFB 123-1 # Ligature lam with alef with hamza below isolated form
+letter \xFEFC 123-1 # Ligature lam with alef with hamza below final form
+
+#--END----------------------------------------------[Peter Engström 2011-02-08]
diff --git a/tables/ckb-g1.ctb b/tables/ckb-g1.ctb
new file mode 100644
index 0000000..1a2c47b
--- /dev/null
+++ b/tables/ckb-g1.ctb
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2011 by Peter Engström <peter.engstrom@indexbraille.com>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# -----------------------------------------------------------------------------
+# SORANI (KURDISH)
+# ================
+# Author: Peter Engström
+# Company: Index Braille
+# ---------------------------------------------------------------------------------------
+
+include ckb-chardefs.cti
+include braille-patterns.cti
+include ckb-translation.cti
+
+# ---------------------------------------------------------------------------------------
diff --git a/tables/ckb-translation.cti b/tables/ckb-translation.cti
new file mode 100644
index 0000000..2887843
--- /dev/null
+++ b/tables/ckb-translation.cti
@@ -0,0 +1,131 @@
+#
+# Copyright (C) 2011 by Peter Engström <peter.engstrom@indexbraille.com>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# -----------------------------------------------------------------------------
+#
+# SORANI (KURDISH)
+# ================
+# Author: Peter Engström
+# Company: Index Braille
+#
+# Date: Note:
+# 2011-02-08 Renamed _translation_ar-g1.ctb and changed first line to access this file.
+# Peter Engström, Index Braille.
+# 2011-03-15 Updated by Peter Engström
+#
+# ---------------------------------------------------------------------------------------
+
+always \x0644\x0627 123-1 #[Peter Engström 2011-02-08]
+always \x0640\x0640\x0640\x064F 136
+always \x0640\x0640\x0640\x064B 23
+always \x0640\x0640\x0640\x064C 26
+
+
+include countries.cti
+#undefined 123456
+
+# Braille indicators
+numsign 3456 number sign, just a dots operand
+multind 56-6 letsign capsletter
+capsletter 6
+begcapsword 6-6
+endcapsword 6-3
+emphclass italic
+emphclass underline
+emphclass bold
+begemph italic 46
+endemph italic 46-46
+begemph bold 456
+endemph bold 456-456
+begcomp 456-346
+endcomp 456-156
+
+# the decimal digits
+include litdigits6Dots.uti
+
+# Letters are defined in en-chardefs
+# punctuation
+
+prepunc ) 356
+postpunc ( 236
+
+prepunc " 236 #[Peter Engström 2011-03-15]
+postpunc " 236 #[Peter Engström 2011-03-15]
+
+prepunc ' 3 #[Peter Engström 2011-03-15]
+postpunc ' 3 #[Peter Engström 2011-03-15]
+word 'em =
+word 'tis =
+word 'twas =
+begnum # 3456 print number sign before number #[Peter Engström 2011-03-15]
+midnum , 46
+postpunc , 46
+decpoint . 46
+midnum - 36
+hyphen - 36
+#capsnocont
+postpunc . 256
+postpunc ; 5 #[Peter Engström 2011-03-15]
+midnum : 5-2 #[Peter Engström 2011-03-15]
+postpunc : 5-2 #[Peter Engström 2011-03-15]
+postpunc ! 235
+midnum / 34
+noback always / 34
+#always < 0-135-0 #[Peter Engström 2011-03-15]
+# always > 0-246-0
+postpunc ? 1456 #[Peter Engström 2011-03-15]
+endnum % 1234 #[Peter Engström 2011-03-15]
+midnum ^ 346 #[Peter Engström 2011-03-15]
+noback always ^ 45 #[Peter Engström 2011-03-15]
+noback always ~ 45
+noback always & 12346 #[Peter Engström 2011-03-15]
+midnum * 16 #[Peter Engström 2011-03-15]
+noback always * 16 #[Peter Engström 2011-03-15]
+noback always [ 13456 #[Peter Engström 2011-03-15]
+noback always ] 12346 #[Peter Engström 2011-03-15]
+noback always { 135 #[Peter Engström 2011-03-15]
+noback always } 246 #[Peter Engström 2011-03-15]
+prepunc ` 6-236
+noback always @ 4
+always \\ 1256 #[Peter Engström 2011-03-15]
+noback always | 1245
+always ... 3-3-3
+always .\s.\s. 3-3-3 . . .
+noback always $ 1246 #[Peter Engström 2011-03-15]
+
+# special character sequences
+compbrl :// URLs
+compbrl www.
+compbrl .com
+compbrl .edu
+compbrl .gov
+compbrl .mil
+compbrl .net
+compbrl .org
+compbrl .doc
+compbrl .htm
+compbrl .html
+compbrl .tex
+compbrl .txt
+compbrl .gif
+compbrl .jpg
+compbrl .png
+compbrl .wav
+compbrl .tar
+compbrl .zip
diff --git a/tables/ckb.tbl b/tables/ckb.tbl
new file mode 100644
index 0000000..373e429
--- /dev/null
+++ b/tables/ckb.tbl
@@ -0,0 +1,18 @@
+#-index-name: Kurdish
+#-display-name: Kurdish braille
+
+#+locale:ckb
+#+type:literary
+#+grade:1
+
+# TODO: Please correct the metadata above. It is not meant to be
+# accurate nor complete. It hasn't been verified by the table
+# author yet. It is merely an attempt by the liblouis maintainers
+# to get some sensible initial values in place.
+
+# TODO: Please add a reference to official documentation about
+# the implemented braille code. Preferably submit the documents
+# to https://github.com/liblouis/braille-specs.
+
+include ckb-g1.ctb
+include braille-patterns.cti
diff --git a/tables/compress.cti b/tables/compress.cti
new file mode 100644
index 0000000..e0c04a3
--- /dev/null
+++ b/tables/compress.cti
@@ -0,0 +1,44 @@
+# Multiple Blank, Tab, etc. Suppression Table
+
+# Based on the Linux screenreader BRLTTY, copyright (C) 1999-2006 by
+# The BRLTTY Team
+#
+# Copyright (C) 2004-2006 ViewPlus Technologies, Inc. www.viewplus.com
+# Copyright (C) 2004-2006 JJB Software, Inc. www.jjb-software.com
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+space \s 0 blank
+space \t 9 tab
+space \x000a 0 newline
+space \x000c 0
+space \x000d 0 carriage return
+space \x001b 1b escape character for html back-translation
+space \x00A0 a NO-BREAK SPACE <noBreak> 0020 NON-BREAKING SPACE
+
+# Sequences which should be represented by blank spaces
+repeated \s 0
+repeated \t 0
+
+# cut down lines of hyphens, underscores, etc.
+repeated --- 36
+repeated ___ 456
+repeated === 123456
+
+#pass2 `$s1-10 ?
+#pass2 $s1-10 @0
+
diff --git a/tables/controlchars.cti b/tables/controlchars.cti
new file mode 100644
index 0000000..951bcb9
--- /dev/null
+++ b/tables/controlchars.cti
@@ -0,0 +1,27 @@
+# liblouis: some control characters
+
+# Based on the Linux screenreader BRLTTY, copyright (C) 1999-2006 by
+# The BRLTTY Team
+#
+# Copyright (C) 2004-2006 ViewPlus Technologies, Inc. www.viewplus.com
+# Copyright (C) 2004-2006 JJB Software, Inc. www.jjb-software.com
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+space \x000a a1 newline
+space \x000c a2 forms feed
+space \x000d a3 carriage return
diff --git a/tables/corrections.cti b/tables/corrections.cti
new file mode 100644
index 0000000..da7dd39
--- /dev/null
+++ b/tables/corrections.cti
@@ -0,0 +1,47 @@
+# liblouis: corrections table
+#
+# Copyright (C) 2009 JJB Software, Inc. www.jjb-software.com
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# Append this table to others to correct scannos, etc.
+
+repeated ____ 456-456-456-456
+repeated ---- 36-36-36-36
+repeated .... 3-3-3-3
+sign \x0094 5
+noback correct "\x0094" "\""
+noback correct "\x00a0" "\s"
+noback correct "\x000a" "\s"
+space \x00ad 0
+noback correct "\x00ad" ?
+noback correct "\x2019" "'"
+space \x0097 0
+noback correct "\x0097" "\s"
+noback correct "(\s" "("
+noback correct "\s)" ")"
+noback correct "cornf" "comf"
+noback correct "cornm" "comm"
+noback correct "cornp" "comp"
+noback correct $p["-"] "\s-\s"
+noback correct "..." *
+noback correct "\s," ","
+noback correct "\s." "."
+noback correct "\s?" "?"
+noback correct "-\"" "--\""
+noback correct [".\s\""]$s ".\""
+noback correct "-"$s ?
diff --git a/tables/countries.cti b/tables/countries.cti
new file mode 100644
index 0000000..f4d3a7d
--- /dev/null
+++ b/tables/countries.cti
@@ -0,0 +1,263 @@
+#
+# Copyright (C) 1995-2004 by The BRLTTY Team. All rights reserved.
+#
+# This file is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This file is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this file; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+# This is free software, placed under the terms of the
+# GNU General Public License, as published by the Free Software
+# Foundation. Please see the file COPYING for details.
+
+# show any "word" which contains a country code in 8-dot computer braille.
+compbrl .ad Andorra
+compbrl .ae United Arab Emirates
+compbrl .af Afghanistan
+compbrl .ag Antigua and Barbuda
+compbrl .ai Anguilla
+compbrl .al Albania
+compbrl .am Armenia
+compbrl .an Netherlands Antilles
+compbrl .ao Angola
+compbrl .aq Antarctica
+compbrl .ar Argentina
+compbrl .as American Samoa
+compbrl .at Austria
+compbrl .au Australia
+compbrl .aw Aruba
+compbrl .az Azerbaijan
+compbrl .ba Bosnia-Herzegovina
+compbrl .bb Barbados
+compbrl .bd Bangladesh
+compbrl .be Belgium
+compbrl .bf Burkina Faso
+compbrl .bg Bulgaria
+compbrl .bh Bahrain
+compbrl .bi Burundi
+compbrl .bj Benin
+compbrl .bm Bermuda
+compbrl .bn Brunei Darussalam
+compbrl .bo Bolivia
+compbrl .br Brazil
+compbrl .bs Bahamas
+compbrl .bt Bhutan
+compbrl .bv Bouvet Island
+compbrl .bw Botswana
+compbrl .by Belarus
+compbrl .bz Belize
+compbrl .ca Canada
+compbrl .cc Cocos (Keeling) Islands
+compbrl .cd The Democratic Republic of The Congo
+compbrl .cf Central African Republic
+compbrl .cg Congo
+compbrl .ch Switzerland
+compbrl .ci Ivory Coast
+compbrl .ck Cook Islands
+compbrl .cl Chile
+compbrl .cm Cameroon
+compbrl .cn China
+compbrl .co Colombia
+compbrl .cr Costa Rica
+compbrl .cu Cuba
+compbrl .cv Cape Verde
+compbrl .cx Christmas Island
+compbrl .cy Cyprus
+compbrl .cz Czech Republic
+compbrl .de Germany
+compbrl .dj Djibouti
+compbrl .dk Denmark
+compbrl .dm Dominica
+compbrl .do Dominican Republic
+compbrl .dz Algeria
+compbrl .ec Ecuador
+compbrl .ee Estonia
+compbrl .eg Egypt
+compbrl .eh Western Sahara
+compbrl .er Eritrea
+compbrl .es Spain
+compbrl .et Ethiopia
+compbrl .fi Finland
+compbrl .fj Fiji
+compbrl .fk Falkland Islands (Malvinas)
+compbrl .fm Micronesia
+compbrl .fo Faroe Islands
+compbrl .fr France
+compbrl .ga Gabon
+compbrl .gb United Kingdom
+compbrl .gd Grenada
+compbrl .ge Georgia
+compbrl .gf French Guiana
+compbrl .gh Ghana
+compbrl .gi Gibraltar
+compbrl .gl Greenland
+compbrl .gm Gambia
+compbrl .gn Guinea
+compbrl .gp Guadeloupe (Fr.)
+compbrl .gq Equatorial Guinea
+compbrl .gr Greece
+compbrl .gs South Georgia And The South Sandwich Islands
+compbrl .gt Guatemala
+compbrl .gu Guam (U.S.)
+compbrl .gw Guinea-Bissau
+compbrl .gy Guyana
+compbrl .hk Hong Kong
+compbrl .hm Heard Island And Mcdonald Islands
+compbrl .hn Honduras
+compbrl .hr Croatia
+compbrl .ht Haiti
+compbrl .hu Hungary
+compbrl .id Indonesia
+compbrl .ie Ireland
+compbrl .il Israel
+compbrl .im Isle of Man
+compbrl .in India
+compbrl .io British Indian Ocean Territory
+compbrl .iq Iraq
+compbrl .ir Iran
+compbrl .is Iceland
+compbrl .it Italy
+compbrl .jm Jamaica
+compbrl .jo Jordan
+compbrl .jp Japan
+compbrl .ke Kenya
+compbrl .kg Kyrgyzstan
+compbrl .kh Cambodia
+compbrl .ki Kiribati
+compbrl .km Comoros
+compbrl .kn Saint Kitts and Nevis
+compbrl .kp Korea (North)
+compbrl .kr Korea (South)
+compbrl .kw Kuwait
+compbrl .ky Cayman Islands
+compbrl .kz Kazakstan
+compbrl .la Lao People's Democratic Republic
+compbrl .lb Lebanon
+compbrl .lc Saint Lucia
+compbrl .li Liechtenstein
+compbrl .lk Sri Lanka
+compbrl .lr Liberia
+compbrl .ls Lesotho
+compbrl .lt Lithuania
+compbrl .lu Luxembourg
+compbrl .lv Latvia
+compbrl .ly Libyan Arab Jamahiriya
+compbrl .ma Morocco
+compbrl .mc Monaco
+compbrl .md Moldova
+compbrl .mg Madagascar
+compbrl .mh Marshall Islands
+compbrl .mk Macedonia
+compbrl .ml Mali
+compbrl .mm Myanmar
+compbrl .mn Mongolia
+compbrl .mo Macau
+compbrl .mp Northern Mariana Islands
+compbrl .mq Martinique
+compbrl .mr Mauritania
+compbrl .ms Montserrat
+compbrl .mt Malta
+compbrl .mu Mauritius
+compbrl .mv Maldives
+compbrl .mw Malawi
+compbrl .mx Mexico
+compbrl .my Malaysia
+compbrl .mz Mozambique
+compbrl .na Namibia
+compbrl .nc New Caledonia (Fr.)
+compbrl .ne Niger
+compbrl .nf Norfolk Island
+compbrl .ng Nigeria
+compbrl .ni Nicaragua
+compbrl .nl Netherlands
+compbrl .no Norway
+compbrl .np Nepal
+compbrl .nr Nauru
+compbrl .nu Niue
+compbrl .nz New Zealand
+compbrl .om Oman
+compbrl .pa Panama
+compbrl .pe Peru
+compbrl .pf Polynesia (Fr.)
+compbrl .pg Papua New Guinea
+compbrl .ph Philippines
+compbrl .pk Pakistan
+compbrl .pl Poland
+compbrl .pm Saint Pierre and Miquelon
+compbrl .pn Pitcairn
+compbrl .pr Puerto Rico (U.S.)
+compbrl .ps Palestinian Territory, Occupied
+compbrl .pt Portugal
+compbrl .pw Palau
+compbrl .py Paraguay
+compbrl .qa Qatar
+compbrl .re Reunion (Fr.)
+compbrl .ro Romania
+compbrl .ru Russia
+compbrl .rw Rwanda
+compbrl .sa Saudi Arabia
+compbrl .sb Solomon Islands
+compbrl .sc Seychelles
+compbrl .sd Sudan
+compbrl .se Sweden
+compbrl .sg Singapore
+compbrl .sh Saint Helena
+compbrl .si Slovenia
+compbrl .sj Svalbard and Jan Mayen
+compbrl .sk Slovakia
+compbrl .sl Sierra Leone
+compbrl .sm San Marino
+compbrl .sn Senegal
+compbrl .so Somalia
+compbrl .sr Suriname
+compbrl .st Sao Tome And Principe
+compbrl .su U.S.S.R.
+compbrl .sv El Salvador
+compbrl .sy Syrian Arab Republic
+compbrl .sz Swaziland
+compbrl .tc Turks And Caicos Islands
+compbrl .td Chad
+compbrl .tf French Southern Territories
+compbrl .tg Togo
+compbrl .th Thailand
+compbrl .tj Tajikistan
+compbrl .tk Tokelau
+compbrl .tm Turkmenistan
+compbrl .tn Tunisia
+compbrl .to Tonga
+compbrl .tp East Timor
+compbrl .tr Turkey
+compbrl .tt Trinidad and Tobago
+compbrl .tv Tuvalu
+compbrl .tw Taiwan
+compbrl .tz Tanzania
+compbrl .ua Ukraine
+compbrl .ug Uganda
+compbrl .uk United Kingdom
+compbrl .um United States Minor Outlying Islands
+compbrl .us United States
+compbrl .uy Uruguay
+compbrl .uz Uzbekistan
+compbrl .va Holy See (Vatican City State)
+compbrl .vc St. Vincent and the Grenadines
+compbrl .ve Venezuela
+compbrl .vg Virgin Islands, British
+compbrl .vi Virgin Islands, U.S.
+compbrl .vn Vietnam
+compbrl .vu Vanuatu
+compbrl .wf Wallis and Futuna
+compbrl .ws Samoa
+compbrl .ye Yemen
+compbrl .yt Mayotte
+compbrl .yu Yugoslavia
+compbrl .za South Africa
+compbrl .zm Zambia
+compbrl .zw Zimbabwe
diff --git a/tables/cs-chardefs.cti b/tables/cs-chardefs.cti
new file mode 100644
index 0000000..e11f247
--- /dev/null
+++ b/tables/cs-chardefs.cti
@@ -0,0 +1,208 @@
+#
+# Copyright (C) 2011 by Bert Frees <bertfrees@gmail.com>
+# Copyright (C) 2011 by Jan Halousek <merit@login.cz>
+# Copyright (C) 2012 by Brailcom, o.p.s.
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# ----------------------------------------------------------------------------------------------
+#
+# Czech Braille
+#
+# Created and maintained by Bert Frees <bertfrees@gmail.com>
+# Jan Halousek <merit@login.cz>
+#
+# Based on the official Czech Braille Standard
+# ----------------------------------------------------------------------------------------------
+
+space \x0009 9 <control> HORIZONTAL TABULATION
+space \x001B 1b <control> ESCAPE
+space \x00A0 a NO-BREAK SPACE
+include spaces.uti
+
+# ==============================================================================================
+# SINGLE-CELL
+# ==============================================================================================
+
+include cs-letterDef8Dots.uti
+
+uplow \x013D\x013E 1234567,123456 Ľľ LATIN CAPITAL LETTER L WITH CARON - LATIN SMALL LETTER L WITH CARON
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 0000..007F C0 Controls and Basic Latin
+# ----------------------------------------------------------------------------------------------
+
+punctuation \x0021 235 ! EXCLAMATION MARK
+punctuation \x0022 2356 " QUOTATION MARK
+sign \x0023 6-3456 # NUMBER SIGN
+punctuation \x0027 4 ' APOSTROPHE
+punctuation \x0028 236 ( LEFT PARENTHESIS
+punctuation \x0029 356 ) RIGHT PARENTHESIS
+sign \x002A 35 * ASTERISK
+math \x002B 256 + PLUS SIGN
+punctuation \x002C 2 , COMMA
+punctuation \x002D 36 - HYPHEN-MINUS
+punctuation \x002E 3 . FULL STOP
+math \x002F 12456 / SOLIDUS
+include digits6Dots.uti
+punctuation \x003A 25 : COLON
+punctuation \x003B 23 ; SEMICOLON
+math \x003C 126 < LESS-THAN SIGN
+math \x003D 2356 = EQUALS SIGN
+math \x003E 345 > GREATER-THAN SIGN
+punctuation \x003F 26 ? QUESTION MARK
+sign \x007C 456 | VERTICAL LINE
+
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 0080..00FF C1 Controls and Latin-1 Supplement
+# ----------------------------------------------------------------------------------------------
+
+sign \x00A9 1246-2456-6-14 © COPYRIGHT SIGN
+punctuation \x00AD 36 SOFT HYPHEN
+math \x00B1 256-36 ± PLUS-MINUS SIGN
+sign \x00B4 4 ´ ACUTE ACCENT
+math \x00D7 346 × MULTIPLICATION SIGN
+math \x00F7 25 ÷ DIVISION SIGN
+
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 2000..206F General Punctuation
+# ----------------------------------------------------------------------------------------------
+
+punctuation \x2010 36 ‐ HYPHEN
+punctuation \x2011 36 ‑ NON-BREAKING HYPHEN
+punctuation \x2012 36 ‒ FIGURE DASH
+punctuation \x2013 36 – EN DASH
+punctuation \x2014 36 — EM DASH
+punctuation \x2015 36 ― HORIZONTAL BAR
+punctuation \x2018 4 ‘ LEFT SINGLE QUOTATION MARK
+punctuation \x2019 4 ’ RIGHT SINGLE QUOTATION MARK
+punctuation \x201A 4 ‚ SINGLE LOW-9 QUOTATION MARK
+punctuation \x201B 4 ‛ SINGLE HIGH-REVERSED-9 QUOTATION MARK
+punctuation \x201C 2356 “ LEFT DOUBLE QUOTATION MARK
+punctuation \x201D 2356 ” RIGHT DOUBLE QUOTATION MARK
+punctuation \x201E 2356 „ DOUBLE LOW-9 QUOTATION MARK
+punctuation \x201F 2356 ‟ DOUBLE HIGH-REVERSED-9 QUOTATION MARK
+
+
+# ==============================================================================================
+# MULTI-CELL
+# ==============================================================================================
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 0000..007F C0 Controls and Basic Latin
+# ----------------------------------------------------------------------------------------------
+
+sign \x0024 3456-1246 $ DOLLAR SIGN
+math \x0025 3456-1234 % PERCENT SIGN
+sign \x0026 3456-12346 & AMPERSAND
+sign \x0040 3456-12456 @ COMMERCIAL AT
+punctuation \x005B 6-236 [ LEFT SQUARE BRACKET
+sign \x005C 3456-1256 \ REVERSE SOLIDUS
+punctuation \x005D 6-356 ] RIGHT SQUARE BRACKET
+sign \x005E 6-45 ^ CIRCUMFLEX ACCENT
+sign \x005F 6-36 _ LOW LINE
+punctuation \x0060 45-4 ` GRAVE ACCENT
+math \x007B 46-236 { LEFT CURLY BRACKET
+math \x007D 46-356 } RIGHT CURLY BRACKET
+math \x007E 6-5 ~ TILDE
+sign \x007F 6-3 DELETE
+
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 0080..00FF C1 Controls and Latin-1 Supplement
+# ----------------------------------------------------------------------------------------------
+
+sign \x0080 15-136-1235-135 € <control> - ANSI: EURO-CURRENCY SIGN - MACROMAN: A DIAERESIS
+sign \x00B0 3456-234 ° DEGREE SIGN
+sign \x00B5 4-134 µ MICRO SIGN
+math \x00B9 34-1 ¹ SUPERSCRIPT ONE
+uplow \x00C4\x00E4 1-15,1-15 Ää LATIN CAPITAL LETTER A WITH DIAERESIS - LATIN SMALL LETTER A WITH DIAERESIS
+uplow \x00D6\x00F6 135-15,135-15 Öö LATIN CAPITAL LETTER O WITH DIAERESIS - LATIN SMALL LETTER O WITH DIAERESIS
+uplow \x00DC\x00FC 136-15,136-15 Üü LATIN CAPITAL LETTER U WITH DIAERESIS - LATIN SMALL LETTER U WITH DIAERESIS
+
+
+# ----------------------------------------------------------------------------------------------
+# Unicode 0370..03FF Greek and Coptic
+# ----------------------------------------------------------------------------------------------
+
+letter \x0391 46-1 Α GREEK CAPITAL LETTER ALPHA
+letter \x0392 46-12 Β GREEK CAPITAL LETTER BETA
+letter \x0393 46-1245 Γ GREEK CAPITAL LETTER GAMMA
+letter \x0394 46-145 Δ GREEK CAPITAL LETTER DELTA
+letter \x0395 46-15 Ε GREEK CAPITAL LETTER EPSILON
+letter \x0398 46-1456 Θ GREEK CAPITAL LETTER THETA
+letter \x0399 46-24 Ι GREEK CAPITAL LETTER IOTA
+letter \x039A 46-13 Κ GREEK CAPITAL LETTER KAPPA
+letter \x039B 46-123 Λ GREEK CAPITAL LETTER LAMDA
+letter \x039C 46-134 Μ GREEK CAPITAL LETTER MU
+letter \x039D 46-1345 Ν GREEK CAPITAL LETTER NU
+letter \x039E 46-1346 Ξ GREEK CAPITAL LETTER XI
+letter \x039F 46-135 Ο GREEK CAPITAL LETTER OMICRON
+letter \x03A0 46-1234 Π GREEK CAPITAL LETTER PI
+letter \x03A1 46-1235 Ρ GREEK CAPITAL LETTER RHO
+letter \x03A3 46-234 Σ GREEK CAPITAL LETTER SIGMA
+letter \x03A4 46-2345 Τ GREEK CAPITAL LETTER TAU
+letter \x03A5 46-13456 Υ GREEK CAPITAL LETTER UPSILON
+letter \x03A6 46-124 Φ GREEK CAPITAL LETTER PHI
+letter \x03A7 46-125 Χ GREEK CAPITAL LETTER CHI
+letter \x03A8 46-12346 Ψ GREEK CAPITAL LETTER PSI
+letter \x03A9 46-2356 Ω GREEK CAPITAL LETTER OMEGA
+
+lowercase \x03B1 45-1 α GREEK SMALL LETTER ALPHA
+lowercase \x03B2 45-12 β GREEK SMALL LETTER BETA
+lowercase \x03B3 45-1245 γ GREEK SMALL LETTER GAMMA
+lowercase \x03B4 45-145 δ GREEK SMALL LETTER DELTA
+lowercase \x03B5 45-15 ε GREEK SMALL LETTER EPSILON
+lowercase \x03B8 45-1456 θ GREEK SMALL LETTER THETA
+lowercase \x03B9 45-24 ι GREEK SMALL LETTER IOTA
+lowercase \x03BA 45-13 κ GREEK SMALL LETTER KAPPA
+lowercase \x03BB 45-123 λ GREEK SMALL LETTER LAMDA
+lowercase \x03BC 45-134 μ GREEK SMALL LETTER MU
+lowercase \x03BD 45-1345 ν GREEK SMALL LETTER NU
+lowercase \x03BE 45-1346 ξ GREEK SMALL LETTER XI
+lowercase \x03BF 45-135 ο GREEK SMALL LETTER OMICRON
+lowercase \x03C0 45-1234 π GREEK SMALL LETTER PI
+lowercase \x03C1 45-1235 ρ GREEK SMALL LETTER RHO
+lowercase \x03C3 45-234 σ GREEK SMALL LETTER SIGMA
+lowercase \x03C4 45-2345 τ GREEK SMALL LETTER TAU
+lowercase \x03C5 45-13456 υ GREEK SMALL LETTER UPSILON
+lowercase \x03C6 45-124 φ GREEK SMALL LETTER PHI
+lowercase \x03C7 45-125 χ GREEK SMALL LETTER CHI
+lowercase \x03C8 45-12346 ψ GREEK SMALL LETTER PSI
+lowercase \x03C9 45-2356 ω GREEK SMALL LETTER OMEGA
+
+# ----------------------------------------------------------------------------------------------
+# Other Unicode characters
+# ----------------------------------------------------------------------------------------------
+
+math \x2030 3456-1235 ‰ PER MILLE SIGN
+math \x0609 3456-1235 ؉ ARABIC-INDIC PER MILLE SIGN
+math \x27E8 4-126 ⟨ MATHEMATICAL LEFT ANGLE BRACKET
+math \x27E9 4-345 ⟩ MATHEMATICAL RIGHT ANGLE BRACKET
+math \x2260 4-2356 ≠ NOT EQUAL TO
+math \x2250 5-2356 ≐ APPROACHES THE LIMIT
+math \x2264 126-2356 ≤ LESS-THAN OR EQUAL TO
+math \x2265 345-2356 ≥ GREATER-THAN OR EQUAL TO
+math \x22C5 3 ⋅ DOT OPERATOR
+math \x2217 35 ∗ ASTERISK OPERATOR
+math \x2236 25 ∶ RATIO
+math \x2208 45-15 ∈ ELEMENT OF
+math \x2209 4-45-15 ∉ NOT AN ELEMENT OF
+
+# ----------------------------------------------------------------------------------------------
diff --git a/tables/cs-comp8.utb b/tables/cs-comp8.utb
new file mode 100644
index 0000000..9193b65
--- /dev/null
+++ b/tables/cs-comp8.utb
@@ -0,0 +1,312 @@
+# liblouis: Czech 8-dot Computer Braille Table
+
+#-index-name: Czech, computer
+#-display-name: Czech computer braille
+#
+#+locale:cs
+#+type:computer
+#+grade:0
+#+dots:8
+#
+# Copyright (C) 2011, 2018 Jan Hegr <hegrjan@gmail.com>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# Based on the official Czech Braille Standard and Czech8.bwe (Window-Eyes Braille table)
+# Implements basic math symbols described at:
+# http://teiresias.muni.cz/czbraille8/?strana=norma
+
+include digits8Dots.uti
+include cs-letterDef8Dots.uti
+
+sign \x0000 9
+sign \x0001 178
+sign \x0002 1278
+sign \x0003 1478
+sign \x0004 14578
+sign \x0005 1578
+sign \x0006 12478
+sign \x0007 124578
+sign \x0008 12578
+space \t 9 # tab
+sign \x000a 24578
+sign \x000b 1378
+sign \x000c 134568
+space \n 13478
+sign \x000e 134578
+sign \x000f 13578
+sign \x0010 123478
+sign \x0011 1234578
+sign \x0012 123578
+sign \x0013 23478
+sign \x0014 234578
+sign \x0015 13678
+sign \x0016 123678
+sign \x0017 245678
+sign \x0018 134678
+sign \x0019 1345678
+sign \x001a 135678
+sign \x001b 24678
+sign \x001c 125678
+sign \x001d 1245678
+sign \x001e 4578
+sign \x001f 45678
+space \s 0
+punctuation ! 235
+punctuation " 2356
+sign # 34567
+sign $ 2358
+sign % 12348
+sign & 23578
+punctuation ' 4
+punctuation ( 236
+punctuation ) 356
+sign * 35
+math + 256
+punctuation , 2
+punctuation - 36
+punctuation . 3
+math / 12456
+punctuation : 25
+punctuation ; 23
+math < 238
+math = 235678
+math > 567
+punctuation ? 26
+sign @ 124568
+punctuation [ 2367
+sign \\ 2368
+punctuation ] 3568
+sign ^ 457
+sign _ 367
+sign ` 478
+punctuation { 23678
+sign | 4568
+punctuation } 35678
+math ~ 57
+sign \x007f 37
+space \x00a0 a # Non-breaking space
+sign \x00a4 24578
+sign \x00a6 4568
+sign \x00a7 3468
+sign \x00a8 56
+sign \x00a9 1478
+sign \x00ab 348
+math \x00ac 568 # not
+sign \x00ad 368
+sign \x00ae 145678
+sign \x00b0 2348
+math \x00b1 256-36 # plus-minus
+sign \x00b4 3456
+sign \x00b5 45-134
+sign \x00b6 12345678
+sign \x00b7 6
+sign \x00b8 7
+sign \x00bb 467
+sign \x00c2 134678
+sign \x00c4 34578
+sign \x00c7 5678
+sign \x00cb 14578
+sign \x00ce 245678
+uplow \x00d4\x00f4 12678,1268 # o with circumflex
+sign \x00d6 24678
+math \x00d7 3 # times
+sign \x00dc 125678
+sign \x00df 1278
+sign \x00e2 135678
+sign \x00e4 3458
+sign \x00e7 568
+sign \x00eb 15678
+sign \x00ee 24568
+sign \x00f6 2468
+math \x00f7 25 # division
+sign \x00fc 12568
+sign \x0102 124578
+sign \x0103 124568
+sign \x0104 12478
+sign \x0105 12578
+sign \x0106 14678
+sign \x0107 1468
+sign \x0110 2357
+sign \x0111 2378
+sign \x0118 4567
+sign \x0119 4578
+uplow \x0139\x013a 4678,468 # l with acute
+sign \x013a 468
+uplow \x013d\x013e 1378,138 # l with caron
+sign \x0141 2567
+sign \x0142 2568
+sign \x0143 134578
+sign \x0144 13458
+sign \x0150 13578
+sign \x0151 13568
+uplow \x0154\x0155 123578,12358 # r with acute
+sign \x015a 124678
+sign \x015b 123458
+sign \x015e 23478
+sign \x015f 23458
+sign \x0162 234578
+sign \x0163 234568
+sign \x0170 13478
+sign \x0171 13678
+sign \x0179 3478
+sign \x017a 3578
+sign \x017b 123478
+sign \x017c 123468
+sign \x02c7 178
+sign \x02d8 1578
+sign \x02d9 5
+sign \x02db 45678
+sign \x02dd 23568
+letter \x0391 45-17 # Alpha
+letter \x0392 45-127 # Beta
+letter \x0393 45-12457 # Gama
+letter \x0394 45-1457 # Delta
+letter \x0395 45-157 # Epsilon
+letter \x0396 45-13567 # Zeta
+letter \x0397 45-3457 # Eta
+letter \x0398 45-1257 # Theta
+letter \x0399 45-247 # Iota
+letter \x039a 45-137 # Kappa
+letter \x039b 45-1237 # Lambda
+letter \x039c 45-1347 # Mu
+letter \x039d 45-13457 # Nu
+letter \x039e 45-13467 # Xi
+letter \x039f 45-135 # Omicron
+letter \x03a0 45-12347 # Pi
+letter \x03a1 45-12357 # Rho
+letter \x03a3 45-2347 # Sigma
+letter \x03a4 45-23457 # Tau
+letter \x03a5 45-134567 # Upsilon
+letter \x03a6 45-1247 # Phi
+letter \x03a7 45-147 # Chi
+letter \x03a8 45-123467 # Psi
+letter \x03a9 45-24567 # Omega
+letter \x03b1 45-1 # alpha
+letter \x03b2 45-12 # beta
+letter \x03b3 45-1245 # gama
+letter \x03b4 45-145 # delta
+letter \x03b5 45-15 # epsilon
+letter \x03b6 45-1356 # zeta
+letter \x03b7 45-345 # eta
+letter \x03b8 45-125 # theta
+letter \x03b9 45-24 # iota
+letter \x03ba 45-13 # kappa
+letter \x03bb 45-123 # lambda
+letter \x03bc 45-134 # mu
+letter \x03bd 45-1345 # nu
+letter \x03be 45-1346 # xi
+letter \x03bf 45-135 # omicron
+letter \x03c0 45-1234 # pi
+letter \x03c1 45-1235 # rho
+letter \x03c3 45-234 # sigma
+letter \x03c4 45-2345 # tau
+letter \x03c5 45-13456 # upsilon
+letter \x03c6 45-124 # phi
+letter \x03c7 45-14 # chi
+letter \x03c8 45-12346 # psi
+letter \x03c9 45-2456 # omega
+sign \x2010 36 # hyphen
+sign \x2011 36 # non-breaking hyphen
+sign \x2012 36 # dash
+sign \x2013 36 # dash
+sign \x2014 36 # dash
+sign \x2018 45
+sign \x2019 46
+sign \x201a 68
+sign \x201c 2356
+sign \x201d 2356
+sign \x201e 378
+sign \x2020 14568
+sign \x2021 1234567
+sign \x2022 58
+sign \x2026 67
+sign \x2030 12358 # per mille
+sign \x2030 1345678
+sign \x2039 278
+sign \x203a 578
+math \x2044 12456 # fraction slash
+sign \x20ac 234568 # euro sign
+sign \x20ae 358
+sign \x2122 123456
+sign \x2126 45-24567 # Ohm
+sign \x2135 178 # alef symbol
+sign \x2190 258 # left arrow
+sign \x2191 67 # up arrow
+sign \x2192 267 # right arrow
+sign \x2193 38 # down arrow
+sign \x2194 358-267 # left-right arrow
+math \x2200 12368 # for all
+math \x2201 56-147 # complement
+math \x2203 1348 # there exists
+math \x2204 48-1348 # there doesn't exist
+math \x2205 13568 # empty set
+sign \x2207 24568 # nabla
+math \x2208 1578 # element of
+math \x2209 48-1578 # not an element of
+math \x2212 36 # minus sign
+math \x2213 36-256 # minus or plus
+math \x2215 12456 # division slash
+math \x2216 56-36 # set minus
+math \x2217 35 # asterisk operator
+math \x221a 258 # square root
+math \x221d 2345678 # proportional to
+math \x221e 13458 # infinity
+math \x2220 2468 # angle
+math \x2223 4568 # divides
+math \x2225 12345678 # parallel
+math \x2226 48-12345678 # not parallel
+math \x2227 678 # logical and
+math \x2228 368 # logical or
+math \x2229 56-256 # intersection
+math \x222a 56-356 # union
+math \x222b 3578 # integral
+math \x2245 1235678 # approximately equal to
+math \x224d 58-235678 # equivalent to
+math \x2258 46-235678 # corresponds to
+math \x2260 48-235678 # not equal to
+math \x2264 238-235678 # less-than or equal to
+math \x2265 567-235678 # greater-than or equal to
+math \x226a 238-238 # much less-than
+math \x226b 567-567 # much greater-than
+math \x227a 46-238 # precedes
+math \x227b 46-567 # succeeds
+math \x2282 56-23578 # subset of
+math \x2284 48-56-23578 # not a subset of
+math \x2286 56-23578-235678 # subset of or equal to
+math \x2288 48-56-23578-235678 # neither a subset of nor equal to
+math \x22a8 23457 # true
+math \x22ad 1247 # not true
+math \x22bb 46-678 # xor
+math \x22c5 3 # dot operator
+math \x2312 46-2468 # arc
+math \x2329 138 # left angle bracket
+math \x232a 467 # right angle bracket
+sign \x2554 4
+sign \x2557 45
+sign \x255a 6
+sign \x255d 56
+sign \x255f 23
+sign \x2562 56
+sign \x25cf 35 # black circle
+math \x2715 578 # multiplication x
+math \x27c2 34568 # perpendicular
+math \x2a2f 578 # vector or cross product
+
+undefined 26
+
+include braille-patterns.cti
diff --git a/tables/cs-g1.ctb b/tables/cs-g1.ctb
new file mode 100644
index 0000000..695caa9
--- /dev/null
+++ b/tables/cs-g1.ctb
@@ -0,0 +1,37 @@
+#
+# Copyright (C) 2011 by Bert Frees <bertfrees@gmail.com>
+# Copyright (C) 2011 by Jan Halousek <merit@login.cz>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#--------------------------------------------------------------------------------
+#
+# Czech Braille
+#
+# Created and maintained by Bert Frees <bertfrees@gmail.com>
+# Jan Halousek <merit@login.cz>
+#
+# Based on the official Czech Braille Standard
+# -------------------------------------------------------------------------------
+
+include cs-chardefs.cti
+include braille-patterns.cti
+include cs-translation.cti
+
+undefined 26
+
+# -------------------------------------------------------------------------------
diff --git a/tables/cs-letterDef8Dots.uti b/tables/cs-letterDef8Dots.uti
new file mode 100644
index 0000000..9f1de0e
--- /dev/null
+++ b/tables/cs-letterDef8Dots.uti
@@ -0,0 +1,66 @@
+# liblouis: sub table for Czech Latin letter definition, 8 dots.
+#
+# Copyright (C) 2012-2014 Mesar Hameed <mesar.hameed@gmail.com>
+# Copyright (C) 2018 Jan Hegr <hegrjan@gmail.com>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# Note that this table does not simply include latinLetterDef8Dots.uti
+# because latinLetterDef8Dots defines "w" as 2456, but in Czech 2456
+# is used for "ř" and "w" is mapped to 12356.
+
+uplow \x0041\x0061 17,1 Aa LATIN CAPITAL LETTER A - LATIN SMALL LETTER A
+uplow \x00C1\x00E1 167,16 Áá LATIN CAPITAL LETTER A WITH ACUTE - LATIN SMALL LETTER A WITH ACUTE
+uplow \x0042\x0062 127,12 Bb LATIN CAPITAL LETTER B - LATIN SMALL LETTER B
+uplow \x0043\x0063 147,14 Cc LATIN CAPITAL LETTER C - LATIN SMALL LETTER C
+uplow \x010C\x010D 1467,146 Čč LATIN CAPITAL LETTER C WITH CARON - LATIN SMALL LETTER C WITH CARON
+uplow \x0044\x0064 1457,145 Dd LATIN CAPITAL LETTER D - LATIN SMALL LETTER D
+uplow \x010E\x010F 14567,1456 Ďď LATIN CAPITAL LETTER D WITH CARON - LATIN SMALL LETTER D WITH CARON
+uplow \x0045\x0065 157,15 Ee LATIN CAPITAL LETTER E - LATIN SMALL LETTER E
+uplow \x00C9\x00E9 3457,345 Éé LATIN CAPITAL LETTER E WITH ACUTE - LATIN SMALL LETTER E WITH ACUTE
+uplow \x011A\x011B 1267,126 Ěě LATIN CAPITAL LETTER E WITH CARON - LATIN SMALL LETTER E WITH CARON
+uplow \x0046\x0066 1247,124 Ff LATIN CAPITAL LETTER F - LATIN SMALL LETTER F
+uplow \x0047\x0067 12457,1245 Gg LATIN CAPITAL LETTER G - LATIN SMALL LETTER G
+uplow \x0048\x0068 1257,125 Hh LATIN CAPITAL LETTER H - LATIN SMALL LETTER H
+uplow \x0049\x0069 247,24 Ii LATIN CAPITAL LETTER I - LATIN SMALL LETTER I
+uplow \x00CD\x00ED 347,34 Íí LATIN CAPITAL LETTER I WITH ACUTE - LATIN SMALL LETTER I WITH ACUTE
+uplow \x004A\x006A 2457,245 Jj LATIN CAPITAL LETTER J - LATIN SMALL LETTER J
+uplow \x004B\x006B 137,13 Kk LATIN CAPITAL LETTER K - LATIN SMALL LETTER K
+uplow \x004C\x006C 1237,123 Ll LATIN CAPITAL LETTER L - LATIN SMALL LETTER L
+uplow \x004D\x006D 1347,134 Mm LATIN CAPITAL LETTER M - LATIN SMALL LETTER M
+uplow \x004E\x006E 13457,1345 Nn LATIN CAPITAL LETTER N - LATIN SMALL LETTER N
+uplow \x0147\x0148 12467,1246 Ňň LATIN CAPITAL LETTER N WITH CARON - LATIN SMALL LETTER N WITH CARON
+uplow \x004F\x006F 1357,135 Oo LATIN CAPITAL LETTER O - LATIN SMALL LETTER O
+uplow \x00D3\x00F3 2467,246 Óó LATIN CAPITAL LETTER O WITH ACUTE - LATIN SMALL LETTER O WITH ACUTE
+uplow \x0050\x0070 12347,1234 Pp LATIN CAPITAL LETTER P - LATIN SMALL LETTER P
+uplow \x0051\x0071 123457,12345 Qq LATIN CAPITAL LETTER Q - LATIN SMALL LETTER Q
+uplow \x0052\x0072 12357,1235 Rr LATIN CAPITAL LETTER R - LATIN SMALL LETTER R
+uplow \x0158\x0159 24567,2456 Řř LATIN CAPITAL LETTER R WITH CARON - LATIN SMALL LETTER R WITH CARON
+uplow \x0053\x0073 2347,234 Ss LATIN CAPITAL LETTER S - LATIN SMALL LETTER S
+uplow \x0160\x0161 1567,156 Šš LATIN CAPITAL LETTER S WITH CARON - LATIN SMALL LETTER S WITH CARON
+uplow \x0054\x0074 23457,2345 Tt LATIN CAPITAL LETTER T - LATIN SMALL LETTER T
+uplow \x0164\x0165 12567,1256 Ťť LATIN CAPITAL LETTER T WITH CARON - LATIN SMALL LETTER T WITH CARON
+uplow \x0055\x0075 1367,136 Uu LATIN CAPITAL LETTER U - LATIN SMALL LETTER U
+uplow \x00DA\x00FA 3467,346 Úú LATIN CAPITAL LETTER U WITH ACUTE - LATIN SMALL LETTER U WITH ACUTE
+uplow \x016E\x016F 234567,23456 Ůů LATIN CAPITAL LETTER U WITH RING ABOVE - LATIN SMALL LETTER U WITH RING ABOVE
+uplow \x0056\x0076 12367,1236 Vv LATIN CAPITAL LETTER V - LATIN SMALL LETTER V
+uplow \x0057\x0077 123567,12356 Ww LATIN CAPITAL LETTER W - LATIN SMALL LETTER W
+uplow \x0058\x0078 13467,1346 Xx LATIN CAPITAL LETTER X - LATIN SMALL LETTER X
+uplow \x0059\x0079 134567,13456 Yy LATIN CAPITAL LETTER Y - LATIN SMALL LETTER Y
+uplow \x00DD\x00FD 123467,12346 Ýý LATIN CAPITAL LETTER Y WITH ACUTE - LATIN SMALL LETTER Y WITH ACUTE
+uplow \x005A\x007A 13567,1356 Zz LATIN CAPITAL LETTER Z - LATIN SMALL LETTER Z
+uplow \x017D\x017E 23467,2346 Žž LATIN CAPITAL LETTER Z WITH CARON - LATIN SMALL LETTER Z WITH CARON
diff --git a/tables/cs-translation.cti b/tables/cs-translation.cti
new file mode 100644
index 0000000..75fe283
--- /dev/null
+++ b/tables/cs-translation.cti
@@ -0,0 +1,63 @@
+#
+# Copyright (C) 2011 by Bert Frees <bertfrees@gmail.com>
+# Copyright (C) 2011 by Jan Halousek <merit@login.cz>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# ----------------------------------------------------------------------------------------------
+#
+# Czech Braille
+#
+# Created and maintained by Bert Frees <bertfrees@gmail.com>
+# Jan Halousek <merit@login.cz>
+#
+# Based on the official Czech Braille Standard
+# ----------------------------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------------------------
+# Braille indicator opcodes
+# ----------------------------------------------------------------------------------------------
+
+numsign 3456
+capsletter 6
+begcapsword 56
+endcapsword 5
+
+# ----------------------------------------------------------------------------------------------
+# Literary digits
+# ----------------------------------------------------------------------------------------------
+
+include litdigits6Dots.uti
+
+# ----------------------------------------------------------------------------------------------
+# Decimal points, hyphens
+# ----------------------------------------------------------------------------------------------
+
+decpoint \x002C 2
+decpoint \x002E 3
+hyphen \x002D 36
+
+# ----------------------------------------------------------------------------------------------
+# Letter prefix in numbers
+# ----------------------------------------------------------------------------------------------
+
+class digitletter abcdefghij
+noback context $d[]%digitletter @5
+noback context $d"."[]%digitletter @5
+noback context $d","[]%digitletter @5
+
+# ----------------------------------------------------------------------------------------------
diff --git a/tables/cs.tbl b/tables/cs.tbl
new file mode 100644
index 0000000..9ad9da7
--- /dev/null
+++ b/tables/cs.tbl
@@ -0,0 +1,17 @@
+#-index-name: Czech
+#-display-name: Czech braille
+
+#+locale:cs
+#+type:literary
+#+grade:1
+
+# TODO: Please correct the metadata above. It is not meant to be
+# accurate nor complete. It hasn't been verified by the table
+# author yet. It is merely an attempt by the liblouis maintainers
+# to get some sensible initial values in place.
+
+# TODO: Please add a reference to official documentation about
+# the implemented braille code. Preferably submit the documents
+# to https://github.com/liblouis/braille-specs.
+
+include cs-g1.ctb
diff --git a/tables/cy-cy-g1.utb b/tables/cy-cy-g1.utb
new file mode 100644
index 0000000..e599ec8
--- /dev/null
+++ b/tables/cy-cy-g1.utb
@@ -0,0 +1,458 @@
+# liblouis: Welsh Grade 1 table
+#
+# ------------
+#-index-name: Welsh, uncontracted
+#-display-name: Welsh uncontracted braille
+#
+#+locale:cy
+#+type:literary
+#+contraction:no
+#+grade:1
+#
+# TODO: Please correct the metadata above. It is not meant to be
+# accurate nor complete. It hasn't been verified by the table
+# author yet. It is merely an attempt by the liblouis maintainers
+# to get some sensible initial values in place.
+#
+# TODO: Please add a reference to official documentation about
+# the implemented braille code. Preferably submit the documents
+# to https://github.com/liblouis/braille-specs.
+# ------------
+
+# Based on the braille contraction modules in BRLTTY
+#
+# Copyright (C) 1995-2004 by The BRLTTY Team.
+# Copyright (C) 2004 ViewPlus Technologies, inc., www.viewplustech.com
+# Copyright (C) 2004 Computers to Help People, Inc., www.chpi.org
+
+# This file is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This file is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this file; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+include text_nabcc.dis All display opcodes
+
+space \t 9 tab
+space \x001b 1b escape character for html back-translation
+space \x00A0 a NO-BREAK SPACE <noBreak> 0020 NON-BREAKING SPACE
+include spaces.uti
+
+include loweredDigits6Dots.uti
+include latinLetterDef8Dots.uti
+
+punctuation ( 12356
+punctuation } 12456
+punctuation ] 124567
+punctuation ? 1456
+punctuation : 156
+punctuation ) 23456
+punctuation ! 2346
+punctuation { 246
+punctuation [ 2467
+punctuation ' 3
+punctuation - 36
+punctuation . 46
+punctuation " 5
+punctuation ; 56
+punctuation , 6
+sign & 12346
+sign $ 1246
+sign | 1256
+sign \\ 12567
+sign % 146
+sign * 16
+sign # 3456
+punctuation ` 4
+sign _ 456
+sign ^ 457
+sign @ 47
+math = 123456
+math < 126
+math / 34
+math > 345
+math + 346
+math ~ 45
+
+# Miscellaneous
+math \x00B1 346-36 PLUS-MINUS SIGN PLUS-OR-MINUS SIGN
+math \x00B7 16 MIDDLE DOT
+math \x00BC 1456-2-34-256-3456 VULGAR FRACTION ONE QUARTER No 0031 2044
+math \x00BD 1456-2-34-23-3456 VULGAR FRACTION ONE HALF No 0031 2044 0032
+math \x00BE 1456-25-34-23-3456 VULGAR FRACTION THREE QUARTERS No 0033
+math \x00D7 4-16 MULTIPLICATION SIGN
+math \x00F7 46-34 DIVISION SIGN
+punctuation \x0092 3
+punctuation \x0097 36-36
+punctuation \x00A1 235 INVERTED EXCLAMATION MARK
+punctuation \x00ad 36
+punctuation \x00BF 236 INVERTED QUESTION MARK
+punctuation \x2011 36
+punctuation \x2013 36-36
+punctuation \x2014 36-36
+punctuation \x2018 6-236
+punctuation \x2019 3
+punctuation \x2019 356-3
+punctuation \x201c 236
+punctuation \x201d 356
+punctuation \x2026 3
+sign \x2122 45-2345 trademark sign
+sign \x00A2 4-14 CENT SIGN
+sign \x00A3 3456 POUND SIGN
+sign \x00A4 1246 CURRENCY SIGN
+sign \x00A7 4-234 SECTION SIGN
+sign \x00A9 45-14 COPYRIGHT SIGN
+sign \x00AE 45-1235 REGISTERED SIGN REGISTERED TRADE MARK SIGN
+sign \x00B0 56-145-1245 DEGREE SIGN
+sign \x00B4 b4 ACUTE ACCENT 0020 0301 SPACING ACUTE
+sign \x00B5 46-134 MICRO SIGN 03BC 039C 039C
+sign \x00A5 4-13456 YEN SIGN
+punctuation \x00A6 456-1256 BROKEN BAR BROKEN VERTICAL BAR
+# sign \x00A8 DIAERESIS 0020 0308 SPACING DIAERESIS
+# sign \x00AA FEMININE ORDINAL INDICATOR 0061
+# punctuation \x00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK LEFT
+# sign \x00AC NOT SIGN
+# sign \x00AF MACRON 0020 0304 SPACING MACRON
+# math \x00B2 SUPERSCRIPT TWO 0032 2 2 SUPERSCRIPT DIGIT TWO
+# math \x00B3 SUPERSCRIPT THREE 0033 3 3 SUPERSCRIPT DIGIT THREE
+sign \x00B6 1234-345 PILCROW SIGN PARAGRAPH SIGN
+# sign \x00B8 CEDILLA 0020 0327 SPACING CEDILLA
+# math \x00B9 SUPERSCRIPT ONE 0031 1 1 SUPERSCRIPT DIGIT ONE
+sign \x00BA 145-1245 MASCULINE ORDINAL INDICATOR 006F
+# punctuation \x00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK Pf Y
+
+punctuation \x2010 36 # 8208 hyphen
+punctuation \x201F 356 # 8223 smart double high reverse quotation mark
+punctuation \x201E 236 # 8222 smart double low quotation mark
+
+noback sign \x25CF 16 black circle
+
+# Braille indicators
+numsign 3456 number sign, just a dots operand
+multind 56-6 letsign capsletter
+letsign 56
+capsletter 6
+begcapsword 6-6
+endcapsword 6-3
+emphclass italic
+emphclass underline
+emphclass bold
+begemph italic 46
+endemph italic 46-3
+begemph bold 46-46
+endemph bold 46-3
+begcomp 6-346
+endcomp 6-346
+
+# the decimal digits
+include litdigits6Dots.uti
+
+# Letters not defined in en-chardefs
+always ch 16
+always th 1456
+
+#single letter words
+word a 1
+word A 1
+word i 24
+word I 24
+word o 135
+word O 135
+word y 13456
+word Y 13456
+
+# punctuation
+prepunc " 236
+postpunc " 356
+noback always " 5
+prepunc ' 6-236
+postpunc ' 356-3
+postpunc '' 356
+postpunc ''' 356-3-356
+
+noback always ' 3
+midnum , 3
+noback always , 2
+midnum . 2
+decpoint . 2
+noback always . 256
+noback always ; 23
+midnum : 6-25
+noback always : 25
+endnum ! 6-235
+noback always ! 235
+always # 4-3456
+midnum / 456-34-3456
+always / 456-34
+noback always ? 236
+endnum % 0-25-1234
+always % 25-1234
+midnum ^ 346-3456
+always ^ 456-126
+always ~ 4-156
+always & 4-12346
+midnum * 0-56-236-3456
+always * 35-35
+repeated *** 35-35-0-35-35-0-35-35
+prepunc ( 2356
+postpunc ) 2356
+always [ 6-2356
+always ] 2356-3
+always { 46-2356
+always } 46-2356
+always -com =
+endword -to = pointed-to resource
+endword -by = used-by
+# always _ 78
+prepunc `` 236
+prepunc ` 6-236
+noback always ` 4
+noback always @ 2346
+always \\ 5-16
+always | 5-123
+repeated --- 36-36-36
+
+# repeated ___ 78-78-78
+repeated ___ 46-46-46
+
+repeated ::: 25-25-25
+
+repeated === 56-2356-56-2356-56-2356
+repeated ~~~ 4-156-4-156-4-156
+always \s-\s 36-36
+always \s-\scom 36-36-14-135-134
+always ... 3-3-3
+always .\s.\s. 3-3-3 . . .
+# always \x2026 3-3-3 # 8230 MS Word smart ellipsis
+
+# the hyphen
+# always 36
+repeated 36-36-36
+always \s\s 36-36
+
+# accented letters
+
+uplow \x00C0\x00E0 1 # a with grave
+uplow \x00C1\x00E1 1 # a with acute
+uplow \x00C2\x00E2 1 # a with circumflex
+#uplow \x00C3\x00E3 1 # a with tilde
+uplow \x00C4\x00E4 1 # a with dieresis
+#uplow \x00C5\x00E5 1 # a with ring above
+uplow \x00C6\x00E6 1 # letter ae
+#uplow \x00C7\x00E7 14 # c with cedilla
+uplow \x00C8\x00E8 15 # e with grave
+uplow \x00C9\x00E9 15 # e with acute
+uplow \x00CA\x00EA 15 # e with circumflex
+uplow \x00CB\x00EB 15 # e with dieresis
+uplow \x00CC\x00EC 24 # i with grave above
+uplow \x00CD\x00ED 24 # i with acute above
+uplow \x00CE\x00EE 24 # i with circumflex
+uplow \x00CF\x00EF 24 # i with dieresis
+#uplow \x00D0\x00F0 15 # letter eth
+#uplow \x00D1\x00F1 1345 # n with tilde
+uplow \x00D2\x00F2 135 # o with grave above
+uplow \x00D3\x00F3 135 # o with acute above
+uplow \x00D4\x00F4 135 # o with circumflex
+#uplow \x00D5\x00F5 135 # o with tilde
+uplow \x00D6\x00F6 135 # o with dieresis
+# \x00D7 × multiplication sign ----------------------
+#uplow \x00D8\x00F8 135 # o with stroke
+uplow \x00D9\x00F9 136 # u with grave above
+uplow \x00DA\x00FA 136 # u with acute above
+uplow \x00DB\x00FB 136 # u with circumflex above
+uplow \x00DC\x00FC 136 # u with dieeresis
+uplow \x00DD\x00FD 13456 # y with acute above
+#uplow \x00DE\x00FE 2345 # letter thorn
+letter \x00DF 2346 # small sharp s
+uplow \x0174\x0175 2456 w with circumflex
+uplow \x0176\x0177 13456 # y with circumflex
+uplow \x0178\x00ff 13456 # y with diaeresis
+uplow \x1ef2\x1ef3 13456 # y with grave
+
+largesign \x00C0 23-1 [C0] upper a grave
+largesign \x00E0 23-1 [E0] lower a grave
+
+largesign \x00C1 25-1 [C1] upper a acute
+largesign \x00E1 25-1 [E1] lower a acute
+
+largesign \x00C2 4-1 [C2] upper a circumflex
+largesign \x00E2 4-1 [E2] lower a circumflex
+
+#largesign \x00C3 4-1 [C3] upper a tilde
+#largesign \x00E3 4-1 [E3] lower a tilde
+
+largesign \x00C4 45-1 [C4] upper a dieresis
+largesign \x00E4 45-1 [E4] lower a dieresis
+
+#largesign \x00C5 4-1 [C5] upper a ring
+#largesign \x00E5 4-1 [E5] lower a ring
+
+largesign \x00C6 1-15 [C6] upper ae
+largesign \x00E6 1-15 [E6] lower ae
+
+#largesign \x00C7 4-14 [C7] upper c cedilla
+#largesign \x00E7 4-14 [E7] lower c cedilla
+
+largesign \x00C8 23-15 [C8] upper e grave
+largesign \x00E8 23-15 [E8] lower e grave
+
+largesign \x00C9 25-15 [C9] upper e acute
+largesign \x00E9 25-15 [E9] lower e acute
+
+largesign \x00CA 4-15 [CA] upper e circumflex
+largesign \x00EA 4-15 [EA] lower e circumflex
+
+largesign \x00CB 45-15 [CB] upper e dieresis
+largesign \x00EB 45-15 [EB] lower e dieresis
+
+largesign \x00CC 23-24 [CC] upper i grave
+largesign \x00EC 23-24 [EC] lower i grave
+
+largesign \x00CD 25-24 [CD] upper i acute
+largesign \x00ED 25-24 [ED] lower i acute
+
+largesign \x00CE 4-24 [CE] upper i circumflex
+largesign \x00EE 4-24 [EE] lower i circumflex
+
+largesign \x00CF 45-24 [CF] upper i dieresis
+largesign \x00EF 45-24 [EF] lower i dieresis
+
+#largesign \x00D0 4-15 [D0] upper eth
+#largesign \x00F0 4-15 [F0] lower eth
+
+#largesign \x00D1 4-1345 [D1] upper n tilde
+#largesign \x00F1 4-1345 [F1] lower n tilde
+
+largesign \x00D2 23-135 [D2] upper o grave
+largesign \x00F2 23-135 [F2] lower o grave
+
+largesign \x00D3 25-135 [D3] upper o acute
+largesign \x00F3 25-135 [F3] lower o acute
+
+largesign \x00D4 4-135 [D4] upper o circumflex
+largesign \x00F4 4-135 [F4] lower o circumflex
+
+#largesign \x00D5 4-135 [D5] upper o tilde
+#largesign \x00F5 4-135 [F5] lower o tilde
+
+largesign \x00D6 45-135 [D6] upper o dieresis
+largesign \x00F6 45-135 [F6] lower o dieresis
+
+#largesign \x00D8 4-135 [D8] upper o slash
+#largesign \x00f8 4-135 [F8] lower o slash
+
+largesign \x00D9 23-136 [D9] upper u grave
+largesign \x00F9 23-136 [F9] lower u grave
+
+largesign \x00DA 25-136 [DA] upper u acute
+largesign \x00FA 25-136 [FA] lower u acute
+
+largesign \x00DB 4-136 [DB] upper u circumflex
+largesign \x00FB 4-136 [FB] lower u circumflex
+
+largesign \x00DC 45-136 [DC] upper u dieresis
+largesign \x00FC 54-136 [FC] lower u dieresis
+
+largesign \x00DD 25-13456 [DD] upper y acute
+largesign \x00FD 25-13456 [FD] lower y acute
+
+#largesign \x00DE 4-2345 [DE] upper t horn
+#largesign \x00FE 4-2345 [FE] lower t horn
+
+largesign \x00DF 234-234 (DF) lower ss
+
+largesign \x0174 4-2456 lower w circumflex
+largesign \x0175 4-2456 upper w circumflex
+
+largesign \x0176 4-13456 upper y circumflex
+largesign \x0177 4-13456 lower y circumflex
+
+largesign \x0178 45-13456 upper y with dieresis
+largesign \x00FF 45-13456 lower y with dieresis
+
+largesign \x1EF2 23-13456 upper y with grave
+largesign \x1EF3 23-13456 lower y with grave
+
+hyphen \x2010 36 # 8208 hyphen
+
+# punctuation \x2011 36 # 8209 non-breaking hyphen
+punctuation \x2011 23478 # 8209 non-breaking hyphen
+
+
+always \x2013 56-36 # 8211 smart minus sign
+
+
+noback always \x201C 236 # 8220 smart opening double quote
+noback always \x201D 356 # 8221 smart closing double quote
+noback always \x201E 236 # 8222 smart double low quotation mark
+noback always \x201F 356 # 8223 smart double high reverse quotation mark
+
+
+# mathematical symbols
+decpoint . 2
+noback always < 246
+joinword = 56-2356
+joinnum = 56-2356
+noback always > 135
+midnum + 0-56-235-3456
+joinnum + 56-235
+joinword + 56-235
+midnum - 36-3456
+noback always - 36
+joinnum × 56-236
+joinword × 56-236
+midnum ÷ 0-56-256-3456 division sign
+joinnum ÷ 56-256
+joinword ÷ 56-256
+begnum £ 123
+always £ 4-123 pounds
+
+# other special characters
+always © 45-14 copyright
+sign 45-2345 trademark
+sign ® 45-1235 registered
+always ¶ 1234-345 paragraph
+always § 234-3 section
+noback always ° 356 degrees
+begnum $ 256
+always $ 4-256
+always ¢ 4-14 cents
+sign 4-15 euro
+always 4-15 euro
+always ¥ 4-13456 yen
+always µ 2-134 mu
+
+# special character sequences
+literal :// URLs
+literal www.
+
+literal .com
+literal .edu
+literal .gov
+literal .mil
+literal .net
+literal .org
+ include countries.cti
+
+literal .doc
+literal .htm
+literal .html
+literal .tex
+literal .txt
+
+literal .gif
+literal .jpg
+literal .png
+literal .wav
+
+literal .tar
+literal .zip
+
diff --git a/tables/cy-cy-g2.ctb b/tables/cy-cy-g2.ctb
new file mode 100644
index 0000000..a425c4d
--- /dev/null
+++ b/tables/cy-cy-g2.ctb
@@ -0,0 +1,199 @@
+# liblouis: Welsh Grade 2 Braille Contraction Table
+#
+# Copyright (C) 2004-2008 ViewPlus Technologies, Inc. www.viewplus.com
+# Copyright (C) 2004-2006 JJB Software, Inc. www.jjb-software.com
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# Created by Tom Johnston <tom.johnston@accessibilityconsulting.co.uk>.
+
+include cy-cy-g1.utb
+
+# the letter a
+word a 1
+word anghofio 1-1345-1245-125
+always ar 345
+word arbennig 345-12-15-1345-1345-24-1245
+always arh 1-1235-125
+
+#the letter b
+word beth 12
+always blwyddyn 12-123
+always braille 12-1235-123
+word byddai 12-145-145
+
+#the letter c
+word cael 14
+always cyrraedd 456-14
+
+#the letter ch
+word chwarae 16
+always chwerthin 5-16
+
+#the letter d
+always dechrau 145-16-1235
+word diolch 145-16
+always diwedd 145-2456
+word diwethaf 145-2456-1456
+always dydd 5-145
+word dyma 145
+
+#the letter dd
+word ddoe 145-145
+
+#the letter e
+always ed 1246
+always edd 15-145-145
+word ef 15
+word efallai 15-124-123-123
+always eisiau 15-24-234
+always eistedd 5-15
+always en 26
+always er 12456
+always erh 15-1235-125
+
+#the letter f
+word fel 124
+always fyny 5-124
+
+#the letter ff
+word ffordd 124-124
+always ffrind 124-124-1235
+
+#the letter g
+always gorffen 1245-1235-124-124
+always gweithio 456-1245
+word gwelwch 1245-2456
+word gwneud 1245-1345-145
+word gwybod 1245-2456-12
+word gyda 1245
+
+#the letter h
+always heddiw 5-125
+always hefyd 456-125
+word hoffi 125
+word hynny 125-1345
+
+#the letter i
+word i 24
+endword iaeth 56-1456
+endword iaid 46-145
+endword ion 46-1345
+always in 35
+
+#the letter l
+word lawr 123
+
+#the letter ll
+word llawer 123-123
+always llythr 123-123-1235
+
+#the letter m
+word mae 134
+word meddai 134-145-145
+always meddwl 456-134
+always mynd 5-134
+
+#the letter n
+word neithiwr 1345-1456
+always newydd 5-1345
+word nid 1345
+
+#the letter o
+word o 135
+always o'r\sgloch 135-3-1235-0-1245-123
+word oedd 5-135
+always of 12356
+always off 135-124-124
+word oherwydd 135-125-2456
+always ow 135-2456
+
+#the letter p
+word penderfynu 1234-26-145 #the letter p
+always pethau 1234-1456-136
+word plant 1234-123
+always plentyn 5-1234
+word pobl 1234
+always prynhawn 1234-1235-125
+
+#the letter r
+word roedd 1235
+endword rwydd 56-145-145
+
+#the letter rh
+word rhai 1235-125
+always rhaid 5-1235-125
+word rhyw 1235-125-2456
+word rhywbeth 1235-125-2456-12
+word rhywbryd 1235-125-2456-12-1235
+word rhywfaint 1235-125-2456-124-2345
+word rhywfodd 1235-125-2456-124
+word rhywle 1235-125-2456-123
+word rhywun 1235-125-2456-136
+
+#the letter s
+always siarad 5-234
+always st 34
+always sth 234-1456
+always stori 34
+word sydd 234
+always sylweddoli 456-234
+
+#the letter t
+word trwy 2345
+always tywydd 5-2345
+
+#the letter u
+always uchel 5-136
+word unig 136
+word uwchben 136-2456-12
+
+#the letter w
+endword waith 46-1456
+word wedi 2456
+always wedyn 456-2456
+always wrth 5-2456
+word weithiau 2456-1456-136
+
+#the letter y
+word y 13456
+endword yddes 56-234
+always ysgol 5-13456
+word ysgrifennu 13456-234-1245
+
+# Système International Prefixes
+begword yotta 13456-135-2345-2345-1 10^24
+begword zetta 1356-15-2345-2345-1 10^21
+ begword exa 15-1346-1 10^18
+begword peta 1234-15-2345-1 10^15
+begword tera 2345-12456-1 10^12
+begword giga 1245-24-1245-1 10^9
+begword mega 134-15-1245-1 10^6
+begword kilo 13-24-123-135 10^3
+begword hecto 125-15-14-2345-135 10^2
+begword deca 145-15-14-1 10^1
+begword deci 145-15-14-24 10^-1
+begword centi 14-26-2345-24 10^-2
+begword milli 134-24-123-123-24 10^-3
+begword micro 134-24-14-1235-135 10^-6
+begword nano 1345-1-1345-135 10^-9
+begword pico 1234-24-14-135 10^-12
+begword femto 124-15-134-2345-135 10^-15
+begword atto 1-2345-2345-135 10^-18
+begword zepto 1356-15-1234-2345-135 10^-21
+begword yocto 13456-135-14-2345-135 10^-24
+
diff --git a/tables/cy.tbl b/tables/cy.tbl
new file mode 100644
index 0000000..e7de767
--- /dev/null
+++ b/tables/cy.tbl
@@ -0,0 +1,19 @@
+#-index-name: Welsh, contracted
+#-display-name: Welsh contracted braille
+
+#+locale:cy
+#+type:literary
+#+contraction:full
+#+grade:2
+
+# TODO: Please correct the metadata above. It is not meant to be
+# accurate nor complete. It hasn't been verified by the table
+# author yet. It is merely an attempt by the liblouis maintainers
+# to get some sensible initial values in place.
+
+# TODO: Please add a reference to official documentation about
+# the implemented braille code. Preferably submit the documents
+# to https://github.com/liblouis/braille-specs.
+
+include cy-cy-g2.ctb
+include braille-patterns.cti
diff --git a/tables/da-dk-6miscChars.cti b/tables/da-dk-6miscChars.cti
new file mode 100644
index 0000000..e029e2d
--- /dev/null
+++ b/tables/da-dk-6miscChars.cti
@@ -0,0 +1,279 @@
+# Liblouis: Misc character definitions for Danish 6 dots (all grades)
+#
+# By Bue Vester-Andersen
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#------------
+# This file contains miscelaneous unicode character definitions used by 6 dots, all grades.
+# Many of the characters in this file have not been defined in the
+# Danish Braille standard.
+# The current implementation is purely experimental and subject to change.
+# Math chars and arrows etc. are inspired by UEB.
+# Version: Bue Vester-Andersen 191202
+
+# CP1252 (\x0080-\x009f)
+noback sign \x0080 45-15 #EURO SIGN (0x80)
+noback punctuation \x0082 4 #Low single quote (0x82)
+noback sign \x0083 45-124 #Flurihn (0x83)
+noback punctuation \x0084 2356 #Low quote (0x84)
+noback punctuation \x0085 3-3-3 #Elipsis (0x85)
+noback math \x0089 245-356-356 #permille sign (0x89)
+noback uplow \x008a\x009a 5-234 #LATIN LETTER S WITH CARON (0x8a)
+noback punctuation \x008b 4 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK (0x8b)
+noback uplow \x008c\x009c 135-15 #LATIN LIGATURE OE (0x8c)
+noback uplow \x008e\x009e 5-1356 #LATIN CAPITAL LETTER Z WITH CARON (0x8e)
+noback punctuation \x0091 4 #LEFT SINGLE QUOTATION MARK (0x91)
+noback punctuation \x0092 4 #RIGHT SINGLE QUOTATION MARK (0x92)
+noback punctuation \x0093 2356 #LEFT DOUBLE QUOTATION MARK (0x93)
+noback punctuation \x0094 2356 #RIGHT DOUBLE QUOTATION MARK (0x94)
+noback sign \x0095 45-3 #Bullit (0x95)
+noback sign \x0096 36-36 #EN DASH (0x96)
+noback sign \x0097 36-36 #Em DASH (0x97)
+noback sign \x0099 45-2345 #TRADE MARK SIGN (0x99)
+noback punctuation \x009b 4 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (0x9b)
+noback uppercase \x009f 5-13456 #LATIN CAPITAL LETTER Y WITH DIAERESIS (0x9f)
+
+# Latin-1 Supplement (Unicode block) (\x00a0-\x00ff)
+noback punctuation \x00a0 0 NO-BREAK SPACE (0xa0)
+noback punctuation \x00a1 256 INVERTED EXCLAMATION MARK )0xa1)
+punctuation \x00a2 45-25 CENT SIGN (0xa2)
+punctuation \x00a3 45-123 POUND SIGN (0xa3)
+#punctuation \x00a4 2367 CURRENCY SIGN (0xa4)
+punctuation \x00a5 45-13456 YEN SIGN (0xa5)
+#punctuation \x00a6 3478 BROKEN BAR (0xa6)
+#punctuation \x00a8 6-56 DIAERESIS (0xa8)
+punctuation \x00a9 45-14 COPYRIGHT SIGN (0xa9)
+#letter \x00aa 234678 FEMININE ORDINAL INDICATOR (0xaa)
+noback punctuation \x00ab 2356 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (0xab)
+#punctuation \x00ac 34567 NOT SIGN (0xac)
+noback punctuation \x00ad 36 SOFT HYPHEN (0xad)
+punctuation \x00ae 45-1235 REGISTERED SIGN (0xae)
+#punctuation \x00af 23567 MACRON (0xaf)
+sign \x00b0 4-356 DEGREE SIGN (0xb0)
+noback math \x00b1 45-235-36 PLUS-MINUS SIGN
+digit \x00b2 346-12 SUPERSCRIPT TWO
+digit \x00b3 346-14 SUPERSCRIPT THREE
+noback punctuation \x00b4 4 ACUTE ACCENT
+sign \x00b5 5-134 MICRO SIGN
+#punctuation \x00b6 1234568 PILCROW SIGN
+#punctuation \x00b7 38 MIDDLE DOT
+#punctuation \x00b8 4678 CEDILLA
+digit \x00b9 346-1 SUPERSCRIPT ONE
+#letter \x00ba 12345678 MASCULINE ORDINAL INDICATOR
+noback punctuation \x00bb 2356 RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+noback sign \x00bc 3456-1-34-145 VULGAR FRACTION ONE QUARTER
+noback sign \x00bd 3456-1-34-12 VULGAR FRACTION ONE HALF
+noback sign \x00be 3456-14-34-145 VULGAR FRACTION THREE QUARTERS
+noback punctuation \x00bf 26 INVERTED QUESTION MARK
+uplow \x00c0\x00e0 5-1 LATIN LETTER A WITH GRAVE
+noback uplow \x00c1\x00e1 5-1 LATIN LETTER A WITH ACUTE
+noback uplow \x00c2\x00e2 5-1 LATIN LETTER A WITH CIRCUMFLEX
+noback uplow \x00c3\x00e3 5-1 LATIN LETTER A WITH TILDE
+noback uplow \x00c4\x00e4 345 LATIN LETTER A WITH DIAERESIS
+uplow \x00c7\x00e7 5-14 LATIN LETTER C WITH CEDILLA
+noback uplow \x00c8\x00e8 5-15 LATIN LETTER E WITH GRAVE
+uplow \x00c9\x00e9 5-15 LATIN LETTER E WITH ACUTE
+noback uplow \x00ca\x00ea 5-15 LATIN LETTER E WITH CIRCUMFLEX
+noback uplow \x00cb\x00eb 5-15 LATIN LETTER E WITH DIAERESIS
+noback uplow \x00cc\x00ec 5-24 LATIN LETTER I WITH GRAVE
+noback uplow \x00cd\x00ed 5-24 LATIN LETTER I WITH ACUTE
+uplow \x00ce\x00ee 5-24 LATIN LETTER I WITH CIRCUMFLEX (first for back-translation)
+noback uplow \x00cf\x00ef 5-24 LATIN LETTER I WITH DIAERESIS
+uplow \x00d0\x00f0 5-145 LATIN LETTER ETH
+uplow \x00d1\x00f1 5-1345 LATIN LETTER N WITH TILDE
+noback uplow \x00d2\x00f2 5-135 LATIN LETTER O WITH GRAVE
+noback uplow \x00d3\x00f3 5-135 LATIN LETTER O WITH ACUTE
+uplow \x00d4\x00f4 5-135 LATIN LETTER O WITH CIRCUMFLEX (first for back-translation)
+noback uplow \x00d5\x00f5 5-135 LATIN LETTER O WITH TILDE
+noback uplow \x00d6\x00f6 246 LATIN LETTER O WITH DIAERESIS
+math \x00d7 45-3 MULTIPLICATION SIGN
+noback uplow \x00d9\x00f9 5-136 LATIN LETTER U WITH GRAVE
+noback uplow \x00da\x00fa 5-136 LATIN LETTER U WITH ACUTE
+uplow \x00db\x00fb 5-136 LATIN LETTER U WITH CIRCUMFLEX (first for back-translation
+uplow \x00dd\x00fd 5-13456 LATIN LETTER Y WITH ACUTE (infinite?)
+uplow \x00de\x00fe 5-2345 LATIN CAPITAL LETTER THORN
+noback lowercase \x00df 234-234 LATIN SMALL LETTER SHARP S
+math \x00f7 45-256 DIVISION SIGN
+
+# Latin Extended-A (\x0100-\x017f)
+
+noback uplow \x0100\x0101 5-1 Latin letter a with macron
+noback uplow \x0102\x0103 5-1 Latin letter a with breve
+noback uplow \x0104\x0105 5-1 Latin letter a with ogonek
+noback uplow \x0106\x0107 5-14 Latin letter c with acute
+noback uplow \x0108\x0109 5-14 Latin letter c with circumflex
+noback uplow \x010a\x010b 5-14 Latin letter c with dot above
+noback uplow \x010c\x010d 5-14 Latin letter c with caron
+noback uplow \x010e\x010f 5-145 Latin letter d with caron
+noback uplow \x0110\x0111 5-145 Latin letter d with stroke
+noback uplow \x0112\x0113 5-15 Latin letter e with macron
+noback uplow \x0114\x0115 5-15 Latin letter e with breve
+noback uplow \x0116\x0117 5-15 Latin letter e with dot above
+noback uplow \x0118\x0119 5-15 Latin letter e with ogonek
+noback uplow \x011a\x011b 5-15 Latin letter e with caron
+noback uplow \x011c\x011d 5-1245 Latin letter g with circumflex
+noback uplow \x011e\x011f 5-1245 Latin letter g with breve
+noback uplow \x0120\x0121 5-1245 Latin letter g with dot above
+noback uplow \x0122\x0123 5-1245 Latin letter g with cedilla
+noback uplow \x0124\x0125 5-125 Latin letter h with circumflex
+noback uplow \x0126\x0127 5-125 Latin letter h with stroke
+noback uplow \x0128\x0129 5-24 Latin letter i with tilde
+noback uplow \x012a\x012b 5-24 Latin letter i with macron
+noback uplow \x012c\x012d 5-24 Latin letter i with breve
+noback uplow \x012e\x012f 5-24 Latin letter i with ogonek
+noback uplow \x0130\x0131 5-24 Latin capital letter i with dot above / small dotless i
+noback uplow \x0132\x0133 24-245 Latin ligature ij
+noback uplow \x0134\x0135 5-245 Latin letter j with circumflex
+noback uplow \x0136\x0137 5-13 Latin letter k with cedilla
+noback lowercase \x0138 5-12345 Small latin letter kra (Greenlandic q)
+noback uplow \x0139\x013a 5-123 Latin letter l with acute
+noback uplow \x013b\x013c 5-123 Latin letter l with cedilla
+noback uplow \x013d\x013e 5-123 Latin letter l with caron
+noback uplow \x013f\x0140 5-123 Latin letter l with middle dot
+noback uplow \x0141\x0142 5-123 Latin letter l with stroke
+noback uplow \x0143\x0144 5-1345 Latin letter n with acute
+noback uplow \x0145\x0146 5-1345 Latin letter n with cedilla
+noback uplow \x0147\x0148 5-1345 Latin letter n with caron
+noback lowercase \x0149 4-1345 Latin small letter n preceeded by apostrophe
+noback uplow \x014a\x014b 5-1345 Latin letter eng
+noback uplow \x014c\x014d 5-135 Latin letter o with macron
+noback uplow \x014e\x014f 5-135 Latin letter o with breve
+noback uplow \x0150\x0151 5-135 Latin letter o with double acute
+noback uplow \x0152\x0153 135-15 #LATIN LIGATURE OE (0x8c)
+noback uplow \x0154\x0155 5-1235 Latin letter r with acute
+noback uplow \x0156\x0157 5-1235 Latin letter r with cedilla
+noback uplow \x0158\x0159 5-1235 Latin letter r with caron
+noback uplow \x015a\x015b 5-234 Latin letter s with acute
+noback uplow \x015c\x015d 5-234 Latin letter s with circumflex
+noback uplow \x015e\x015f 5-234 Latin letter s with cedilla
+uplow \x0160\x0161 5-234 #LATIN LETTER S WITH CARON (0x8a)
+noback uplow \x0162\x0163 5-2345 Latin letter t with cedilla
+noback uplow \x0164\x0165 5-2345 Latin letter t with caron
+noback uplow \x0166\x0167 5-2345 Latin letter t with stroke
+noback uplow \x0168\x0169 5-136 Latin letter u with tilde
+noback uplow \x016a\x016b 5-136 Latin letter u with macron
+noback uplow \x016c\x016d 5-136 Latin letter u with breve
+noback uplow \x016e\x016f 5-136 Latin letter u with ring above
+noback uplow \x0170\x0171 5-136 Latin letter u with double acute
+noback uplow \x0172\x0173 5-136 Latin letter u with ogonek
+noback uplow \x0174\x0175 5-2456 Latin letter w with circumflex
+noback uplow \x0176\x0177 5-13456 Latin letter y with circumflex
+uplow \x0178\x00ff 5-13456 #LATIN LETTER Y WITH DIAERESIS (0x9f)
+noback uplow \x0179\x017a 5-1356 Latin letter z with acute
+noback uplow \x017b\x017c 5-1356 Latin letter z with dot above
+uplow \x017d\x017e 5-1356 #LATIN LETTER Z WITH CARON (0x8e)
+noback lowercase \x017f 5-234 Latin small letter long s
+
+# Latin Extended-B
+
+
+sign \x0192 45-124 #Flurihn (0x83)
+#letter \x02c6 5678 #Modifier letter circumflex (0x88)
+noback sign \x02DC 45-6 #SMALL TILDE (0x98)
+
+# Greek letters (with dot 5 as prefix)
+
+noback uplow \x0386\x03AC 5-1 Greek letter alpha with tonos
+noback uplow \x0388\x03AD 5-15 Greek letter epsilon with tonos
+noback uplow \x0389\x03AE 5-156 Greek letter eta with tonos
+noback uplow \x038A\x03AF 5-24 Greek letter iota with sonos
+noback uplow \x038C\x03CC 5-135 Greek letter omicron with tonos
+noback uplow \x038E\x03CD 5-136 Greek letter upsilon with tonos
+noback uplow \x038F\x03CE 5-2456 Greek letter omega with tonos
+
+noback uplow \x0391\x03B1 5-1 Greek letter alpha
+noback uplow \x0392\x03B2 5-12 Greek letter beta
+noback uplow \x0393\x03B3 5-1245 Greek letter gamma
+noback uplow \x0394\x03B4 5-145 Greek letter delta
+noback uplow \x0395\x03B5 5-15 Greek letter epsilon
+noback uplow \x0396\x03B6 5-1356 Greek letter zeta
+noback uplow \x0397\x03B7 5-156 Greek letter eta
+noback uplow \x0398\x03B8 5-1456 Greek letter theta
+noback uplow \x0399\x03B9 5-24 Greek letter iota
+noback uplow \x039A\x03BA 5-13 Greek letter kappa
+noback uplow \x039B\x03BB 5-123 Greek letter lamda
+noback uplow \x039C\x03BC 5-134 Greek letter Mu
+noback uplow \x039D\x03BD 5-1345 Greek letter Nu
+noback uplow \x039E\x03BE 5-1346 Greek letter Xi
+noback uplow \x039F\x03BF 5-135 Greek letter Omicron
+noback uplow \x03A0\x03C0 5-1234 Greek letter Pi
+noback uplow \x03A1\x03C1 5-1235 Greek letter Rho
+noback uplow \x03A3\x03C3 5-234 Greek letter sigma
+noback uplow \x03A4\x03C4 5-2345 Greek letter Tau
+noback uplow \x03A5\x03C5 5-136 Greek letter Upsilon
+noback uplow \x03A6\x03C6 5-124 Greek letter Phi
+noback uplow \x03A7\x03C7 5-125 Greek letter Chi
+noback uplow \x03A8\x03C8 5-13456 Greek letter Psi
+noback uplow \x03A9\x03C9 5-2456 Greek letter Omega
+
+# Punctuation and bullits
+
+noback space \x2000 0 # En quad
+noback space \x2001 0 # Em quad
+noback space \x2002 0 # En space
+noback space \x2003 0 # Em space
+noback space \x2004 0 # Three-Per-Em Space
+noback space \x2005 0 # Four-Per-Em Space
+noback space \x2006 0 # Six-Per-Em Space
+noback space \x2007 0 # Figure Space
+noback space \x2008 0 # Punctuation Space
+noback space \x2009 0 # Thin Space
+noback space \x200a 0 # Hair Space
+noback punctuation \x2010 36 # Hyphen
+noback punctuation \x2011 36 # Non-breaking hyphen
+noback punctuation \x2012 36 # Figure dash
+noback sign \x2013 36-36 #EN DASH (0x96)
+noback sign \x2014 36-36 #Em DASH (0x97)
+noback punctuation \x2018 4 #LEFT SINGLE QUOTATION MARK (0x91)
+noback punctuation \x2019 4 #RIGHT SINGLE QUOTATION MARK (0x92)
+noback punctuation \x201A 4 #Low single quote (0x82)
+noback punctuation \x201b 4 # Single High-Reversed-9 Quotation Mark
+noback punctuation \x201c 2356 #LEFT DOUBLE QUOTATION MARK (0x93)
+noback punctuation \x201d 2356 #RIGHT DOUBLE QUOTATION MARK (0x94)
+noback punctuation \x201E 2356 #Low quote (0x84)
+noback punctuation \x201f 2356 # Double High-Reversed-9 Quotation Mark
+#letter \x2020 2357 #Dagger (0x86
+#letter \x2021 23578 #Double dagger (0x87
+sign \x2022 45-3 #Bullit (0x95)
+noback sign \x2023 45-3 #Triangular bullit
+noback punctuation \x2026 3-3-3 #Elipsis (0x85)
+noback space \x202f 0 # Narrow No-Break Space (NNBSP)
+math \x2030 245-356-356 #permille sign (0x89)
+noback punctuation \x2039 4 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK (0x8b)
+noback punctuation \x203A 4 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (0x9b)
+noback punctuation \x203c 235-235 # Double Exclamation Mark
+noback punctuation \x203d 26-235 # Interrobang
+noback sign \x2043 45-3 # Hyphen bullet (0x95)
+noback punctuation \x2047 26-26 # Double question mark
+noback punctuation \x2048 26-235 # Question exclamation mark
+noback punctuation \x2049 235-26 # Exclamation question mark
+noback sign \x204c 45-3 # BLACK LEFTWARDS BULLET
+noback sign \x204d 45-3 # BLACK RIGHTWARDS BULLET
+sign \x20AC 45-15 #EURO SIGN (0x80)
+sign \x2122 45-2345 #TRADE MARK SIGN (0x99)
+
+# Arrows
+
+sign \x2190 45-2456 Left arrow
+sign \x2191 45-12356 Up arrow
+sign \x2192 45-1235 Right arrow
+sign \x2193 45-12345 Down arrow
+
+# Geometrical shapes
+
+noback sign \x25e6 45-3 #White bullet
diff --git a/tables/da-dk-8miscChars.cti b/tables/da-dk-8miscChars.cti
new file mode 100644
index 0000000..1e69f42
--- /dev/null
+++ b/tables/da-dk-8miscChars.cti
@@ -0,0 +1,205 @@
+# Liblouis: Misc character definitions for Danish 6 dots (all grades)
+#
+# By Bue Vester-Andersen
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#------------
+# This file contains miscelaneous unicode character definitions used by 8 dots, grades 1 and 2.
+# Many of the characters in this file have not been defined in the
+# Danish Braille standard.
+# The current implementation is purely experimental and subject to change.
+# Math chars and arrows etc. are inspired by UEB.
+# Version: Bue Vester-Andersen 191202
+
+# Latin Extended-A (\x0100-\x017f)
+
+uplow \x0100\x0101 5-17,5-1 Latin letter a with macron
+noback uplow \x0102\x0103 5-17,5-1 Latin letter a with breve
+noback uplow \x0104\x0105 5-17,5-1 Latin letter a with ogonek
+uplow \x0106\x0107 5-147,5-14 Latin letter c with acute
+noback uplow \x0108\x0109 5-147,5-14 Latin letter c with circumflex
+noback uplow \x010a\x010b 5-147,5-14 Latin letter c with dot above
+noback uplow \x010c\x010d 5-147,5-14 Latin letter c with caron
+uplow \x010e\x010f 5-1457,5-145 Latin letter d with caron
+noback uplow \x0110\x0111 5-1457,5-145 Latin letter d with stroke
+uplow \x0112\x0113 5-157,5-15 Latin letter e with macron
+noback uplow \x0114\x0115 5-157,5-15 Latin letter e with breve
+noback uplow \x0116\x0117 5-157,5-15 Latin letter e with dot above
+noback uplow \x0118\x0119 5-157,5-15 Latin letter e with ogonek
+noback uplow \x011a\x011b 5-157,5-15 Latin letter e with caron
+uplow \x011c\x011d 5-12457,5-1245 Latin letter g with circumflex
+noback uplow \x011e\x011f 5-12457,5-1245 Latin letter g with breve
+noback uplow \x0120\x0121 5-12457,5-1245 Latin letter g with dot above
+noback uplow \x0122\x0123 5-12457,5-1245 Latin letter g with cedilla
+uplow \x0124\x0125 5-1257,5-125 Latin letter h with circumflex
+noback uplow \x0126\x0127 5-1257,5-125 Latin letter h with stroke
+uplow \x0128\x0129 5-247,5-24 Latin letter i with tilde
+noback uplow \x012a\x012b 5-247,5-24 Latin letter i with macron
+noback uplow \x012c\x012d 5-247,5-24 Latin letter i with breve
+noback uplow \x012e\x012f 5-247,5-24 Latin letter i with ogonek
+noback uplow \x0130\x0131 5-247,5-24 Latin capital letter i with dot above / small dotless i
+uplow \x0132\x0133 5-2457,5-245 Latin ligature ij
+noback uplow \x0134\x0135 5-2457,5-245 Latin letter j with circumflex
+uplow \x0136\x0137 5-137,5-13 Latin letter k with cedilla
+lowercase \x0138 5-12345 Small latin letter kra (Greenlandic q)
+uplow \x0139\x013a 5-1237,5-123 Latin letter l with acute
+noback uplow \x013b\x013c 5-1237,5-123 Latin letter l with cedilla
+noback uplow \x013d\x013e 5-1237,5-123 Latin letter l with caron
+noback uplow \x013f\x0140 5-1237,5-123 Latin letter l with middle dot
+noback uplow \x0141\x0142 5-1237,5-123 Latin letter l with stroke
+uplow \x0143\x0144 5-13457,5-1345 Latin letter n with acute
+noback uplow \x0145\x0146 5-13457,5-1345 Latin letter n with cedilla
+noback uplow \x0147\x0148 5-13457,5-1345 Latin letter n with caron
+noback lowercase \x0149 5-1345 Latin small letter n preceeded by apostrophe
+noback uplow \x014a\x014b 5-13457,5-1345 Latin letter eng
+uplow \x014c\x014d 5-1357,5-135 Latin letter o with macron
+noback uplow \x014e\x014f 5-1357,5-135 Latin letter o with breve
+noback uplow \x0150\x0151 5-1357,5-135 Latin letter o with double acute
+uplow \x0154\x0155 5-12357,5-1235 Latin letter r with acute
+noback uplow \x0156\x0157 5-12357,5-1235 Latin letter r with cedilla
+noback uplow \x0158\x0159 5-12357,5-1235 Latin letter r with caron
+uplow \x015a\x015b 5-2347,5-234 Latin letter s with acute
+noback uplow \x015c\x015d 5-2347,5-234 Latin letter s with circumflex
+noback uplow \x015e\x015f 5-2347,5-234 Latin letter s with cedilla
+uplow \x0162\x0163 5-23457,5-2345 Latin letter t with cedilla
+noback uplow \x0164\x0165 5-23457,5-2345 Latin letter t with caron
+noback uplow \x0166\x0167 5-23457,5-2345 Latin letter t with stroke
+uplow \x0168\x0169 5-1367,5-136 Latin letter u with tilde
+noback uplow \x016a\x016b 5-1367,5-136 Latin letter u with macron
+noback uplow \x016c\x016d 5-1367,5-136 Latin letter u with breve
+noback uplow \x016e\x016f 5-1367,5-136 Latin letter u with ring above
+noback uplow \x0170\x0171 5-1367,5-136 Latin letter u with double acute
+noback uplow \x0172\x0173 5-1367,5-136 Latin letter u with ogonek
+uplow \x0174\x0175 5-24567,5-2456 Latin letter w with circumflex
+uplow \x0176\x0177 5-134567,5-13456 Latin letter y with circumflex
+uplow \x0179\x017a 5-13567,5-1356 Latin letter z with acute
+noback uplow \x017b\x017c 5-13567,5-1356 Latin letter z with dot above
+noback lowercase \x017f 5-234 Latin small letter long s
+
+# Latin Extended-B
+
+sign \x0192 45-124 #Flurihn (0x83)
+noback sign \x02DC 45-6 #SMALL TILDE (0x98)
+
+# Greek letters (with dots 458 as prefix)
+
+ uplow \x0386\x03AC 458-5-17,458-5-1 Greek letter alpha with tonos
+uplow \x0388\x03AD 458-5-157,458-5-15 Greek letter epsilon with tonos
+uplow \x0389\x03AE 458-5-1567,458-5-156 Greek letter eta with tonos
+uplow \x038A\x03AF 458-5-247,458-5-24 Greek letter iota with sonos
+uplow \x038C\x03CC 458-5-1358,458-5-135 Greek letter omicron with tonos
+uplow \x038E\x03CD 458-5-1367,458-5-136 Greek letter upsilon with tonos
+uplow \x038F\x03CE 458-5-24567,458-5-3456 Greek letter omega with tonos
+
+uplow \x0391\x03B1 458-17,458-1 Greek letter alpha
+uplow \x0392\x03B2 458-127,458-12 Greek letter beta
+uplow \x0393\x03B3 458-12457,458-1245 Greek letter gamma
+uplow \x0394\x03B4 458-1457,458-145 Greek letter delta
+uplow \x0395\x03B5 458-157,458-15 Greek letter epsilon
+uplow \x0396\x03B6 458-13567,458-1356 Greek letter zeta
+uplow \x0397\x03B7 458-1567,458-156 Greek letter eta
+uplow \x0398\x03B8 458-14567,458-1456 Greek letter theta
+uplow \x0399\x03B9 458-247,458-24 Greek letter iota
+noback uplow \x039A\x03BA 458-137,458-13 Greek letter kappa
+uplow \x039B\x03BB 458-1237,458-123 Greek letter lamda
+uplow \x039C\x03BC 458-1347,458-134 Greek letter Mu
+uplow \x039D\x03BD 458-13457,458-1345 Greek letter Nu
+uplow \x039E\x03BE 458-13467,458-1346 Greek letter Xi
+uplow \x039F\x03BF 458-1357,458-135 Greek letter Omicron
+uplow \x03A0\x03C0 458-12347,458-1234 Greek letter Pi
+uplow \x03A1\x03C1 458-12357,458-1235 Greek letter Rho
+uplow \x03A3\x03C3 458-2347,458-234 Greek letter sigma
+uplow \x03A4\x03C4 458-23457,458-2345 Greek letter Tau
+uplow \x03A5\x03C5 458-1367,458-136 Greek letter Upsilon
+uplow \x03A6\x03C6 458-1247,458-124 Greek letter Phi
+uplow \x03A7\x03C7 458-123467,458-12346 Greek letter Chi
+uplow \x03A8\x03C8 458-134567,458-13456 Greek letter Psi
+uplow \x03A9\x03C9 458-24567,458-2456 Greek letter Omega
+
+
+# Punctuation and bullits
+
+noback space \x2000 0 # En quad
+noback space \x2001 0 # Em quad
+noback space \x2002 0 # En space
+noback space \x2003 0 # Em space
+noback space \x2004 0 # Three-Per-Em Space
+noback space \x2005 0 # Four-Per-Em Space
+noback space \x2006 0 # Six-Per-Em Space
+noback space \x2007 0 # Figure Space
+noback space \x2008 0 # Punctuation Space
+noback space \x2009 0 # Thin Space
+noback space \x200a 0 # Hair Space
+noback punctuation \x2010 368 # Hyphen
+noback punctuation \x2011 368 # Non-breaking hyphen
+noback punctuation \x2012 368 # Figure dash
+noback sign \x2016 4568-4568 # Double Vertical Line
+sign \x2017 45-3678 # Double low line
+noback punctuation \x201a 4 # Single Low-9 Quotation Mark
+noback punctuation \x201b 4 # Single High-Reversed-9 Quotation Mark
+noback punctuation \x201e 2356 # Double low-9 Quotation Mark
+noback punctuation \x201f 2356 # Double High-Reversed-9 Quotation Mark
+sign \x2022 45-3 #Bullit (0x95)
+noback sign \x2023 45-3 #Triangular bullit
+noback space \x202f 0 # Narrow No-Break Space (NNBSP)
+noback punctuation \x203c 235-235 # Double Exclamation Mark
+noback punctuation \x203d 26-235 # Interrobang
+noback sign \x2043 45-3 # Hyphen bullet (0x95)
+noback punctuation \x2047 26-26 # Double question mark
+noback punctuation \x2048 26-235 # Question exclamation mark
+noback punctuation \x2049 235-26 # Exclamation question mark
+noback sign \x204c 45-3 # BLACK LEFTWARDS BULLET
+noback sign \x204d 45-3 # BLACK RIGHTWARDS BULLET
+
+# Arrows
+
+sign \x2190 45-1256-246 Left arrow
+sign \x2191 45-1256-346 Up arrow
+sign \x2192 45-1256-135 Right arrow
+sign \x2193 45-1256-146 Down arrow
+sign \x2194 45-1256-2456-1235-135 Left-right arrow
+sign \x2196 45-1256-156 Northwest arrow
+sign \x2197 45-1256-234 Northeast arrow
+sign \x2198 45-1256-126 Southeast arrow
+sign \x2199 45-1256-345 Southwest arrow
+sign \x21d4 45-1256-2456-2356-1235-135 Left-right double arrow
+
+# Math signs (experimental)
+
+math \x2200 45-1 # For all
+math \x2208 45-15 # Element of
+math \x2213 456-36 # Minus or plus
+math \x221d 456-5-23568 # Proportional to
+math \x2229 46-236 # Intersection
+math \x222a 46-235 # Union
+math \x2243 456-35 # approx. equal to
+math \x2245 5-45-35 # approx. equal to
+math \x2248 45-35 # approx. equal to
+math \x224f 45-5-23568 # Diff between or approx. equal to
+math \x2251 46-5-23568 # approx. equal to
+math \x2260 5-23568-4-156 # Not equal to
+math \x2261 456-123456 # Equivalent to
+math \x2264 456-358 # Less than or equal to
+math \x2265 456-267 # Greater than or equal to
+math \x226a 46-358 # Much less than
+math \x226b 46-267 # Much greater than
+math \x22c5 5-256 # Multiplication dot
+
+# Geometrical shapes
+
+noback sign \x25e6 45-3 #White bullet
diff --git a/tables/da-dk-g08.ctb b/tables/da-dk-g08.ctb
new file mode 100644
index 0000000..3cef570
--- /dev/null
+++ b/tables/da-dk-g08.ctb
@@ -0,0 +1,329 @@
+# Liblouis: Danish table for 8 dots computer Braille (G0)
+#
+# Copyright (C) 2014-2017, Bue Vester-Andersen <bue@vester-andersen.dk>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#------------
+#
+# This is the Danish table for 8 dots computer Braille.
+# Use this table for translation and back-translation of Danish 8 dots computer Braille (Octo-Braille).
+#
+# Version: Bue Vester-Andersen, 170604
+
+### Table Metadata
+
+#-name: Dansk computer
+#-index-name: Danish, computer
+#-display-name: Danish computer braille
+
+#+locale: da
+#+type: computer
+#+contraction: no
+#+grade: 0
+#+dots: 8
+#+direction: both
+
+
+# Display upcodes
+include da-dk-octobraille.dis
+
+### Character definitions
+
+sign \x0000 8 NULL
+sign \x0001 178 START OF HEADING
+sign \x0002 1278 START OF TEXT
+sign \x0003 1478 END OF TEXT
+sign \x0004 14578 END OF TRANSMISSION
+sign \x0005 24568 ENQUIRY
+sign \x0006 12478 ACKNOWLEDGE
+sign \x0007 124578 BELL
+sign \x0008 12578 BACKSPACE
+space \t 2478 CHARACTER TABULATION
+space \n 678 LINE FEED (LF)
+space \v 1368 LINE TABULATION
+space \f 12378 FORM FEED (FF)
+space \r 257 CARRIAGE RETURN (CR)
+sign \x000e 134578 SHIFT OUT
+sign \x000f 12358 SHIFT IN
+sign \x0010 123478 DATA LINK ESCAPE
+sign \x0011 1234578 DEVICE CONTROL ONE
+sign \x0012 13568 DEVICE CONTROL TWO
+sign \x0013 4578 DEVICE CONTROL THREE
+sign \x0014 268 DEVICE CONTROL FOUR
+sign \x0015 13678 NEGATIVE ACKNOWLEDGE
+sign \x0016 278 SYNCHRONOUS IDLE
+sign \x0017 3578 END OF TRANSMISSION BLOCK
+sign \x0018 78 CANCEL
+sign \x0019 68 END OF MEDIUM
+sign \x001a 135678 SUBSTITUTE
+sign \x001b 2678 ESCAPE
+sign \x001c 45678 INFORMATION SEPARATOR FOUR
+sign \x001d 12368 INFORMATION SEPARATOR THREE
+sign \x001e 1234678 INFORMATION SEPARATOR TWO
+sign \x001f 235678 INFORMATION SEPARATOR ONE
+space \s 0 SPACE
+punctuation ! 235 EXCLAMATION MARK
+punctuation " 2356 QUOTATION MARK
+punctuation # 34568 NUMBER SIGN
+sign $ 25678 DOLLAR SIGN
+math % 24578 PERCENT SIGN
+sign & 123468 AMPERSAND
+punctuation ' 4 APOSTROPHE
+punctuation ( 2368 LEFT PARENTHESIS
+punctuation ) 3568 RIGHT PARENTHESIS
+punctuation * 35 ASTERISK
+math + 2358 PLUS SIGN
+punctuation , 2 COMMA
+punctuation - 368 HYPHEN-MINUS
+punctuation . 3 FULL STOP
+punctuation / 348 SLASH
+include digits8Dots.uti
+punctuation : 25 COLON
+punctuation ; 23 SEMICOLON
+math < 358 LESS-THAN SIGN
+math = 23568 EQUALS SIGN
+math > 267 GREATER-THAN SIGN
+punctuation ? 26 QUESTION MARK
+sign @ 478 COMMERCIAL AT
+uppercase A 17 Latin capital letter A
+uppercase B 127 Latin capital letter B
+uppercase C 147 Latin capital letter C
+uppercase D 1457 Latin capital letter D
+uppercase E 157 Latin capital letter E
+uppercase F 1247 Latin capital letter F
+uppercase G 12457 Latin capital letter G
+uppercase H 1257 Latin capital letter H
+uppercase I 247 Latin capital letter I
+uppercase J 2457 Latin capital letter J
+uppercase K 137 Latin capital letter K
+uppercase L 1237 Latin capital letter L
+uppercase M 1347 Latin capital letter M
+uppercase N 13457 Latin capital letter N
+uppercase O 1357 Latin capital letter O
+uppercase P 12347 Latin capital letter P
+uppercase Q 123457 Latin capital letter Q
+uppercase R 12357 Latin capital letter R
+uppercase S 2347 Latin capital letter S
+uppercase T 23457 Latin capital letter T
+uppercase U 1367 Latin capital letter U
+uppercase V 12367 Latin capital letter V
+uppercase W 24567 Latin capital letter W
+uppercase X 13467 Latin capital letter X
+uppercase Y 134567 Latin capital letter Y
+uppercase Z 13567 Latin capital letter Z
+punctuation [ 23678 LEFT SQUARE BRACKET
+punctuation \\ 347 REVERSE SLASH
+punctuation ] 35678 RIGHT SQUARE BRACKET
+punctuation ^ 12348 CIRCUMFLEX ACCENT
+punctuation _ 3678 LOW LINE
+punctuation ` 5 GRAVE ACCENT
+lowercase a 1 Latin small letter A
+lowercase b 12 Latin small letter B
+lowercase c 14 Latin small letter C
+lowercase d 145 Latin small letter D
+lowercase e 15 Latin small letter E
+lowercase f 124 Latin small letter F
+lowercase g 1245 Latin small letter G
+lowercase h 125 Latin small letter H
+lowercase i 24 Latin small letter I
+lowercase j 245 Latin small letter J
+lowercase k 13 Latin small letter K
+lowercase l 123 Latin small letter L
+lowercase m 134 Latin small letter M
+lowercase n 1345 Latin small letter N
+lowercase o 135 Latin small letter O
+lowercase p 1234 Latin small letter P
+lowercase q 12345 Latin small letter Q
+lowercase r 1235 Latin small letter R
+lowercase s 234 Latin small letter S
+lowercase t 2345 Latin small letter T
+lowercase u 136 Latin small letter U
+lowercase v 1236 Latin small letter V
+lowercase w 2456 Latin small letter W
+lowercase x 1346 Latin small letter X
+lowercase y 13456 Latin small letter Y
+lowercase z 1356 Latin small letter Z
+punctuation { 123678 LEFT CURLY BRACKET
+punctuation | 4568 VERTICAL LINE
+punctuation } 345678 RIGHT CURLY BRACKET
+punctuation ~ 467 TILDE
+sign \x007f 7 DELETE
+sign \x20AC 1578 #EURO SIGN (0x80)
+sign \x0081 45 <control-0081>
+punctuation \x201A 457 #Low single quote (0x82)
+sign \x0192 58 #Flurihn (0x83)
+punctuation \x201E 2378 #Low quote (0x84)
+punctuation \x2026 6 #Elipsis (0x85)
+sign \x2020 2357 #Dagger (0x86
+sign \x2021 23578 #Double dagger (0x87
+sign \x02c6 5678 #Modifier letter circumflex (0x88)
+math \x2030 245678 #permille sign (0x89)
+uppercase \x0160 23478 #Latin capital Letter S with caron (0x8a/0x9a)
+punctuation \x2039 456 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK (0x8b)
+uppercase \x0152 13578 #Latin capital LIGATURE OE (0x8c)
+sign \x008d 3567 REVERSE LINE FEED (not defined in cp1252)
+uppercase \x017d 3467 #Latin capital letter Z with caron (0x8e)
+sign \x008f 27 SINGLE SHIFT THREE (not defined in cp1252)
+sign \x0090 357 DEVICE CONTROL STRING (not defined in cp1252)
+punctuation \x2018 47 #LEFT SINGLE QUOTATION MARK (0x91)
+punctuation \x2019 48 #RIGHT SINGLE QUOTATION MARK (0x92)
+punctuation \x201c 237 #LEFT DOUBLE QUOTATION MARK (0x93)
+punctuation \x201d 568 #RIGHT DOUBLE QUOTATION MARK (0x94)
+sign \x2022 37 #Bullit (0x95)
+sign \x2013 36 #EN DASH (0x96)
+sign \x2014 367 #Em DASH (0x97)
+sign \x02DC 46 #small TILDE (0x98)
+sign \x2122 234578 #TRADE MARK SIGN (0x99)
+lowercase \x0161 2348 #Latin lowercase Letter S with caron (0x8a/0x9a)
+punctuation \x203A 4567 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (0x9b)
+lowercase \x0153 1358 #Latin small LIGATURE OE (0x9c)
+letter \x009d 2567 OPERATING SYSTEM COMMAND
+lowercase \x017E 346 #Latin small letter Z with caron (0x9e)
+uppercase \x0178 2345678 #Latin capital letter Y with DIAERESIS (0x9f)
+# FIXME: this rule now actually works, so adapt tests
+punctuation \x00a0 23458 NO-BREAK SPACE (0xa0)
+punctuation \x00a1 256 INVERTED EXCLAMATION MARK )0xa1)
+punctuation \x00a2 2578 CENT SIGN (0xa2)
+punctuation \x00a3 1238 POUND SIGN (0xa3)
+punctuation \x00a4 2367 CURRENCY SIGN (0xa4)
+punctuation \x00a5 67 YEN SIGN (0xa5)
+punctuation \x00a6 3478 BROKEN BAR (0xa6)
+punctuation \x00a7 578 SECTION SIGN (0xa7)
+punctuation \x00a8 56 DIAERESIS (0xa8)
+punctuation \x00a9 134678 COPYRIGHT SIGN (0xa9)
+letter \x00aa 234678 FEMININE ORDINAL INDICATOR (0xaa)
+punctuation \x00ab 57 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (0xab)
+punctuation \x00ac 34567 NOT SIGN (0xac)
+letter \x00ad 378 SOFT HYPHEN (0xad)
+punctuation \x00ae 123578 Registered sign (0xae)
+punctuation \x00af 23567 macron (0xaf)
+sign \x00b0 356 Degree sign (0xb0)
+math \x00b1 123458 PLUS-MINUS SIGN
+punctuation \x00b2 238 SUPERSCRIPT TWO
+punctuation \x00b3 258 SUPERSCRIPT THREE
+punctuation \x00b4 468 acute ACCENT
+sign \x00b5 236 MICRO SIGN
+punctuation \x00b6 1234568 PILCROW SIGN
+punctuation \x00b7 38 MIDDLE DOT
+punctuation \x00b8 4678 CEDILLA
+punctuation \x00b9 28 SUPERSCRIPT ONE
+letter \x00ba 12345678 MASCULINE ORDINAL INDICATOR
+punctuation \x00bb 567 RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+punctuation \x00bc 13458 VULGAR FRACTION ONE QUARTER
+punctuation \x00bd 458 VULGAR FRACTION ONE HALF
+punctuation \x00be 3456 VULGAR FRACTION THREE QUARTERS
+punctuation \x00bf 34 INVERTED QUESTION MARK
+uppercase \x00c0 123567 Latin capital letter A with GRAVE
+uppercase \x00c1 1235678 Latin capital letter A with acute
+uppercase \x00c2 1678 Latin capital letter A with CIRCUMFLEX
+uppercase \x00c3 14678 Latin capital letter A with TILDE
+uppercase \x00c4 34578 Latin capital letter A with DIAERESIS
+uppercase \x00c5 167 Latin capital letter A with RING ABOVE
+uppercase \x00c6 3457 Latin capital letter AE
+uppercase \x00c7 123467 Latin capital letter C with CEDILLA
+uppercase \x00c8 23467 Latin capital letter E with GRAVE
+uppercase \x00c9 1234567 Latin capital letter E with acute
+uppercase \x00ca 1267 Latin capital letter E with CIRCUMFLEX
+uppercase \x00cb 12467 Latin capital letter E with DIAERESIS
+uppercase \x00cc 15678 Latin capital letter I with GRAVE
+uppercase \x00cd 12678 Latin capital letter I with acute
+uppercase \x00ce 1467 Latin capital letter I with CIRCUMFLEX
+uppercase \x00cf 124567 Latin capital letter I with DIAERESIS
+uppercase \x00d0 1345678 Latin capital letter ETH
+uppercase \x00d1 1245678 Latin capital letter N with TILDE
+uppercase \x00d2 124678 Latin capital letter O with GRAVE
+uppercase \x00d3 34678 Latin capital letter O with acute
+uppercase \x00d4 14567 Latin capital letter O with CIRCUMFLEX
+uppercase \x00d5 145678 Latin capital letter O with TILDE
+uppercase \x00d6 24678 Latin capital letter O with DIAERESIS
+math \x00d7 13468 MULTIPLICATION SIGN
+uppercase \x00d8 2467 Latin capital letter O with STROKE
+uppercase \x00d9 234567 Latin capital letter U with GRAVE
+uppercase \x00da 125678 Latin capital letter U with acute
+uppercase \x00db 1567 Latin capital letter U with CIRCUMFLEX
+uppercase \x00dc 12567 Latin capital letter U with DIAERESIS
+uppercase \x00dd 13478 Latin capital letter Y with acute (infinite?)
+uppercase \x00de 1378 Latin capital letter THORN
+lowercase \x00df 23468 Latin small letter SHARP S
+lowercase \x00e0 12356 Latin small letter A with GRAVE
+lowercase \x00e1 123568 Latin small letter A with acute
+lowercase \x00e2 168 Latin small letter A with CIRCUMFLEX
+lowercase \x00e3 1468 Latin small letter A with TILDE
+lowercase \x00e4 3458 Latin small letter A with DIAERESIS
+lowercase \x00e5 16 Latin small letter A with RING ABOVE
+lowercase \x00e6 345 Latin small letter AE
+lowercase \x00e7 12346 Latin small letter C with CEDILLA
+lowercase \x00e8 2346 Latin small letter E with GRAVE
+lowercase \x00e9 123456 Latin small letter E with acute
+lowercase \x00ea 126 Latin small letter E with CIRCUMFLEX
+lowercase \x00eb 1246 Latin small letter E with DIAERESIS
+lowercase \x00ec 1568 Latin small letter I with GRAVE
+lowercase \x00ed 1268 Latin small letter I with acute
+lowercase \x00ee 146 Latin small letter I with CIRCUMFLEX
+lowercase \x00ef 12456 Latin small letter I with DIAERESIS
+lowercase \x00f0 134568 Latin small letter ETH
+lowercase \x00f1 124568 Latin small letter N with TILDE
+lowercase \x00f2 12468 Latin small letter O with GRAVE
+lowercase \x00f3 3468 Latin small letter O with acute
+lowercase \x00f4 1456 Latin small letter O with CIRCUMFLEX
+lowercase \x00f5 14568 Latin small letter O with TILDE
+lowercase \x00f6 2468 Latin small letter O with DIAERESIS
+math \x00f7 2568 DIVISION SIGN
+lowercase \x00f8 246 Latin small letter O with STROKE
+lowercase \x00f9 23456 Latin small letter U with GRAVE
+lowercase \x00fa 12568 Latin small letter U with acute
+lowercase \x00fb 156 Latin small letter U with CIRCUMFLEX
+lowercase \x00fc 1256 Latin small letter U with DIAERESIS
+lowercase \x00fd 1348 Latin small letter Y with acute
+lowercase \x00fe 138 Latin small letter THORN
+lowercase \x00ff 234568 Latin small letter Y with DIAERESIS
+
+# In CP-1252 the following chars are different from Unicode.
+# This placement ensures that Liblouis will always return the unicode when back-translating.
+sign \x0080 1578 #EURO SIGN (0x80)
+punctuation \x0082 457 #Low single quote (0x82)
+sign \x0083 58 #Flurihn (0x83)
+punctuation \x0084 2378 #Low quote (0x84)
+punctuation \x0085 6 #Elipsis (0x85)
+letter \x0086 2357 #Dagger (0x86
+letter \x0087 23578 #Double dagger (0x87
+letter \x0088 5678 #Modifier letter circumflex (0x88)
+math \x0089 245678 #permille sign (0x89)
+uppercase \x008a 23478 #Latin letter S with caron (0x8a)
+lowercase \x009a 2348
+punctuation \x008b 456 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK (0x8b)
+uppercase \x008c 13578 #Latin LIGATURE OE (0x8c)
+lowercase \x009c 1358
+uppercase \x008e 3467 #Latin capital letter Z with caron (0x8e)
+lowercase \x009e 346
+punctuation \x0091 47 #LEFT SINGLE QUOTATION MARK (0x91)
+punctuation \x0092 48 #RIGHT SINGLE QUOTATION MARK (0x92)
+punctuation \x0093 237 #LEFT DOUBLE QUOTATION MARK (0x93)
+punctuation \x0094 568 #RIGHT DOUBLE QUOTATION MARK (0x94)
+sign \x0095 37 #Bullit (0x95)
+sign \x0096 36 #EN DASH (0x96)
+sign \x0097 367 #Em DASH (0x97)
+sign \x0098 46 #small TILDE (0x98)
+sign \x0099 234578 #TRADE MARK SIGN (0x99)
+punctuation \x009b 4567 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (0x9b)
+uppercase \x009f 2345678 #Latin capital letter Y with DIAERESIS (0x9f)
+
+#Unicode Braille patterns
+include braille-patterns.cti
+
+undefined 26
diff --git a/tables/da-dk-g16-lit.ctb b/tables/da-dk-g16-lit.ctb
new file mode 100644
index 0000000..b71d941
--- /dev/null
+++ b/tables/da-dk-g16-lit.ctb
@@ -0,0 +1,277 @@
+# Liblouis: Danish table for 6 dots grade 1 forward translation (literary)
+#
+# Copyright (C) 2014-2017, Bue Vester-Andersen <bue@vester-andersen.dk>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#------------
+#
+# This is the Danish 6 dots grade 1 table for forward translation (literary / not back-translateable).
+#
+# The output from this table is mainly ment for embossing and not suited for back-translation.
+#
+# Version: Bue Vester-Andersen, 170604
+
+### Table Metadata
+
+#-name: Dansk fuldskrift 6-punkt
+#-index-name: Danish, uncontracted, 6-dot
+#-display-name: Danish 6-dot uncontracted braille
+
+#+locale: da
+#+type: literary
+#+contraction: no
+#+grade: 1
+#+dots: 6
+#+direction: forward
+
+# Display opcodes
+include da-dk-octobraille.dis
+
+### Spaces
+
+# These ctrl-chars have to have a representation, so that they can be properly converted back and forth.
+space \t 2478 CHARACTER TABULATION
+space \n 678 LINE FEED (LF)
+space \v 1368 LINE TABULATION
+space \f 12378 FORM FEED (FF)
+space \r 257 CARRIAGE RETURN (CR)
+space \x00a0 a
+
+include spaces.uti
+
+### Character definitions
+
+# Definition of dot cells
+punctuation ! 235 EXCLAMATION MARK
+punctuation " 2356 QUOTATION MARK
+sign & 12346 AMPERSAND
+punctuation ' 4 APOSTROPHE
+punctuation ( 236 LEFT PARENTHESIS
+punctuation ) 356 RIGHT PARENTHESIS
+punctuation * 35 ASTERISK
+punctuation , 2 COMMA
+punctuation - 36 HYPHEN-MINUS
+punctuation . 3 FULL STOP
+punctuation / 34 SLASH
+punctuation : 25 COLON
+punctuation ; 23 SEMICOLON
+punctuation ? 26 QUESTION MARK
+include latinLetterDef6Dots.uti
+
+include digits6Dots.uti
+
+punctuation \x00a7 346 SECTION SIGN (0xa7)
+
+uplow \x00c5\x00e5 16 LATIN LETTER A WITH RING ABOVE
+uplow \x00c6\x00e6 345 LATIN LETTER AE
+uplow \x00d8\x00f8 246 LATIN LETTER O WITH STROKE
+uplow \x00dc\x00fc 1256 LATIN CAPITAL LETTER U WITH DIAERESIS
+math \x00f7 256 DIVISION SIGN
+
+# cover all other Braille patterns
+include braille-patterns.cti
+
+# Characters with two or more cells
+
+punctuation # 45-3456 NUMBER SIGN
+sign $ 45-256 DOLLAR SIGN
+math % 245-356 PERCENT SIGN
+#sign & 6-12346 AMPERSAND
+#punctuation * 6-35 ASTERISK
+math + 45-235 PLUS SIGN
+math < 45-134 LESS-THAN SIGN
+math = 45-2356 EQUALS SIGN
+math > 45-234 GREATER-THAN SIGN
+sign @ 45-1 COMMERCIAL AT
+punctuation [ 5-236 LEFT SQUARE BRACKET
+punctuation \\ 45-16 REVERSE SLASH
+punctuation ] 5-356 RIGHT SQUARE BRACKET
+punctuation ^ 45-346 CIRCUMFLEX ACCENT
+punctuation _ 45-36 LOW LINE
+punctuation ` 4 GRAVE ACCENT
+punctuation { 45-246 LEFT CURLY BRACKET
+punctuation | 45-456 VERTICAL LINE
+punctuation } 45-135 RIGHT CURLY BRACKET
+punctuation ~ 45-6 TILDE
+
+# Misc unicode characters
+include da-dk-6miscChars.cti
+
+# Litdigits
+include litdigits6Dots.uti
+
+undefined 26
+
+### Braille indicators and special characters
+
+#hyphen - 36
+
+letsign 6
+
+# No letsign before capital letters or letters with accents
+
+noletsign ABCDEFGHIJKLMNOPQRSTUVWXYZ\x0160\x0152\x017d\x0178\x00c0\x00c1\x00c2\x00c3\x00c4\x00c5\x00c6\x00c7\x00c8\x00c9\x00ca\x00cb\x00cc\x00cd\x00ce\x00cf\x00d0\x00d1\x00d2\x00d3\x00d4\x00d5\x00d6\x00d8\x00d9\x00da\x00db\x00dc\x00dd\x00de\x008a\x008c\x008e
+noletsign i\x0161\x0153\x017e\x00ff\x00df\x00e0\x00e1\x00e2\x00e3\x00e7\x00e8\x00e9\x00ea\x00eb\x00ec\x00ed\x00ee\x00ef\x00f0\x00f1\x00f2\x00f3\x00f4\x00f5\x00f9\x00fa\x00fb\x00fd\x00fe\x009a\x009c
+noletsign abcdefghjklmnopqrstuvwxyz\x00e4\x00e5\x00e6\x00f6\x00f8\x00fc
+
+# Emphasis opcodes
+emphclass italic
+emphclass underline
+emphclass bold
+
+begemphphrase italic 56
+endemphphrase italic after 56
+begemphword italic 56
+endemphword italic 56
+
+begemphphrase bold 56
+endemphphrase bold after 56
+begemphword bold 56
+endemphword bold 56
+
+begemphphrase underline 56
+endemphphrase underline after 56
+begemphword underline 56
+endemphword underline 56
+
+capsletter 46
+begcapsword 456
+endcapsword 6
+
+numsign 3456
+
+#class of none-space characters that demand double dashes
+# Used in context lines later.
+#must be the first class defined.
+class charsWDoubleDash .,?!/:"'() # class w
+
+### Correct
+
+# Chars that don't require a space before percent and permille:
+class charsBeforePercent "(\x201e\x0084\x201c\x0093\x201d\x0094\x00ab\x00bb #class x
+noback correct `["%"] *
+noback correct `["\x2030"] *
+noback correct !$sx["%"] " %"
+noback correct !$sx["\x2030"] " \x2030"
+noback correct `["\x0089"] *
+noback correct !$sx["\x0089"] " \x2030"
+
+# Chars to be treated like digits when switching back to letter mode
+class extraDigits \x00bc\x00bd\x00be
+
+#Use the "correct" opcode to convert chars that can't be back-translated
+# and make the table more simple.
+
+# Dashes
+class dashes \x2013\x2014\x0096\x0097\x00ad
+noback correct %dashes "-"
+
+class quotes \x201e\x0084\x201c\x0093\x201d\x0094\x00ab\x00bb
+noback correct %quotes "\""
+
+class apostrophes `\x201a\x0082\x2039\x008b\x2018\x0091\x2019\x0092\x203a\x009b\x00b4
+noback correct %apostrophes "'"
+
+# Convert most single caps to lowercase
+
+#Special abbreviations with imbedded small letters.
+# Must be handled by case in this version of liblouis
+noback correct "KAbB" "KABB"
+noback correct "CUDiM" "CUDIM"
+
+swapcc UpperLower ABCDEFGHIJKLMNOPQRSTUVWXYZ\x0160\x0152\x017d\x0178\x00c0\x00c1\x00c2\x00c3\x00c4\x00c5\x00c6\x00c7\x00c8\x00c9\x00ca\x00cb\x00cc\x00cd\x00ce\x00cf\x00d0\x00d1\x00d2\x00d3\x00d4\x00d5\x00d6\x00d8\x00d9\x00da\x00db\x00dc\x00dd\x00de\x008a\x008c abcdefghijklmnopqrstuvwxyz\x0161\x0153\x017e\x00ff\x00e0\x00e1\x00e2\x00e3\x00e4\x00e5\x00e6\x00e7\x00e8\x00e9\x00ea\x00eb\x00ec\x00ed\x00ee\x00ef\x00f0\x00f1\x00f2\x00f3\x00f4\x00f5\x00f6\x00f8\x00f9\x00fa\x00fb\x00fc\x00fd\x00fe\x009a\x009c
+
+# I is a special case
+noback correct _$sp["I"]$sp "i"
+noback correct `["I"]$sp "i"
+noback correct _$sp["I"]~ "i"
+
+noback correct $sSpu[%UpperLower]$u %UpperLower
+noback correct `[%UpperLower]$u %UpperLower
+
+# Punctuations, math and numbers
+midnum , 2
+midnum . 3
+midnum - 36
+endnum - 36
+midnum / 34
+midnum : 25
+
+midnum ^ 45-346
+midnum \x00d7 45-3-3456
+
+# Punctuation
+prepunc " 2356
+postpunc " 2356
+prepunc - 36
+postpunc - 36
+always :- 25-36
+always ;- 23-36
+always --- 36-36-36
+always ---- 36-36-36-36
+always ----- 36-36-36-36-36
+
+# these characters must be separated from ")" by a letsign.
+class SepToRightpar Jj%'\x2030\x0089\x201a\x0082\x2039\x009b\x2018\x0091\x2019\x0092\x203a\x009b
+after SepToRightpar always ) 6-356
+
+prepunc ( 236
+postpunc ) 356
+
+always .) 3-356
+always ... 3-3-3
+
+always !! 235-235
+always !!! 235-235-235
+always !!!! 235-235-235-235
+always !!!!! 235-235-235-235-235
+
+### Context rules
+
+# Substitutions for joinnum rules with common math signs
+noback context $dy$s["-"$s]$dy @36
+noback context $dy$s["+"$s]$dy @235
+noback context $dy$s["\x00d7"$s]$dy @3
+noback context $dy$s["\x00f7"$s]$dy @256
+noback context $dy$s["="$s]$dy @2356
+
+# Space on each side of = when between letters or punctuation.
+noback context $lp["="]$lp @0-2356-0
+
+# Ensure two dashes where appropriate.
+noback context $w["-"]$w @36
+noback context $sw["-"]$sw @36-36
+noback context `["-"]$sw @36-36
+noback context $sw["-"]~ @36-36
+noback context !$sw["-"]~ @36
+noback context `["-"]~ @36-36
+
+#ensure dot 6 between a digit and a letter
+noback context $dy[]$u @6
+noback context $dy$Spm.[]$u @6
+
+# Ensure dot 6 as nocaps
+#noback context $U2-50[]$u @6
+
+### Pass 2
+
+noback pass2 @6-46-5 @46-5 # no letsign before cap letters with accent
+noback pass2 @45-6-46 * # don't touch tilde before capnoback pass2 @6-46 @46-6 # Ensure correct order
+
+# Ensure there is only one letsign
+ noback pass2 @6-6 @6
diff --git a/tables/da-dk-g16.ctb b/tables/da-dk-g16.ctb
new file mode 100644
index 0000000..b44bd73
--- /dev/null
+++ b/tables/da-dk-g16.ctb
@@ -0,0 +1,293 @@
+# Liblouis: Danish table for 6 dots grade 1 forward and backward translation
+#
+# Copyright (C) 2014-2017, Bue Vester-Andersen <bue@vester-andersen.dk>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# Version: Bue Vester-Andersen, 170604
+
+### Table Metadata
+
+#-name: Dansk fuldskrift 6-punkt
+#-index-name: Danish, uncontracted, 6-dot
+#-display-name: Danish 6-dot uncontracted braille
+
+#+locale: da
+#+type: literary
+#+contraction: no
+#+grade: 1
+#+dots: 6
+#+direction: both
+
+# Display opcodes
+include da-dk-octobraille.dis
+
+### Spaces
+
+# These ctrl-chars have to have a representation, so that they can be properly converted back and forth.
+space \t 2478 CHARACTER TABULATION
+space \n 678 LINE FEED (LF)
+space \v 1368 LINE TABULATION
+space \f 12378 FORM FEED (FF)
+space \r 257 CARRIAGE RETURN (CR)
+space \x00a0 a
+
+include spaces.uti
+
+### Character definitions
+
+# Definition of dot cells
+punctuation ! 235 EXCLAMATION MARK
+punctuation " 2356 QUOTATION MARK
+sign & 12346 AMPERSAND
+punctuation ' 4 APOSTROPHE
+punctuation ( 236 LEFT PARENTHESIS
+punctuation ) 356 RIGHT PARENTHESIS
+punctuation * 35 ASTERISK
+punctuation , 2 COMMA
+punctuation - 36 HYPHEN-MINUS
+punctuation . 3 FULL STOP
+punctuation / 34 SLASH
+punctuation : 25 COLON
+punctuation ; 23 SEMICOLON
+punctuation ? 26 QUESTION MARK
+include latinLetterDef6Dots.uti
+
+include digits6Dots.uti
+
+punctuation \x00a7 346 SECTION SIGN (0xa7)
+
+uplow \x00c5\x00e5 16 LATIN LETTER A WITH RING ABOVE
+uplow \x00c6\x00e6 345 LATIN LETTER AE
+uplow \x00d8\x00f8 246 LATIN LETTER O WITH STROKE
+uplow \x00dc\x00fc 1256 LATIN CAPITAL LETTER U WITH DIAERESIS
+math \x00f7 256 DIVISION SIGN
+
+# cover all other Braille patterns
+include braille-patterns.cti
+
+# Characters with two or more cells
+
+punctuation # 45-3456 NUMBER SIGN
+sign $ 45-256 DOLLAR SIGN
+math % 245-356 PERCENT SIGN
+#sign & 6-12346 AMPERSAND
+#punctuation * 6-35 ASTERISK
+math + 45-235 PLUS SIGN
+math < 45-134 LESS-THAN SIGN
+math = 45-2356 EQUALS SIGN
+math > 45-234 GREATER-THAN SIGN
+sign @ 45-1 COMMERCIAL AT
+punctuation [ 5-236 LEFT SQUARE BRACKET
+punctuation \\ 45-16 REVERSE SLASH
+punctuation ] 5-356 RIGHT SQUARE BRACKET
+punctuation ^ 45-346 CIRCUMFLEX ACCENT
+punctuation _ 45-36 LOW LINE
+punctuation ` 4 GRAVE ACCENT
+punctuation { 45-246 LEFT CURLY BRACKET
+punctuation | 4568 VERTICAL LINE
+punctuation } 45-135 RIGHT CURLY BRACKET
+punctuation ~ 467 TILDE (changed by pass 2 to not conflict with indicators
+
+# Misc unicode characters
+include da-dk-6miscChars.cti
+
+# Litdigits
+include litdigits6Dots.uti
+midendnumericmodechars /,.:^
+undefined 26
+
+### Braille indicators and special characters
+
+#hyphen - 36
+
+letsign 6
+
+# No letsign before capital letters or letters with accents
+
+noletsign ABCDEFGHIJKLMNOPQRSTUVWXYZ\x0160\x0152\x017d\x0178\x00c0\x00c1\x00c2\x00c3\x00c4\x00c5\x00c6\x00c7\x00c8\x00c9\x00ca\x00cb\x00cc\x00cd\x00ce\x00cf\x00d0\x00d1\x00d2\x00d3\x00d4\x00d5\x00d6\x00d8\x00d9\x00da\x00db\x00dc\x00dd\x00de\x008a\x008c\x008e
+noletsign i\x0161\x0153\x017e\x00ff\x00df\x00e0\x00e1\x00e2\x00e3\x00e7\x00e8\x00e9\x00ea\x00eb\x00ec\x00ed\x00ee\x00ef\x00f0\x00f1\x00f2\x00f3\x00f4\x00f5\x00f9\x00fa\x00fb\x00fd\x00fe\x009a\x009c
+noletsign abcdefghjklmnopqrstuvwxyz\x00e4\x00e5\x00e6\x00f6\x00f8\x00fc
+
+# Emphasis opcodes
+emphclass italic
+emphclass underline
+emphclass bold
+
+begemphphrase italic 56
+endemphphrase italic after 56
+begemphword italic 56
+endemphword italic 56
+
+begemphphrase bold 56
+endemphphrase bold after 56
+begemphword bold 56
+endemphword bold 56
+
+begemphphrase underline 56
+endemphphrase underline after 56
+begemphword underline 56
+endemphword underline 56
+
+capsletter 46
+begcapsword 456
+endcapsword 6
+multind 6-46 letsign capsletter
+multind 46-6 capsletter letsign
+multind 6-456 letsign begcapsword
+
+numsign 3456
+multind 6-3456 letsign numsign
+
+#class of none-space characters that demand double dashes
+# Used in context lines later.
+#must be the first class defined.
+class charsWDoubleDash .,?!/:"'() # class w
+
+### Correct - forward translation
+
+# Chars that don't require a space before percent and permille:
+class charsBeforePercent "(\x201e\x0084\x201c\x0093\x201d\x0094\x00ab\x00bb #class x
+noback correct `["%"] *
+noback correct !$sx["%"] " %"
+noback correct `["\x2030"] *
+noback correct !$sx["\x2030"] " \x2030"
+noback correct `["\x0089"] *
+noback correct !$sx["\x0089"] " \x2030"
+
+# Chars to be treated like digits when switching back to letter mode
+class extraDigits \x00bc\x00bd\x00be
+
+#Use the "correct" opcode to convert chars that can't be back-translated
+# and make the table more simple.
+
+# Dashes
+class dashes \x2013\x2014\x0096\x0097\x00ad
+noback correct %dashes "-"
+
+class quotes \x201e\x0084\x201c\x0093\x201d\x0094\x00ab\x00bb
+noback correct %quotes "\""
+
+class apostrophes `\x201a\x0082\x2039\x008b\x2018\x0091\x2019\x0092\x203a\x009b\x00b4
+noback correct %apostrophes "'"
+
+### Correct - backward translation
+
+# characters that may get mangled by the insertion of extra letsigns
+nofor correct "\x2818" "~"
+#nofor correct "\x282f" "&"
+#nofor correct "\x2814" "*"
+
+# Try to distinguish between times (\x00d7) and bullit (\x2022),
+# which share the same Braille representation.
+nofor correct `["\x00d7"] "\x2022"
+# nofor correct $d["\s\x00d7\s"]$d * #apparently doesn't work now
+nofor correct ["\x00d7"]!$d "\x2022"
+nofor correct !$d["\x00d7"] "\x2022"
+
+nofor correct "\x28a0" ? # Extraneous endcaps signs
+#nofor correct "\x2820" ?
+nofor correct "~\\456/" "|"
+
+### Pass 1 - Forward and backward
+
+# Punctuations, math and numbers
+#midnum , 2
+#midnum . 3
+#midnum - 36
+endnum - 36
+#midnum / 34
+#midnum : 25
+
+midnum ^ 45-346
+midnum \x00d7 45-3
+
+# Punctuation
+prepunc " 2356
+postpunc " 2356
+prepunc - 36
+postpunc - 36
+nofor always \s-\s 0-36-36-0
+always :- 25-36
+always ;- 23-36
+always --- 36-36-36
+always ---- 36-36-36-36
+always ----- 36-36-36-36-36
+
+# these characters must be separated from ")" by a letsign.
+class SepToRightpar Jj%'\x2030\x0089\x201a\x0082\x2039\x009b\x2018\x0091\x2019\x0092\x203a\x009b
+after SepToRightpar always ) 6-356
+
+prepunc ( 236
+postpunc ) 356
+
+always .) 3-356
+always ... 3-3-3
+
+always !! 235-235
+always !!! 235-235-235
+always !!!! 235-235-235-235
+always !!!!! 235-235-235-235-235
+
+### Context rules - forward translation
+
+# Ensure two dashes where appropriate.
+noback context $w["-"]$w @36
+noback context $sw["-"]$sw @36-36
+noback context `["-"]$sw @36-36
+noback context $sw["-"]~ @36-36
+noback context !$sw["-"]~ @36
+noback context `["-"]~ @36-36
+
+#ensure dot 6 between a digit and a letter
+noback context $dy[]$u @6
+noback context $dy$Spm.[]$u @6
+
+### context - backward translation
+
+# Ensure the correct number of dashes
+nofor context @36[@36-36] "--"
+nofor context [@36-36]@36 "--"
+nofor context $w[@36-36]$w "--"
+nofor context $sw[@36-36]$sw "-"
+nofor context `[@36-36]$sw "-"
+nofor context $sw[@36-36]~ "-"
+nofor context `@36-36~ "-"
+
+
+### Pass 2 - forward translation
+
+# Correct tilde and vertical line
+noback pass2 @467 @45-6
+noback pass2 @4568 @45-456
+
+noback pass2 @6-46-5 @46-5 # no letsign before cap letters with accent
+noback pass2 @6-46 @46-6 # Ensure correct order
+
+ ### Pass 2 - backward
+
+### Pass 3 - forward translation
+
+# Ensure there is only one letsign
+ noback pass3 @6-6 @6
+
+
+### Pass 3 - backward translation
+
+# save ~ and | before inserting extra letsigns and endcapsword in pass 2.
+nofor pass3 @45-6 @468 # Create alternative representation of "~"
+nofor pass3 @45-456 @4568
diff --git a/tables/da-dk-g18.ctb b/tables/da-dk-g18.ctb
new file mode 100644
index 0000000..c045a7e
--- /dev/null
+++ b/tables/da-dk-g18.ctb
@@ -0,0 +1,355 @@
+# Liblouis: Danish table for 8 dots grade 1
+#
+# Copyright (C) 2014-2017, Bue Vester-Andersen <bue@vester-andersen.dk>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#------------
+#
+# This is the Danish table for 8 dots grade 1 (fuldskrift).
+# Use this table for translation and back-translation of Danish 8 dots grade 1.
+#
+# Version: Bue Vester-Andersen, 170604
+
+### Table Metadata
+
+#-name: Dansk fuldskrift 8-punkt
+#-index-name: Danish, uncontracted, 8-dot
+#-display-name: Danish 8-dot uncontracted braille
+
+#+locale: da
+#+type: literary
+#+contraction: no
+#+grade: 1
+#+dots: 8
+#+direction: both
+
+# Display upcodes
+include da-dk-octobraille.dis
+
+### Character definitions ###
+
+sign \x0000 8 NULL
+sign \x0001 178 START OF HEADING
+sign \x0002 1278 START OF TEXT
+sign \x0003 1478 END OF TEXT
+sign \x0004 14578 END OF TRANSMISSION
+sign \x0005 24568 ENQUIRY
+sign \x0006 12478 ACKNOWLEDGE
+sign \x0007 124578 BELL
+sign \x0008 12578 BACKSPACE
+space \t 2478 CHARACTER TABULATION
+space \n 678 LINE FEED (LF)
+space \v 1368 LINE TABULATION
+space \f 12378 FORM FEED (FF)
+space \r 257 CARRIAGE RETURN (CR)
+sign \x000e 134578 SHIFT OUT
+sign \x000f 12358 SHIFT IN
+sign \x0010 123478 DATA LINK ESCAPE
+sign \x0011 1234578 DEVICE CONTROL ONE
+sign \x0012 13568 DEVICE CONTROL TWO
+sign \x0013 4578 DEVICE CONTROL THREE
+sign \x0014 268 DEVICE CONTROL FOUR
+sign \x0015 13678 NEGATIVE ACKNOWLEDGE
+sign \x0016 278 SYNCHRONOUS IDLE
+sign \x0017 3578 END OF TRANSMISSION BLOCK
+sign \x0018 78 CANCEL
+sign \x0019 68 END OF MEDIUM
+sign \x001a 135678 SUBSTITUTE
+sign \x001b 2678 ESCAPE
+sign \x001c 45678 INFORMATION SEPARATOR FOUR
+sign \x001d 12368 INFORMATION SEPARATOR THREE
+sign \x001e 1234678 INFORMATION SEPARATOR TWO
+sign \x001f 235678 INFORMATION SEPARATOR ONE
+space \s 0 SPACE
+punctuation ! 235 EXCLAMATION MARK
+punctuation " 2356 QUOTATION MARK
+punctuation # 34568 NUMBER SIGN
+sign $ 25678 DOLLAR SIGN
+math % 24578 PERCENT SIGN
+sign & 123468 AMPERSAND
+punctuation ' 4 APOSTROPHE
+punctuation ( 2368 LEFT PARENTHESIS
+punctuation ) 3568 RIGHT PARENTHESIS
+punctuation * 35 ASTERISK
+math + 2358 PLUS SIGN
+punctuation , 2 COMMA
+punctuation - 368 HYPHEN-MINUS
+punctuation . 3 FULL STOP
+punctuation / 348 SLASH
+include digits8Dots.uti
+punctuation : 25 COLON
+punctuation ; 23 SEMICOLON
+math < 358 LESS-THAN SIGN
+math = 23568 EQUALS SIGN
+math > 267 GREATER-THAN SIGN
+punctuation ? 26 QUESTION MARK
+sign @ 478 COMMERCIAL AT
+uppercase A 17 LATIN CAPITAL LETTER A
+uppercase B 127 LATIN CAPITAL LETTER B
+uppercase C 147 LATIN CAPITAL LETTER C
+uppercase D 1457 LATIN CAPITAL LETTER D
+uppercase E 157 LATIN CAPITAL LETTER E
+uppercase F 1247 LATIN CAPITAL LETTER F
+uppercase G 12457 LATIN CAPITAL LETTER G
+uppercase H 1257 LATIN CAPITAL LETTER H
+uppercase I 247 LATIN CAPITAL LETTER I
+uppercase J 2457 LATIN CAPITAL LETTER J
+uppercase K 137 LATIN CAPITAL LETTER K
+uppercase L 1237 LATIN CAPITAL LETTER L
+uppercase M 1347 LATIN CAPITAL LETTER M
+uppercase N 13457 LATIN CAPITAL LETTER N
+uppercase O 1357 LATIN CAPITAL LETTER O
+uppercase P 12347 LATIN CAPITAL LETTER P
+uppercase Q 123457 LATIN CAPITAL LETTER Q
+uppercase R 12357 LATIN CAPITAL LETTER R
+uppercase S 2347 LATIN CAPITAL LETTER S
+uppercase T 23457 LATIN CAPITAL LETTER T
+uppercase U 1367 LATIN CAPITAL LETTER U
+uppercase V 12367 LATIN CAPITAL LETTER V
+uppercase W 24567 LATIN CAPITAL LETTER W
+uppercase X 13467 LATIN CAPITAL LETTER X
+uppercase Y 134567 LATIN CAPITAL LETTER Y
+uppercase Z 13567 LATIN CAPITAL LETTER Z
+punctuation [ 23678 LEFT SQUARE BRACKET
+punctuation \\ 347 REVERSE SLASH
+punctuation ] 35678 RIGHT SQUARE BRACKET
+punctuation ^ 12348 CIRCUMFLEX ACCENT
+punctuation _ 3678 LOW LINE
+punctuation ` 5 GRAVE ACCENT
+lowercase a 1 LATIN SMALL LETTER A
+lowercase b 12 LATIN SMALL LETTER B
+lowercase c 14 LATIN SMALL LETTER C
+lowercase d 145 LATIN SMALL LETTER D
+lowercase e 15 LATIN SMALL LETTER E
+lowercase f 124 LATIN SMALL LETTER F
+lowercase g 1245 LATIN SMALL LETTER G
+lowercase h 125 LATIN SMALL LETTER H
+lowercase i 24 LATIN SMALL LETTER I
+lowercase j 245 LATIN SMALL LETTER J
+lowercase k 13 LATIN SMALL LETTER K
+lowercase l 123 LATIN SMALL LETTER L
+lowercase m 134 LATIN SMALL LETTER M
+lowercase n 1345 LATIN SMALL LETTER N
+lowercase o 135 LATIN SMALL LETTER O
+lowercase p 1234 LATIN SMALL LETTER P
+lowercase q 12345 LATIN SMALL LETTER Q
+lowercase r 1235 LATIN SMALL LETTER R
+lowercase s 234 LATIN SMALL LETTER S
+lowercase t 2345 LATIN SMALL LETTER T
+lowercase u 136 LATIN SMALL LETTER U
+lowercase v 1236 LATIN SMALL LETTER V
+lowercase w 2456 LATIN SMALL LETTER W
+lowercase x 1346 LATIN SMALL LETTER X
+lowercase y 13456 LATIN SMALL LETTER Y
+lowercase z 1356 LATIN SMALL LETTER Z
+punctuation { 123678 LEFT CURLY BRACKET
+punctuation | 4568 VERTICAL LINE
+punctuation } 345678 RIGHT CURLY BRACKET
+punctuation ~ 467 TILDE
+sign \x007f 7 DELETE
+sign \x20AC 1578 #EURO SIGN (0x80)
+sign \x0081 45 <control-0081>
+punctuation \x201A 457 #Low single quote (0x82)
+sign \x0192 58 #Flurihn (0x83)
+punctuation \x201E 2378 #Low quote (0x84)
+letter \x2020 2357 #Dagger (0x86
+letter \x2021 23578 #Double dagger (0x87
+letter \x02c6 5678 #Modifier letter circumflex (0x88)
+math \x2030 245678 #permille sign (0x89)
+uppercase \x0160 23478 #LATIN CAPITAL LETTER S WITH CARON (0x8a)
+punctuation \x2039 456 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK (0x8b)
+uppercase \x0152 13578 #LATIN CAPITAL LIGATURE OE (0x8c)
+sign \x008d 3567 REVERSE LINE FEED (not defined in cp1252)
+uppercase \x017d 3467 #LATIN CAPITAL LETTER Z WITH CARON (0x8e)
+letter \x008f 27 SINGLE SHIFT THREE (not defined in cp1252)
+letter \x0090 357 DEVICE CONTROL STRING (not defined in cp1252)
+punctuation \x2018 47 #LEFT SINGLE QUOTATION MARK (0x91)
+punctuation \x2019 48 #RIGHT SINGLE QUOTATION MARK (0x92)
+punctuation \x201c 237 #LEFT DOUBLE QUOTATION MARK (0x93)
+punctuation \x201d 568 #RIGHT DOUBLE QUOTATION MARK (0x94)
+sign \x2022 37 #Bullit (0x95)
+sign \x02DC 46 #SMALL TILDE (0x98)
+sign \x2122 234578 #TRADE MARK SIGN (0x99)
+lowercase \x0161 2348 #LATIN SMALL LETTER S WITH CARON (0x9a)
+punctuation \x203A 4567 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (0x9b)
+lowercase \x0153 1358 #LATIN SMALL LIGATURE OE (0x9c)
+letter \x009d 2567 OPERATING SYSTEM COMMAND
+lowercase \x017E 346 #LATIN SMALL LETTER Z WITH CARON (0x9e)
+uppercase \x0178 2345678 #LATIN CAPITAL LETTER Y WITH DIAERESIS (0x9f)
+punctuation \x00a0 23458 NO-BREAK SPACE (0xa0)
+punctuation \x00a1 256 INVERTED EXCLAMATION MARK )0xa1)
+punctuation \x00a2 2578 CENT SIGN (0xa2)
+punctuation \x00a3 1238 POUND SIGN (0xa3)
+punctuation \x00a4 2367 CURRENCY SIGN (0xa4)
+punctuation \x00a5 67 YEN SIGN (0xa5)
+punctuation \x00a6 3478 BROKEN BAR (0xa6)
+punctuation \x00a7 578 SECTION SIGN (0xa7)
+punctuation \x00a8 56 DIAERESIS (0xa8)
+punctuation \x00a9 134678 COPYRIGHT SIGN (0xa9)
+letter \x00aa 234678 FEMININE ORDINAL INDICATOR (0xaa)
+punctuation \x00ab 57 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (0xab)
+punctuation \x00ac 34567 NOT SIGN (0xac)
+letter \x00ad 378 SOFT HYPHEN (0xad)
+punctuation \x00ae 123578 REGISTERED SIGN (0xae)
+punctuation \x00af 23567 MACRON (0xaf)
+sign \x00b0 356 DEGREE SIGN (0xb0)
+math \x00b1 123458 PLUS-MINUS SIGN
+punctuation \x00b2 238 SUPERSCRIPT TWO
+punctuation \x00b3 258 SUPERSCRIPT THREE
+punctuation \x00b4 468 ACUTE ACCENT
+sign \x00b5 236 MICRO SIGN
+punctuation \x00b6 1234568 PILCROW SIGN
+punctuation \x00b7 38 MIDDLE DOT
+punctuation \x00b8 4678 CEDILLA
+punctuation \x00b9 28 SUPERSCRIPT ONE
+letter \x00ba 12345678 MASCULINE ORDINAL INDICATOR
+punctuation \x00bb 567 RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+punctuation \x00bc 13458 VULGAR FRACTION ONE QUARTER
+punctuation \x00bd 458 VULGAR FRACTION ONE HALF
+punctuation \x00be 3456 VULGAR FRACTION THREE QUARTERS
+punctuation \x00bf 34 INVERTED QUESTION MARK
+uppercase \x00c0 123567 LATIN CAPITAL LETTER A WITH GRAVE
+uppercase \x00c1 1235678 LATIN CAPITAL LETTER A WITH ACUTE
+uppercase \x00c2 1678 LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+uppercase \x00c3 14678 LATIN CAPITAL LETTER A WITH TILDE
+uppercase \x00c4 34578 LATIN CAPITAL LETTER A WITH DIAERESIS
+uppercase \x00c5 167 LATIN CAPITAL LETTER A WITH RING ABOVE
+uppercase \x00c6 3457 LATIN CAPITAL LETTER AE
+uppercase \x00c7 123467 LATIN CAPITAL LETTER C WITH CEDILLA
+uppercase \x00c8 23467 LATIN CAPITAL LETTER E WITH GRAVE
+uppercase \x00c9 1234567 LATIN CAPITAL LETTER E WITH ACUTE
+uppercase \x00ca 1267 LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+uppercase \x00cb 12467 LATIN CAPITAL LETTER E WITH DIAERESIS
+uppercase \x00cc 15678 LATIN CAPITAL LETTER I WITH GRAVE
+uppercase \x00cd 12678 LATIN CAPITAL LETTER I WITH ACUTE
+uppercase \x00ce 1467 LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+uppercase \x00cf 124567 LATIN CAPITAL LETTER I WITH DIAERESIS
+uppercase \x00d0 1345678 LATIN CAPITAL LETTER ETH
+uppercase \x00d1 1245678 LATIN CAPITAL LETTER N WITH TILDE
+uppercase \x00d2 124678 LATIN CAPITAL LETTER O WITH GRAVE
+uppercase \x00d3 34678 LATIN CAPITAL LETTER O WITH ACUTE
+uppercase \x00d4 14567 LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+uppercase \x00d5 145678 LATIN CAPITAL LETTER O WITH TILDE
+uppercase \x00d6 24678 LATIN CAPITAL LETTER O WITH DIAERESIS
+math \x00d7 13468 MULTIPLICATION SIGN
+uppercase \x00d8 2467 LATIN CAPITAL LETTER O WITH STROKE
+uppercase \x00d9 234567 LATIN CAPITAL LETTER U WITH GRAVE
+uppercase \x00da 125678 LATIN CAPITAL LETTER U WITH ACUTE
+uppercase \x00db 1567 LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+uppercase \x00dc 12567 LATIN CAPITAL LETTER U WITH DIAERESIS
+uppercase \x00dd 13478 LATIN CAPITAL LETTER Y WITH ACUTE (infinite?)
+uppercase \x00de 1378 LATIN CAPITAL LETTER THORN
+lowercase \x00df 23468 LATIN SMALL LETTER SHARP S
+lowercase \x00e0 12356 LATIN SMALL LETTER A WITH GRAVE
+lowercase \x00e1 123568 LATIN SMALL LETTER A WITH ACUTE
+lowercase \x00e2 168 LATIN SMALL LETTER A WITH CIRCUMFLEX
+lowercase \x00e3 1468 LATIN SMALL LETTER A WITH TILDE
+lowercase \x00e4 3458 LATIN SMALL LETTER A WITH DIAERESIS
+lowercase \x00e5 16 LATIN SMALL LETTER A WITH RING ABOVE
+lowercase \x00e6 345 LATIN SMALL LETTER AE
+lowercase \x00e7 12346 LATIN SMALL LETTER C WITH CEDILLA
+lowercase \x00e8 2346 LATIN SMALL LETTER E WITH GRAVE
+lowercase \x00e9 123456 LATIN SMALL LETTER E WITH ACUTE
+lowercase \x00ea 126 LATIN SMALL LETTER E WITH CIRCUMFLEX
+lowercase \x00eb 1246 LATIN SMALL LETTER E WITH DIAERESIS
+lowercase \x00ec 1568 LATIN SMALL LETTER I WITH GRAVE
+lowercase \x00ed 1268 LATIN SMALL LETTER I WITH ACUTE
+lowercase \x00ee 146 LATIN SMALL LETTER I WITH CIRCUMFLEX
+lowercase \x00ef 12456 LATIN SMALL LETTER I WITH DIAERESIS
+lowercase \x00f0 134568 LATIN SMALL LETTER ETH
+lowercase \x00f1 124568 LATIN SMALL LETTER N WITH TILDE
+lowercase \x00f2 12468 LATIN SMALL LETTER O WITH GRAVE
+lowercase \x00f3 3468 LATIN SMALL LETTER O WITH ACUTE
+lowercase \x00f4 1456 LATIN SMALL LETTER O WITH CIRCUMFLEX
+lowercase \x00f5 14568 LATIN SMALL LETTER O WITH TILDE
+lowercase \x00f6 2468 LATIN SMALL LETTER O WITH DIAERESIS
+math \x00f7 2568 DIVISION SIGN
+lowercase \x00f8 246 LATIN SMALL LETTER O WITH STROKE
+lowercase \x00f9 23456 LATIN SMALL LETTER U WITH GRAVE
+lowercase \x00fa 12568 LATIN SMALL LETTER U WITH ACUTE
+lowercase \x00fb 156 LATIN SMALL LETTER U WITH CIRCUMFLEX
+lowercase \x00fc 1256 LATIN SMALL LETTER U WITH DIAERESIS
+lowercase \x00fd 1348 LATIN SMALL LETTER Y WITH ACUTE
+lowercase \x00fe 138 LATIN SMALL LETTER THORN
+lowercase \x00ff 234568 LATIN SMALL LETTER Y WITH DIAERESIS
+
+# In CP-1252 the following chars are different from Unicode.
+# This placement ensures that Liblouis will always return the unicode when back-translating.
+sign \x0080 1578 #EURO SIGN (0x80)
+punctuation \x0082 457 #Low single quote (0x82)
+sign \x0083 58 #Flurihn (0x83)
+punctuation \x0084 2378 #Low quote (0x84)
+letter \x0086 2357 #Dagger (0x86
+letter \x0087 23578 #Double dagger (0x87
+letter \x0088 5678 #Modifier letter circumflex (0x88)
+math \x0089 245678 #permille sign (0x89)
+uppercase \x008a 23478 #LATIN LETTER S WITH CARON (0x8a)
+lowercase \x009a 2348
+punctuation \x008b 456 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK (0x8b)
+uppercase \x008c 13578 #LATIN LIGATURE OE (0x8c)
+lowercase \x009c 1358
+uppercase \x008e 3467 #LATIN CAPITAL LETTER Z WITH CARON (0x8e)
+lowercase \x009e 346
+punctuation \x0091 47 #LEFT SINGLE QUOTATION MARK (0x91)
+punctuation \x0092 48 #RIGHT SINGLE QUOTATION MARK (0x92)
+punctuation \x0093 237 #LEFT DOUBLE QUOTATION MARK (0x93)
+punctuation \x0094 568 #RIGHT DOUBLE QUOTATION MARK (0x94)
+sign \x0095 37 #Bullit (0x95)
+sign \x0098 46 #SMALL TILDE (0x98)
+sign \x0099 234578 #TRADE MARK SIGN (0x99)
+punctuation \x009b 4567 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (0x9b)
+uppercase \x009f 2345678 #LATIN CAPITAL LETTER Y WITH DIAERESIS (0x9f)
+
+#Unicode Braille patterns
+include braille-patterns.cti
+
+# characters that have letsign as part of their definition
+# (to be removed when the alwaysletsign opcode has been implemented).
+
+punctuation \x2026 6-3-3-3 #Elipsis (0x85)
+noback punctuation \x0085 6-3-3-3 #Elipsis (0x85)
+letter \x2013 6-36 #EN DASH (0x96)
+noback sign \x0096 6-36 #EN DASH (0x96)
+letter \x2014 6-367 #Em DASH (0x97)
+noback sign \x0097 6-367 #Em DASH (0x97)
+
+# Misc unicode characters
+include da-dk-8miscChars.cti
+
+# Rules for grade 1 and grade 2
+
+# Emphasis opcodes
+emphclass italic
+emphclass underline
+emphclass bold
+
+begemphphrase italic 56
+endemphphrase italic after 56
+begemphword italic 56
+endemphword italic 56
+
+begemphphrase bold 56
+endemphphrase bold after 56
+begemphword bold 56
+endemphword bold 56
+
+begemphphrase underline 56
+endemphphrase underline after 56
+begemphword underline 56
+endemphword underline 56
+
diff --git a/tables/da-dk-g26-lit.ctb b/tables/da-dk-g26-lit.ctb
new file mode 100644
index 0000000..f0569ce
--- /dev/null
+++ b/tables/da-dk-g26-lit.ctb
@@ -0,0 +1,875 @@
+# Liblouis: Danish table for 6 dots grade 2 forward translation (literary)
+#
+# Copyright (C) 2014-2017, Bue Vester-Andersen <bue@vester-andersen.dk>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+# This table is for 6 dots grade 2 literary Braille, embossable, not meant for back-translation.
+#
+# Version: Bue Vester-Andersen, 170604
+
+### Table Metadata
+
+#-name: Dansk forkortet 6-punkt
+#-index-name: Danish, contracted, 6-dot
+#-display-name: Danish 6-dot contracted braille
+
+#+locale: da
+#+type: literary
+#+contraction: full
+#+grade: 2
+#+dots: 6
+#+direction: forward
+
+#-has-nocross: yes
+
+# Display opcodes
+include da-dk-octobraille.dis
+
+### Spaces
+
+# These ctrl-chars have to have a representation, so that they can be properly converted back and forth.
+space \t 2478 CHARACTER TABULATION
+space \n 678 LINE FEED (LF)
+space \v 1368 LINE TABULATION
+space \f 12378 FORM FEED (FF)
+space \r 257 CARRIAGE RETURN (CR)
+space \x00a0 a
+
+include spaces.uti
+
+### Character definitions
+
+# Definition of dot cells
+punctuation ! 235 EXCLAMATION MARK
+punctuation " 2356 QUOTATION MARK
+punctuation ' 4 APOSTROPHE
+punctuation ( 236 LEFT PARENTHESIS
+punctuation ) 356 RIGHT PARENTHESIS
+punctuation , 2 COMMA
+punctuation - 36 HYPHEN-MINUS
+punctuation . 3 FULL STOP
+punctuation / 34 SLASH
+punctuation : 25 COLON
+punctuation ; 23 SEMICOLON
+punctuation ? 26 QUESTION MARK
+uplow Aa 1
+uplow Bb 12
+uplow Cc 14
+uplow Dd 145
+uplow Ee 15
+uplow Ff 124
+uplow Gg 1245
+uplow Hh 125
+uplow Ii 24
+uplow Jj 245
+uplow Kk 13
+uplow Ll 123
+uplow Mm 134
+uplow Nn 1345
+uplow Oo 135
+uplow Pp 1234
+uplow Rr 1235
+uplow Ss 234
+uplow Tt 2345
+uplow Uu 136
+uplow Vv 1236
+uplow Yy 13456
+
+#use 8 dots for the following chars to avoid conflict with indicators
+uplow Qq 123457
+uplow Ww 24567
+uplow Xx 13467
+uplow Zz 13567
+punctuation | 4568 VERTICAL LINE
+punctuation ~ 467 TILDE (changed by pass 2 to not conflict with indicators
+uplow \x00dc\x00fc 12567
+
+include digits6Dots.uti
+
+punctuation \x00a7 346 SECTION SIGN (0xa7)
+
+uplow \x00c5\x00e5 16 LATIN LETTER A WITH RING ABOVE
+uplow \x00c6\x00e6 345 LATIN LETTER AE
+uplow \x00d8\x00f8 246 LATIN LETTER O WITH STROKE
+
+# cover all other Braille patterns
+include braille-patterns.cti
+
+# Characters with two or more cells
+
+punctuation # 45-3456 NUMBER SIGN
+sign $ 45-256 DOLLAR SIGN
+math % 245-356 PERCENT SIGN
+sign & 6-12346 AMPERSAND
+punctuation * 6-35 ASTERISK
+math + 45-235 PLUS SIGN
+math < 45-134 LESS-THAN SIGN
+math = 45-2356 EQUALS SIGN
+math > 45-234 GREATER-THAN SIGN
+sign @ 45-1 COMMERCIAL AT
+punctuation [ 5-236 LEFT SQUARE BRACKET
+punctuation \\ 45-16 REVERSE SLASH
+punctuation ] 5-356 RIGHT SQUARE BRACKET
+punctuation ^ 45-346 CIRCUMFLEX ACCENT
+punctuation _ 45-36 LOW LINE
+punctuation ` 4 GRAVE ACCENT
+punctuation { 45-246 LEFT CURLY BRACKET
+punctuation } 45-135 RIGHT CURLY BRACKET
+math \x00f7 45-256 DIVISION SIGN
+
+# Misc unicode characters
+include da-dk-6miscChars.cti
+
+# Litdigits
+include litdigits6Dots.uti
+
+undefined 26
+
+### Braille indicators and special characters
+
+#hyphen - 36
+
+letsign 6
+
+# No letsign before capital letters or letters with accents
+
+noletsign I\x0160\x0152\x017d\x0178\x00c0\x00c1\x00c2\x00c3\x00c7\x00c8\x00c9\x00ca\x00cb\x00cc\x00cd\x00ce\x00cf\x00d0\x00d1\x00d2\x00d3\x00d4\x00d5\x00d9\x00da\x00db\x00dc\x00dd\x00de\x008a\x008c\x008e
+noletsign i\x0161\x0153\x017e\x00ff\x00df\x00e0\x00e1\x00e2\x00e3\x00e7\x00e8\x00e9\x00ea\x00eb\x00ec\x00ed\x00ee\x00ef\x00f0\x00f1\x00f2\x00f3\x00f4\x00f5\x00f9\x00fa\x00fb\x00fd\x00fe\x009a\x009c
+
+# Emphasis opcodes
+emphclass italic
+emphclass underline
+emphclass bold
+
+begemphphrase italic 56
+endemphphrase italic after 56
+begemphword italic 56
+endemphword italic 56
+
+begemphphrase bold 56
+endemphphrase bold after 56
+begemphword bold 56
+endemphword bold 56
+
+begemphphrase underline 56
+endemphphrase underline after 56
+begemphword underline 56
+endemphword underline 56
+
+capsletter 46
+begcapsword 456
+endcapsword 68 # Used during back-translation to stop overflow of capsword
+multind 6-46 letsign capsletter
+multind 46-6 capsletter letsign
+multind 6-456 letsign begcapsword
+multind 68-6-46 endcapsword letsign capsletter
+multind 68-6-456 endcapsword letsign begcapsword
+multind 68-6 endcapsword letsign
+
+numsign 3456
+multind 6-3456 letsign numsign
+
+#class of none-space characters that demand double dashes
+# Used in context lines later.
+#must be the first class defined.
+class charsWDoubleDash .,?!/:"'() # class w
+
+### Correct - forward translation
+
+# Chars that don't require a space before percent and permille:
+class charsBeforePercent "(\x201e\x0084\x201c\x0093\x201d\x0094\x00ab\x00bb #class x
+noback correct `["%"] *
+noback correct !$sx["%"] " %"
+noback correct `["\x2030"] *
+noback correct !$sx["\x2030"] " \x2030"
+noback correct `["\x0089"] *
+noback correct !$sx["\x0089"] " \x2030"
+
+# Chars to be treated like digits when switching back to letter mode
+class extraDigits \x00bc\x00bd\x00be
+
+#Use the "correct" opcode to convert chars that can't be back-translated
+# and make the table more simple.
+
+# Dashes
+class dashes \x2013\x2014\x0096\x0097\x00ad
+noback correct %dashes "-"
+
+class quotes \x201e\x0084\x201c\x0093\x201d\x0094\x00ab\x00bb
+noback correct %quotes "\""
+
+class apostrophes `\x201a\x0082\x2039\x008b\x2018\x0091\x2019\x0092\x203a\x009b\x00b4
+noback correct %apostrophes "'"
+
+# Convert most single caps to lowercase
+
+#Special abbreviations with imbedded small letters.
+# Must be handled by case in this version of liblouis
+noback correct "KAbB" "KABB"
+noback correct "CUDiM" "CUDIM"
+
+swapcc UpperLower ABCDEFGHIJKLMNOPQRSTUVWXYZ\x0160\x0152\x017d\x0178\x00c0\x00c1\x00c2\x00c3\x00c4\x00c5\x00c6\x00c7\x00c8\x00c9\x00ca\x00cb\x00cc\x00cd\x00ce\x00cf\x00d0\x00d1\x00d2\x00d3\x00d4\x00d5\x00d6\x00d8\x00d9\x00da\x00db\x00dc\x00dd\x00de\x008a\x008c abcdefghijklmnopqrstuvwxyz\x0161\x0153\x017e\x00ff\x00e0\x00e1\x00e2\x00e3\x00e4\x00e5\x00e6\x00e7\x00e8\x00e9\x00ea\x00eb\x00ec\x00ed\x00ee\x00ef\x00f0\x00f1\x00f2\x00f3\x00f4\x00f5\x00f6\x00f8\x00f9\x00fa\x00fb\x00fc\x00fd\x00fe\x009a\x009c
+
+# I is a special case
+noback correct _$sp["I"]$sp "i"
+noback correct `["I"]$sp "i"
+noback correct _$sp["I"]~ "i"
+
+noback correct $sSpu[%UpperLower]$u %UpperLower
+noback correct `[%UpperLower]$u %UpperLower
+
+### Pass 1
+
+# Punctuations, math and numbers
+midnum , 2
+midnum . 3
+#midnum - 36
+endnum - 36
+midnum / 34
+midnum : 25
+nofor midnum ^ 346
+nofor midnum ^ 45-346
+
+midnum ^ 45-346
+midnum \x00d7 45-3-3456
+
+# Punctuation
+prepunc " 2356
+postpunc " 2356
+always /\s 6-34-0
+always \s/ 0-6-34
+prepunc - 36
+postpunc - 36
+always :- 25-36
+always ;- 23-36
+always --- 36-36-36
+always ---- 36-36-36-36
+always ----- 36-36-36-36-36
+# Star enclosed by parentheses
+always (*) 236-35-356
+
+before punctuation before sign always ( 6-236
+
+# these characters must be separated from ")" by a letsign.
+class SepToRightpar Jj%'\x2030\x0089\x201a\x0082\x2039\x009b\x2018\x0091\x2019\x0092\x203a\x009b
+after SepToRightpar always ) 6-356
+after punctuation after sign always ) 6-356
+
+prepunc ( 236
+postpunc ) 356
+always .) 3-356
+always ( 6-236
+always ) 6-356
+
+always ... 3-3-3
+
+# Exclamation and "fra"
+always fra! 124-1235-1-235
+always !fra 235-124-1235-1
+always ?! 26-6-235
+always )! 356-6-235
+always (!) 236-6-235-356
+always "fra" 2356-124-1235-1-2356
+always "!" 2356-6-235-2356
+always !! 235-235
+always !!! 235-235-235
+always !!!! 235-235-235-235
+always !!!!! 235-235-235-235-235
+always '! 4-6-235
+always \s! 0-6-235
+prepunc ! 6-235
+always \x00a1 6-256
+
+### Contractions ###
+
+#Special sequences, urls emails and file names.
+
+nocont $
+nocont \x005c
+nocont @
+nocont ://
+nocont www
+nocont .com
+nocont .dk
+nocont .eu
+nocont .edu
+nocont .gov
+nocont .mil
+nocont .net
+nocont .org
+nocont .uk
+nocont .doc
+nocont .exe
+nocont .htm
+nocont .tex
+nocont .txt
+nocont .gif
+nocont .jpg
+nocont .png
+nocont .wav
+nocont .tar
+nocont .zip
+
+# Ensure no contractions in English ordinal numbers
+endnum nd 6-1345-145
+endnum st 6-234-2345
+endnum ve 6-1236-15
+
+#Words
+word af 356
+always 'af 4-1-124
+word aldrig 1-35
+word aig =
+word alle 1-15
+begnum ae 6-1-15
+contraction ae
+word allerede 1-123-1235
+begnum alr 6-1-123-1235
+contraction alr
+word alligevel 1-123-1236
+begnum alv 6-1-123-1236
+contraction alv
+word altid 1-2345-145
+begnum atd 6-1-2345-145
+contraction atd
+word altså 1-16
+begnum aå 6-1-16
+contraction aå
+word at 1
+
+word blevet 12-2345
+begnum bt 6-12-2345
+contraction bt
+word blev 12-1236
+begnum bv 6-12-1236
+contraction bv
+word blive 12-3456
+word bve 12-1236-15
+word bliver 12
+
+word derefter 23456-1356
+word derst =
+word deres 256
+word derfor 23456-124
+word derf =
+word derigennem 23456-24-12456
+word derige 1456-1235-24-12456
+word dermed 23456-134
+word derm =
+word derned 23456-1246
+word derne =
+word derop 23456-135
+word dero =
+word derover 23456-1346
+word deror =
+word derpå 23456-1234
+word derp =
+word dersom 23456-234
+word ders =
+word dertil 23456-2345
+word dert =
+word derunder 23456-12345
+word derved 23456-1236
+word din 145-1345
+begnum dn 6-145-1345
+contraction dn
+word disse 145-234
+begnum ds 6-145-234
+contraction ds
+word dit 145-2345
+begnum dt 6-145-2345
+contraction dt
+word du 145
+
+word efter 1356
+word eller 15
+word endnu 15-136
+begnum eu 6-15-136
+contraction eu
+
+word fik 124-13
+begnum fk 6-124-13
+contraction fk
+word fordi 124-145
+begnum fd 6-124-145
+contraction fd
+word forskellige 124-123456-15
+word fske =
+word forskelligt 124-123456-2345
+word fskt =
+word forskellig 124-123456
+word fsk =
+word for 124
+word fra 235
+word første 124-1356-15
+word først 124-1356
+word før 246
+
+word ganske 1245-123456
+word gennem 12456
+word ge =
+word gik 1245-13
+begnum gk 6-1245-13
+contraction gk
+word gør 1245
+
+word ham 236
+word hans 13456-234
+begnum ys 6-13456-234
+contraction ys
+word han 13456
+word har 125
+word havde 125-1456
+word hde =
+word have 125-3456
+word hve =
+word helt 125-2345
+begnum ht 6-125-2345
+contraction ht
+word hendes 125-234
+begnum hs 6-125-234
+contraction hs
+word hende 125-145
+begnum hd 6-125-145
+contraction hd
+word hun 136
+word hvad 2456
+word hv =
+word hvis 2456-234
+word hvs =
+word hvordan 34-1
+word hvora 34-6-1
+word hvorefter 34-1356
+word hvorst 34-234-2345
+word hvorfor 34-124
+word hvorf 34-6-124
+word hvorigennem 34-24-12456
+word hvorledes 34-15
+word hvore 34-6-15
+word hvormed 34-134
+word hvorm 34-6-134
+word hvornår 34-1345
+word hvorn 34-6-1345
+word hvorover 34-1346
+word hvoror 34-135-1235
+word hvorpå 34-1234
+word hvorp 34-6-1234
+word hvortil 34-2345
+word hvort 34-6-2345
+word hvorunder 34-12345
+word hvornd 34-1345-145
+word hvorved 34-1236
+word hvorv 34-6-1236
+word hvor 34
+
+word igennem 24-12456
+word ige =
+word igen 35
+word (igen) 236-24-1245-126-356
+word ig =
+word ikke 24-13
+begnum ik 6-24-13
+contraction ik
+word imidlertid 24-24
+begnum ii 6-24-24
+contraction ii
+
+word jeg 245
+word jeg) 245-6-356
+
+word kan 13
+word kommer 13-156
+word ker =
+word kommet 13-346
+word ket =
+word komme 13-146
+word kme =
+word kom 13-134
+begnum km 6-13-134
+contraction km
+word kunne 13-1246
+word kne =
+
+word ligesom 123-234
+begnum ls 6-123-234
+contraction ls
+word lige 123
+word lille 123-123
+begnum ll 6-123-123
+contraction ll
+
+word mange 134-12456
+word mge =
+word med 134
+word megen 146-126
+word meen =
+word meget 146-346
+word meet =
+word mellem 146-134
+word mem =
+word men 146
+word me =
+word min 134-1345
+begnum mn 6-134-1345
+contraction mn
+word mit 134-2345
+begnum mt 6-145-2345
+contraction mt
+word måske 134-123456
+word msk =
+word måtte 134-1256
+word mte =
+
+word naturligvis 1345-2345-1236
+begnum ntv 6-1345-2345-1236
+contraction ntv
+word nd =
+word ned 1246
+word ne =
+word nogen 1345-1345
+begnum nn 6-1345-1345
+contraction nn
+word noget 1345-2345
+begnum nt 6-1345-2345
+contraction nt
+word nogle 1345-123-15
+begnum nle 6-1345-123-15
+contraction nle
+word når 1345
+
+word også 14-16
+begnum cå 6-14-16
+contraction cå
+word og 14
+word omkring 135-134-13
+begnum omk 6-135-134-13
+contraction omk
+word op 135
+word or =
+word over 1346
+
+word på 1234
+
+word ret 12356
+word re 1235-15
+word rigtige 1235-12456
+word rge =
+word rigtigt 1235-2345
+begnum rt 6-1235-2345
+contraction rt
+word rigtig 1235
+
+word sagde 234-1456
+word sammen 234-134
+begnum sm 6-234-134
+contraction sm
+word samme 234-146
+word sme =
+word selvfølgelig 234-1236-124
+begnum svf 6-234-1236-124
+contraction svf
+word selv 234-1236
+begnum sv 6-234-1236
+contraction sv
+word sidste 234-1356-15
+word sste =
+word sidst 234-1356
+word sst =
+word sin 234-1345
+begnum sn 6-234-1345
+contraction sn
+word sit 234-2345
+begnum st 6-234-2345
+contraction st
+word skal 123456
+word sk =
+word skulle 123456-123-15
+word skle =
+word snart 234-1235
+begnum sr 6-234-1235
+contraction sr
+word som 234
+word sådan 16-1
+begnum åa 6-16-1
+contraction åa
+word således 16-15
+begnum åe 6-16-15
+contraction åe
+word så 16
+
+word tid 2345-145
+begnum td 6-2345-145
+contraction td
+word tilbage 2345-12
+begnum tb 6-2345-12
+contraction tb
+word til 2345
+
+word under 12345
+
+word var- =
+word var. =
+word var 36
+word ve 3456
+word ved 1236
+word ville 1236-123-15
+begnum vle 6-1236-123-15
+contraction vle
+word vil 1236-123
+begnum vl 6-1236-123
+contraction vl
+word været 1236-2345
+begnum vt 6-1236-2345
+contraction vt
+word være 345
+
+#Part words
+nocross den 12346
+nocross der 23456
+nocross det 2346
+nocross de 1456
+nocross en 126
+nocross er 156
+nocross et 346
+nocross ge 12456
+#nocross hvor 34
+nocross hv 2456
+nocross ig 35
+nocross me 146
+nocross nd 12345
+nocross ne 1246
+nocross or 1346
+nocross re 12356
+nocross sk 123456
+nocross st 1356
+nocross te 1256
+
+# Numsign/"ve", special case when back-translating
+noback nocross ve 3456
+
+# Additional words containing "hvor"
+# these are made explicit in 6-dots to handle / better
+
+word hvoraf 34-1-124
+word hvorfra 34-124-1235-1
+word hvorhen 34-125-126
+word hvorhenne 34-125-126-1246
+word hvori 34-24
+word hvoriblandt 34-24-12-123-1-12345-2345
+word hvorimellem 34-24-146-123-123-15-134
+word hvorimod 34-24-134-135-145
+word hvorlænge 34-123-345-1345-12456
+word hvormange 34-134-1-1345-12456
+word hvorom 34-135-134
+word hvormeget 34-146-1245-346
+word hvorudfra 34-136-145-124-1235-1
+word hvorvidt 34-1236-24-145-2345
+word ihvorvel 24-34-3456-123
+
+# Common combinations of one word contractions with slash
+word af/på 356-34-1234
+word af/på 356-34-68-1234
+word du/i 145-34-24
+word du/i 145-34-68-24
+word eller/og 15-34-14
+word eller/og 15-34-68-14
+word fra/til 235-34-2345
+word fra/til 235-34-68-2345
+word han/hun 13456-34-136
+word han/hun 13456-34-68-136
+word hun/han 136-34-13456
+word hun/han 136-34-68-13456
+word i/du 24-34-145
+word i/du 24-34-68-145
+word og/eller 14-34-15
+word og/eller 14-34-68-15
+word over/under 1346-34-12345
+word over/under 1346-34-68-12345
+word på/af 1234-34-356
+word på/af 1234-34-68-356
+word til/fra 2345-34-235
+word til/fra 2345-34-68-235
+word under/over 12345-34-1346
+word under/over 12345-34-68-1346
+
+# Ensure no one-letter word contraction before or after a dash
+
+endword -af 36-1-124
+begword af- 1-124-36
+endword -altid 36-1-2345-145
+begword altid- 1-2345-145-36
+endword -at 36-1-2345
+endword -a 36-6-1
+begword at- 1-2345-36
+endword -og 36-135-1245
+endword -c 36-6-14
+begword og- 135-1245-36
+endword -du 36-145-136
+endword -d 36-6-145
+begword du- 145-136-36
+endword -efter 36-15-124-2345-156
+endword -z 36-6-1356
+begword efter- 15-124-2345-156-36
+midword -efter- 36-1356-36
+endword -e 36-6-15
+endword -for 36-124-1346
+endword -f 36-6-124
+begword for- 124-1346-36
+endword -fra 36-124-1235-1
+begword fra- 124-1235-1-36
+endword -g 36-6-1245
+endword -gennem 36-1245-126-1246-134
+begword gennem- 1245-126-1246-134-36
+endword -ham 36-125-1-134
+begword ham- 125-1-134-36
+endword -han 36-125-1-1345
+endword -y 36-6-13456
+begword han- 125-1-1345-36
+endword -har 36-125-1-1235
+endword -h 36-6-125
+begword har- 125-1-1235-36
+endword -hun 36-125-136-1345
+endword -u 36-6-136
+begword hun- 125-136-1345-36
+endword -j 36-6-245
+endword -kan 36-13-1-1345
+endword -k 36-6-13
+begword kan- 13-1-1345-36
+endword -lige 36-123-24-12456
+endword -l 36-6-123
+begword lige- 123-24-12456-36
+endword -med 36-146-145
+endword -m 36-6-134
+begword med- 146-145-36
+endword -men 36-134-126
+begword men- 134-126-36
+ endword -ned 36-1246-145
+begword ned- 1246-145-36
+endword -når 36-1345-16-1235
+endword -n 36-6-1345
+begword når- 1345-16-1235-36
+endword -op 36-135-1234
+endword -o 36-6-135
+begword op- 135-1234-36
+endword -over 36-135-1236-156
+endword -x 36-6-1346
+begword over- 135-1236-156-36
+endword -på 36-1234-16
+endword -p 36-6-1234
+begword på- 1234-16-36
+midword -på- 36-1234-36
+endword -ret 36-1235-346
+begword ret- 1235-346-36
+midword -ret- 36-12356-36
+endword -rigtig 36-1235-35-2345-35
+endword -r 36-6-1235
+begword rigtig- 1235-35-2345-35-36
+midword -rigtig- 36-1235-36
+endword -skal 36-123456-1-123
+begword skal- 123456-1-123-36
+midword -skal- 36-123456-36
+endword -som 36-234-135-134
+endword -s 36-6-234
+begword som- 234-135-134-36
+midword -som- 36-234-36
+endword -så 36-234-16
+endword -å 36-6-16
+begword så- 234-16-36
+endword -til 36-2345-24-123
+endword -t 36-6-2345
+begword til- 2345-24-123-36
+midword -til- 36-2345-36
+endword -under 36-136-1345-23456
+begword under- 136-1345-23456-36
+midword -under- 36-12345-36
+endword -ved 36-1236-15-145
+endword -v 36-6-1236
+begword ved- 1236-15-145-36
+midword -ved- 36-1236-36
+
+
+### Context rules - forward translation
+
+# Substitutions for joinnum rules with common math signs
+noback context $dy$s["-"$s]$dy @36
+noback context $dy$s["+"$s]$dy @235
+noback context $dy$s["\x00d7"$s]$dy @3
+noback context $dy$s["\x00f7"$s]$dy @256
+noback context $dy$s["="$s]$dy @2356
+
+# Space on each side of = when between letters or punctuation.
+noback context $lp["="]$lp @0-2356-0
+
+# Exclamation at beginning of string
+noback context `["!"] @6-235
+
+# Ensure two dashes where appropriate.
+noback context $w["-"]$w @36
+noback context $sw["-"]$sw @36-36
+noback context `["-"]$sw @36-36
+noback context $sw["-"]~ @36-36
+noback context !$sw["-"]~ @36
+noback context `["-"]~ @36-36
+
+# Ensure letsign between letter and numsign
+noback context $l[]$D @6
+
+# No "nd", "hv", "or", or "st" after a digit and a letsign
+noback context $dy["hv"] @6-125-1236
+noback context $dy$Spm["hv"] @6-125-1236
+noback context $dy["nd"] @6-1345-145
+noback context $dy$Spm["nd"] @6-1345-145
+noback context $dy["or"] @6-135-1235
+noback context $dy$Spm["or"] @6-135-1235
+noback context $dy["st"] @6-234-2345
+noback context $dy$Spm["st"] @6-234-2345
+noback context $dy["te"] @6-2345-15
+noback context $dy$Spm["te"] @6-2345-15
+
+
+#ensure dot 6 between a digit and a letter
+noback context $dy[]$u @6
+# Not letsign after digit + punctuation in literary braille
+# noback context $dy$Spm.[]$u @6
+
+### Pass 2 - forward translation
+
+# Correct chars defined as 8 dots because they include letsign
+noback pass2 @467 @45-6
+noback pass2 @4568 @45-456
+noback pass2 @123457 @6-12345
+noback pass2 @24567 @6-2456
+noback pass2 @13467 @6-1346
+noback pass2 @13567 @6-1356
+noback pass2 @12567 @6-1256
+
+# Show endcapsword as dot 6 (letsign)
+noback pass2 @68 @6
+
+noback pass2 @6-46-5 @46-5 # no letsign before cap letters with accent
+noback pass2 _$D[@6-46-6] *
+noback pass2 _$D[@6-46] *
+noback pass2 @6-46-6 @46-6 # Ensure correct order and no double letsign
+noback pass2 @6-46 @46-6 # Ensure correct order
+
+### Pass 3 - forward translation
+
+# Ensure there is only one letsign
+ noback pass3 @6-6 @6
+
+# Include hyphenation file as the last thing
+include hyph_brl_da_dk.dic
diff --git a/tables/da-dk-g26.ctb b/tables/da-dk-g26.ctb
new file mode 100644
index 0000000..4073f52
--- /dev/null
+++ b/tables/da-dk-g26.ctb
@@ -0,0 +1,1109 @@
+# Liblouis: Danish table for 6 dots grade 2 forward and backward translation
+#
+# Copyright (C) 2014-2017, Bue Vester-Andersen <bue@vester-andersen.dk>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# Version: Bue Vester-Andersen, 170604
+
+### Table Metadata
+
+#-name: Dansk forkortet 6-punkt
+#-index-name: Danish, contracted, 6-dot
+#-display-name: Danish 6-dot contracted braille
+
+#+locale: da
+#+type: literary
+#+contraction: full
+#+grade: 2
+#+dots: 6
+#+direction: both
+
+#-has-nocross: yes
+
+# Display opcodes
+include da-dk-octobraille.dis
+
+### Spaces
+
+# These ctrl-chars have to have a representation, so that they can be properly converted back and forth.
+space \t 2478 CHARACTER TABULATION
+space \n 678 LINE FEED (LF)
+space \v 1368 LINE TABULATION
+space \f 12378 FORM FEED (FF)
+space \r 257 CARRIAGE RETURN (CR)
+space \x00a0 a
+
+include spaces.uti
+
+### Character definitions
+
+# Definition of dot cells
+punctuation ! 235 EXCLAMATION MARK
+punctuation " 2356 QUOTATION MARK
+punctuation ' 4 APOSTROPHE
+punctuation ( 236 LEFT PARENTHESIS
+punctuation ) 356 RIGHT PARENTHESIS
+punctuation , 2 COMMA
+punctuation - 36 HYPHEN-MINUS
+punctuation . 3 FULL STOP
+punctuation / 34 SLASH
+punctuation : 25 COLON
+punctuation ; 23 SEMICOLON
+punctuation ? 26 QUESTION MARK
+uplow Aa 1
+uplow Bb 12
+uplow Cc 14
+uplow Dd 145
+uplow Ee 15
+uplow Ff 124
+uplow Gg 1245
+uplow Hh 125
+uplow Ii 24
+uplow Jj 245
+uplow Kk 13
+uplow Ll 123
+uplow Mm 134
+uplow Nn 1345
+uplow Oo 135
+uplow Pp 1234
+uplow Rr 1235
+uplow Ss 234
+uplow Tt 2345
+uplow Uu 136
+uplow Vv 1236
+uplow Yy 13456
+
+#use 8 dots for the following chars to avoid conflict with indicators
+uplow Qq 123457
+uplow Ww 24567
+uplow Xx 13467
+uplow Zz 13567
+punctuation | 4568 VERTICAL LINE
+punctuation ~ 467 TILDE (changed by pass 2 to not conflict with indicators
+uplow \x00dc\x00fc 12567
+
+include digits6Dots.uti
+
+punctuation \x00a7 346 SECTION SIGN (0xa7)
+
+uplow \x00c5\x00e5 16 LATIN LETTER A WITH RING ABOVE
+uplow \x00c6\x00e6 345 LATIN LETTER AE
+uplow \x00d8\x00f8 246 LATIN LETTER O WITH STROKE
+
+# cover all other Braille patterns
+include braille-patterns.cti
+
+# Characters with two or more cells
+
+punctuation # 45-3456 NUMBER SIGN
+sign $ 45-256 DOLLAR SIGN
+math % 245-356 PERCENT SIGN
+sign & 6-12346 AMPERSAND
+punctuation * 6-35 ASTERISK
+math + 45-235 PLUS SIGN
+math < 45-134 LESS-THAN SIGN
+math = 45-2356 EQUALS SIGN
+math > 45-234 GREATER-THAN SIGN
+sign @ 45-1 COMMERCIAL AT
+punctuation [ 5-236 LEFT SQUARE BRACKET
+punctuation \\ 45-16 REVERSE SLASH
+punctuation ] 5-356 RIGHT SQUARE BRACKET
+punctuation ^ 45-346 CIRCUMFLEX ACCENT
+punctuation _ 45-36 LOW LINE
+punctuation ` 4 GRAVE ACCENT
+punctuation { 45-246 LEFT CURLY BRACKET
+punctuation } 45-135 RIGHT CURLY BRACKET
+math \x00f7 45-256 DIVISION SIGN
+
+# Misc unicode characters
+include da-dk-6miscChars.cti
+
+# Extra chars for private use:
+space \xf800 234f # Used to force a hidden word boundary
+letter \xf801 123f # Used to prevent word contractions in certain cases
+
+# Litdigits
+include litdigits6Dots.uti
+midendnumericmodechars /,.:^
+
+undefined 26
+
+### Braille indicators and special characters
+
+#hyphen - 36
+
+letsign 6
+
+# No letsign before capital letters or letters with accents
+
+noletsign I\x0160\x0152\x017d\x0178\x00c0\x00c1\x00c2\x00c3\x00c7\x00c8\x00c9\x00ca\x00cb\x00cc\x00cd\x00ce\x00cf\x00d0\x00d1\x00d2\x00d3\x00d4\x00d5\x00d9\x00da\x00db\x00dc\x00dd\x00de\x008a\x008c\x008e
+noletsign i\x0161\x0153\x017e\x00ff\x00df\x00e0\x00e1\x00e2\x00e3\x00e7\x00e8\x00e9\x00ea\x00eb\x00ec\x00ed\x00ee\x00ef\x00f0\x00f1\x00f2\x00f3\x00f4\x00f5\x00f9\x00fa\x00fb\x00fd\x00fe\x009a\x009c
+
+# Emphasis opcodes
+emphclass italic
+emphclass underline
+emphclass bold
+
+begemphphrase italic 56
+endemphphrase italic after 56
+begemphword italic 56
+endemphword italic 56
+
+begemphphrase bold 56
+endemphphrase bold after 56
+begemphword bold 56
+endemphword bold 56
+
+begemphphrase underline 56
+endemphphrase underline after 56
+begemphword underline 56
+endemphword underline 56
+
+capsletter 46
+begcapsword 456
+endcapsword 6
+multind 6-46 letsign capsletter
+multind 46-6 capsletter letsign
+multind 6-456 letsign begcapsword
+
+numsign 3456
+multind 6-3456 letsign numsign
+
+#class of none-space characters that demand double dashes
+# Used in context lines later.
+#must be the first class defined.
+class charsWDoubleDash .,?!/:"'() # class w
+
+### Correct - forward translation
+
+# Chars that don't require a space before percent and permille:
+class charsBeforePercent "(\x201e\x0084\x201c\x0093\x201d\x0094\x00ab\x00bb #class x
+noback correct `["%"] *
+noback correct !$sx["%"] " %"
+noback correct `["\x2030"] *
+noback correct !$sx["\x2030"] " \x2030"
+noback correct `["\x0089"] *
+noback correct !$sx["\x0089"] " \x2030"
+
+# Chars to be treated like digits when switching back to letter mode
+class extraDigits \x00bc\x00bd\x00be
+
+#Use the "correct" opcode to convert chars that can't be back-translated
+# and make the table more simple.
+
+# Dashes
+class dashes \x2013\x2014\x0096\x0097\x00ad
+noback correct %dashes "-"
+
+class quotes \x201e\x0084\x201c\x0093\x201d\x0094\x00ab\x00bb
+noback correct %quotes "\""
+
+class apostrophes `\x201a\x0082\x2039\x008b\x2018\x0091\x2019\x0092\x203a\x009b\x00b4
+noback correct %apostrophes "'"
+
+### Correct - backward translation
+
+# characters that may get mangled by the insertion of extra letsigns
+nofor correct "\x2818" "~"
+#nofor correct "\x282f" "&"
+#nofor correct "\x2814" "*"
+
+# Try to distinguish between times (\x00d7) and bullit (\x2022),
+# which share the same Braille representation.
+nofor correct `["\x00d7"] "\x2022"
+# nofor correct $d["\s\x00d7\s"]$d * #apparently doesn't work now
+nofor correct ["\x00d7"]!$d "\x2022"
+nofor correct !$d["\x00d7"] "\x2022"
+
+nofor correct "\x28a0" ? # Extraneous endcaps signs
+#nofor correct "\x2820" ?
+nofor correct "~\\456/" "|"
+
+#ensure \xf800\xf801 between a digit and a letter
+noback correct $dy[]$l "\xf800\xf801"
+noback correct $dy$Spm.[]$l "\xf800\xf801"
+### Pass 1 - Forward and backward
+
+# Punctuations, math and numbers
+#midnum , 2
+#midnum . 3
+#midnum - 36
+endnum - 36
+#midnum / 34
+#midnum : 25
+nofor midnum ^ 346
+nofor midnum ^ 45-346
+
+midnum ^ 45-346
+midnum \x00d7 45-3
+
+# various back rules for math signs etc.
+nofor midnum % 0-245-356-0-3456
+nofor endnum % 0-245-356
+nofor endnum \x2030 0-245-356-356
+nofor midnum \x00d7 45-3
+#nofor midnum \x00d7 3
+
+# Punctuation
+prepunc " 2356
+postpunc " 2356
+always /\s 6-34-0
+always \s/ 0-6-34
+nofor always / 6-34
+prepunc - 36
+postpunc - 36
+nofor always \s-\s 0-36-36-0
+always :- 25-36
+always ;- 23-36
+always --- 36-36-36
+always ---- 36-36-36-36
+always ----- 36-36-36-36-36
+# Star enclosed by parentheses
+always (*) 236-35-356
+
+before punctuation before sign always ( 6-236
+
+# these characters must be separated from ")" by a letsign.
+class SepToRightpar Jj%'\x2030\x0089\x201a\x0082\x2039\x009b\x2018\x0091\x2019\x0092\x203a\x009b
+after SepToRightpar always ) 6-356
+after punctuation after sign always ) 6-356
+
+prepunc ( 236
+postpunc ) 356
+always .) 3-356
+always ( 6-236
+always ) 6-356
+
+# extra back rules for ")"
+nofor after punctuation always ) 356
+nofor always \x00b0 4-356
+nofor always ') 4-6-356
+nofor always ") 2356-356
+nofor endword j) 245-356
+nofor always ) 6-356
+
+always ... 3-3-3
+
+# Exclamation and "fra"
+always fra! 124-1235-1-235
+always !fra 235-124-1235-1
+always ?! 26-6-235
+always )! 356-6-235
+always (!) 236-6-235-356
+always "fra" 2356-124-1235-1-2356
+always "!" 2356-6-235-2356
+always !! 235-235
+always !!! 235-235-235
+always !!!! 235-235-235-235
+always !!!!! 235-235-235-235-235
+always '! 4-6-235
+always \s! 0-6-235
+prepunc ! 6-235
+always \x00a1 6-256
+
+### Contractions ###
+
+#Special sequences, urls emails and file names.
+
+nocont $
+nocont \x005c
+nocont @
+nocont ://
+nocont www
+nocont .com
+nocont .dk
+nocont .eu
+nocont .edu
+nocont .gov
+nocont .mil
+nocont .net
+nocont .org
+nocont .uk
+nocont .doc
+nocont .exe
+nocont .htm
+nocont .tex
+nocont .txt
+nocont .gif
+nocont .jpg
+nocont .png
+nocont .wav
+nocont .tar
+nocont .zip
+
+# Ensure no contractions in English ordinal numbers
+endnum nd 6-1345-145
+endnum st 6-234-2345
+endnum ve 6-1236-15
+
+#Words
+word af 356
+always 'af 4-1-124
+word aldrig 1-35
+word aig =
+word alle 1-15
+begnum ae 6-1-15
+contraction ae
+word allerede 1-123-1235
+begnum alr 6-1-123-1235
+contraction alr
+word alligevel 1-123-1236
+begnum alv 6-1-123-1236
+contraction alv
+word altid 1-2345-145
+begnum atd 6-1-2345-145
+contraction atd
+word altså 1-16
+begnum aå 6-1-16
+contraction aå
+word at 1
+
+word blevet 12-2345
+begnum bt 6-12-2345
+contraction bt
+word blev 12-1236
+begnum bv 6-12-1236
+contraction bv
+word blive 12-3456
+word bve 12-1236-15
+word bliver 12
+
+word derefter 23456-1356
+word derst =
+word deres 256
+word derfor 23456-124
+word derf =
+word derigennem 23456-24-12456
+word derige 1456-1235-24-12456
+word dermed 23456-134
+word derm =
+word derned 23456-1246
+word derne =
+word derop 23456-135
+word dero =
+word derover 23456-1346
+word deror =
+word derpå 23456-1234
+word derp =
+word dersom 23456-234
+word ders =
+word dertil 23456-2345
+word dert =
+word derunder 23456-12345
+word derved 23456-1236
+word din 145-1345
+begnum dn 6-145-1345
+contraction dn
+word disse 145-234
+begnum ds 6-145-234
+contraction ds
+word dit 145-2345
+begnum dt 6-145-2345
+contraction dt
+word du 145
+
+word efter 1356
+word eller 15
+word endnu 15-136
+begnum eu 6-15-136
+contraction eu
+
+word fik 124-13
+begnum fk 6-124-13
+contraction fk
+word fordi 124-145
+begnum fd 6-124-145
+contraction fd
+word forskellige 124-123456-15
+word fske =
+word forskelligt 124-123456-2345
+word fskt =
+word forskellig 124-123456
+word fsk =
+word for 124
+word fra 235
+word første 124-1356-15
+word først 124-1356
+word før 246
+
+word ganske 1245-123456
+word gennem 12456
+word ge =
+word gik 1245-13
+begnum gk 6-1245-13
+contraction gk
+word gør 1245
+
+word ham 236
+word hans 13456-234
+begnum ys 6-13456-234
+contraction ys
+word han 13456
+word har 125
+word havde 125-1456
+word hde =
+word have 125-3456
+word hve =
+word helt 125-2345
+begnum ht 6-125-2345
+contraction ht
+word hendes 125-234
+begnum hs 6-125-234
+contraction hs
+word hende 125-145
+begnum hd 6-125-145
+contraction hd
+word hun 136
+word hvad 2456
+word hv =
+word hvis 2456-234
+word hvs =
+word hvordan 34-1
+word hvora 34-6-1
+word hvorefter 34-1356
+word hvorst 34-234-2345
+word hvorfor 34-124
+word hvorf 34-6-124
+word hvorigennem 34-24-12456
+word hvorledes 34-15
+word hvore 34-6-15
+word hvormed 34-134
+word hvorm 34-6-134
+word hvornår 34-1345
+word hvorn 34-6-1345
+word hvorover 34-1346
+word hvoror 34-135-1235
+word hvorpå 34-1234
+word hvorp 34-6-1234
+word hvortil 34-2345
+word hvort 34-6-2345
+word hvorunder 34-12345
+word hvornd 34-1345-145
+word hvorved 34-1236
+word hvorv 34-6-1236
+word hvor 34
+
+word igennem 24-12456
+word ige =
+word igen 35
+word (igen) 236-24-1245-126-356
+word ig =
+word ikke 24-13
+begnum ik 6-24-13
+contraction ik
+word imidlertid 24-24
+begnum ii 6-24-24
+contraction ii
+
+word jeg 245
+word jeg) 245-6-356
+
+word kan 13
+word kommer 13-156
+word ker =
+word kommet 13-346
+word ket =
+word komme 13-146
+word kme =
+word kom 13-134
+begnum km 6-13-134
+contraction km
+word kunne 13-1246
+word kne =
+
+word ligesom 123-234
+begnum ls 6-123-234
+contraction ls
+word lige 123
+word lille 123-123
+begnum ll 6-123-123
+contraction ll
+
+word mange 134-12456
+word mge =
+word med 134
+word megen 146-126
+word meen =
+word meget 146-346
+word meet =
+word mellem 146-134
+word mem =
+word men 146
+word me =
+word min 134-1345
+begnum mn 6-134-1345
+contraction mn
+word mit 134-2345
+begnum mt 6-145-2345
+contraction mt
+word måske 134-123456
+word msk =
+word måtte 134-1256
+word mte =
+
+word naturligvis 1345-2345-1236
+begnum ntv 6-1345-2345-1236
+contraction ntv
+word nd =
+word ned 1246
+word ne =
+word nogen 1345-1345
+begnum nn 6-1345-1345
+contraction nn
+word noget 1345-2345
+begnum nt 6-1345-2345
+contraction nt
+word nogle 1345-123-15
+begnum nle 6-1345-123-15
+contraction nle
+word når 1345
+
+word også 14-16
+begnum cå 6-14-16
+contraction cå
+word og 14
+word omkring 135-134-13
+begnum omk 6-135-134-13
+contraction omk
+word op 135
+word or =
+word over 1346
+
+word på 1234
+
+word ret 12356
+word re 1235-15
+word rigtige 1235-12456
+word rge =
+word rigtigt 1235-2345
+begnum rt 6-1235-2345
+contraction rt
+word rigtig 1235
+
+word sagde 234-1456
+word sammen 234-134
+begnum sm 6-234-134
+contraction sm
+word samme 234-146
+word sme =
+word selvfølgelig 234-1236-124
+begnum svf 6-234-1236-124
+contraction svf
+word selv 234-1236
+begnum sv 6-234-1236
+contraction sv
+word sidste 234-1356-15
+word sste =
+word sidst 234-1356
+word sst =
+word sin 234-1345
+begnum sn 6-234-1345
+contraction sn
+word sit 234-2345
+begnum st 6-234-2345
+contraction st
+word skal 123456
+word sk =
+word skulle 123456-123-15
+word skle =
+word snart 234-1235
+begnum sr 6-234-1235
+contraction sr
+word som 234
+word sådan 16-1
+begnum åa 6-16-1
+contraction åa
+word således 16-15
+begnum åe 6-16-15
+contraction åe
+word så 16
+
+word tid 2345-145
+begnum td 6-2345-145
+contraction td
+word tilbage 2345-12
+begnum tb 6-2345-12
+contraction tb
+word til 2345
+
+word under 12345
+
+sufword var- =
+sufword var. =
+word var 36
+word ve 3456
+word ved 1236
+word ville 1236-123-15
+begnum vle 6-1236-123-15
+contraction vle
+word vil 1236-123
+begnum vl 6-1236-123
+contraction vl
+word været 1236-2345
+begnum vt 6-1236-2345
+contraction vt
+word være 345
+
+#Part words
+nocross den 12346
+nocross der 23456
+nocross det 2346
+nocross de 1456
+nocross en 126
+nocross er 156
+nocross et 346
+nocross ge 12456
+#nocross hvor 34
+nocross hv 2456
+nocross ig 35
+nocross me 146
+nocross nd 12345
+nocross ne 1246
+nocross or 1346
+nocross re 12356
+nocross sk 123456
+nocross st 1356
+nocross te 1256
+
+# Numsign/"ve", special case when back-translating
+noback nocross ve 3456
+
+# Additional words containing "hvor"
+# these are made explicit in 6-dots to handle / better
+
+word hvoraf 34-1-124
+word hvorfra 34-124-1235-1
+word hvorhen 34-125-126
+word hvorhenne 34-125-126-1246
+word hvori 34-24
+word hvoriblandt 34-24-12-123-1-12345-2345
+word hvorimellem 34-24-146-123-123-15-134
+word hvorimod 34-24-134-135-145
+word hvorlænge 34-123-345-1345-12456
+word hvormange 34-134-1-1345-12456
+word hvorom 34-135-134
+word hvormeget 34-146-1245-346
+word hvorudfra 34-136-145-124-1235-1
+word hvorvidt 34-1236-24-145-2345
+word ihvorvel 24-34-3456-123
+
+# Rules and corrections for back-translation
+
+#ve special case
+nofor midendword ve 3456
+
+# nondigletters covers small letters from k + various part word contractions with dots 5 or 6. Necesary to ensure correct back-translation.
+class nondigletter klmnopqrstuvwxyzæøå\x017e\x00e0\x00e7\x00e8\x00e9\x00ea\x00eb\x00ee\x00ef\x00f4\x00f9\x00fb\x00fc\x283f\x2829\x282b\x2837
+nofor before nondigletter begword ve 3456
+nofor before nondigletter begword vea 3456-1
+nofor sufword veade 3456-1-1456
+nofor sufword veader 3456-1-23456
+nofor sufword veage 3456-1-12456
+nofor before nondigletter begword veag 3456-1-1245
+
+# veb
+nofor before nondigletter begword veb 3456-12
+nofor before nondigletter begword veba 3456-12-1
+nofor before nondigletter begword vebb 3456-12-12
+nofor sufword vebbest 3456-12-12-15-1356
+nofor before nondigletter begword vebe 3456-12-15
+nofor before nondigletter begword vebi 3456-12-24
+
+# vec
+nofor before nondigletter begword vec 3456-14
+nofor before nondigletter begword vecchi 3456-14-14-125-24
+
+# ved
+nofor before nondigletter begword ved 3456-145
+nofor before nondigletter begword veda 3456-145-1
+nofor sufword vedaer 3456-145-1-156
+nofor before nondigletter begword vedb 3456-145-12
+nofor sufword vedben 3456-145-12-126
+nofor sufword vedbend 3456-145-12-15-12345
+nofor sufword vedbenden 3456-145-12-126-12346
+nofor before nondigletter begword vedc 3456-145-14
+nofor before nondigletter begword vedd 3456-145-145
+nofor before nondigletter begword vedda 3456-145-145-1
+nofor sufword vedde 3456-145-1456
+nofor sufword veddet 3456-145-2346
+nofor sufword vede 3456-1456
+nofor sufword veden 3456-12346
+nofor sufword veder 3456-23456
+nofor sufword vedet 3456-2346
+nofor before nondigletter begword vedf 3456-145-124
+nofor before nondigletter begword vedfa 3456-145-124-1
+nofor before nondigletter begword vedfe 3456-145-124-15
+nofor before nondigletter begword vedfi 3456-145-124-24
+nofor before nondigletter begword vedg 3456-145-1245
+nofor before nondigletter begword vedga 3456-145-1245-1
+nofor sufword vedge 3456-145-12456
+nofor before nondigletter begword vedgi 3456-145-1245-24
+nofor before nondigletter begword vedh 3456-145-125
+nofor before nondigletter begword vedha 3456-145-125-1
+nofor before nondigletter begword vedhe 3456-145-125-15
+nofor before nondigletter begword vedhef 3456-145-125-15-124
+nofor sufword vedhefte 3456-145-125-15-124-1256
+nofor before nondigletter begword vedhi 3456-145-125-24
+nofor before nondigletter begword vedi 3456-145-24
+nofor before nondigletter begword vedj 3456-145-245
+nofor sufword vedst 3456-145-1356
+nofor sufword vedte 3456-145-1256
+
+# vee
+nofor before nondigletter begword vee 3456-15
+nofor before nondigletter begword veeb 3456-15-12
+nofor sufword veen 3456-126
+nofor sufword veer 3456-156
+nofor sufword veet 3456-346
+
+# vef
+nofor before nondigletter begword vef 3456-124
+nofor before nondigletter begword vefa 3456-124-1
+nofor before nondigletter begword vefe 3456-124-15
+nofor before nondigletter begword vefi 3456-124-24
+
+# veg
+nofor before nondigletter begword veg 3456-1245
+nofor before nondigletter begword vega 3456-1245-1
+nofor sufword vege 3456-12456
+nofor sufword vegen 3456-1245-126
+nofor word veget 3456-1245-346
+nofor sufword vegger 3456-1245-1245-156
+nofor before nondigletter begword vegi 3456-1245-24
+nofor sufword vegst 3456-1245-1356
+
+# veh
+nofor before nondigletter begword veh 3456-125
+nofor before nondigletter begword veha 3456-125-1
+nofor sufword vehand 3456-125-1-12345
+nofor sufword vehage 3456-125-1-23456
+nofor before nondigletter begword vehe 3456-125-15
+nofor before nondigletter begword vehi 3456-125-24
+
+# vei
+nofor before nondigletter begword vei 3456-24
+nofor before nondigletter begword veibe 3456-24-12-15
+nofor sufword veide 3456-24-1456
+nofor sufword veien 3456-24-126
+nofor sufword veige 3456-24-12456
+nofor before nondigletter begword veij 3456-24-245
+nofor sufword veind 3456-24-12345
+
+# vej
+nofor before nondigletter begword vej 3456-245
+nofor before nondigletter begword veja 3456-245-1
+nofor before nondigletter begword vejadga 3456-245-1-145-1245-1
+nofor before nondigletter begword vejaf 3456-245-1-124
+nofor sufword vejafde 3456-245-1-124-1456
+nofor before nondigletter begword vejafgif 3456-245-1-124-1245-24-124
+nofor before nondigletter begword vejb 3456-245-12
+nofor before nondigletter begword vejba 3456-245-12-1
+nofor before nondigletter begword vejbe 3456-245-12-15
+nofor before nondigletter begword vejbi 3456-245-12-24
+nofor before nondigletter begword vejbid 3456-245-12-24-145
+nofor before nondigletter begword vejc 3456-245-14
+nofor before nondigletter begword vejd 3456-245-145
+nofor before nondigletter begword vejda 3456-245-145-1
+nofor sufword vejde 3456-245-1456
+nofor before nondigletter begword vejdi 3456-245-145-24
+nofor before nondigletter begword veje 3456-245-15
+nofor before nondigletter begword vejea 3456-245-15-1
+nofor before nondigletter begword vejeb 3456-245-15-12
+nofor before nondigletter begword vejed 3456-245-15-145
+nofor before nondigletter begword vejeda 3456-245-15-145-1
+nofor sufword vejede 3456-245-15-1456
+nofor before nondigletter begword vejef 3456-245-15-124
+nofor before nondigletter begword vejeg 3456-245-15-1245
+nofor sufword vejege 3456-245-15-12456
+nofor sufword vejen 3456-245-126
+nofor sufword vejene 3456-245-15-1246
+nofor sufword vejer 3456-245-156
+nofor word vejet 3456-245-346
+nofor before nondigletter begword vejf 3456-245-124
+nofor before nondigletter begword vejfa 3456-245-124-1
+nofor before nondigletter begword vejfe 3456-245-124-15
+nofor sufword vejfest 3456-245-124-15-1356
+nofor before nondigletter begword vejfi 3456-245-124-24
+nofor begword vejfor 3456-245-124-1346
+nofor before nondigletter begword vejg 3456-245-1245
+nofor before nondigletter begword vejga 3456-245-1245-1
+nofor before nondigletter begword vejgaa 3456-245-1245-1-1
+nofor sufword vejge 3456-245-12456
+nofor before nondigletter begword vejgi 3456-245-1245-24
+nofor before nondigletter begword vejh 3456-245-125
+nofor before nondigletter begword vejha 3456-245-125-1
+nofor before nondigletter begword vejhe 3456-245-125-15
+nofor before nondigletter begword vejhi 3456-245-125-24
+nofor sufword vejhist 3456-245-125-24-1356
+nofor before nondigletter begword vejhj 3456-245-125-245
+nofor before nondigletter begword veji 3456-245-24
+nofor before nondigletter begword vejid 3456-245-24-145
+nofor before nondigletter begword vejj 3456-245-245
+nofor before nondigletter begword vejja 3456-245-245-1
+nofor before nondigletter begword vejje 3456-245-245-15
+nofor before nondigletter begword vejji 3456-245-245-24
+nofor sufword vejor 3456-245-1346
+nofor begword vejst 3456-245-1356
+
+nofor always vend 3456-12345
+nofor always veor 3456-1346
+nofor always vest 3456-1356
+nofor always vete 3456-1256
+
+# Corrections of letters with accents
+nofor sufword aïda 1-5-24-145-1
+nofor sufword anaïs 1-1345-1-5-24-234
+nofor sufword barsebäck 12-1-1235-234-15-12-345-14-13
+nofor sufword bohè 12-135-125-5-15
+nofor sufword château 14-125-5-1-1256-1-136
+nofor sufword citroën 14-24-2345-1235-135-5-15-1345
+nofor sufword däniken 145-345-1345-24-13-126
+nofor word fór 124-5-135-1235
+nofor sufword göran 1245-246-1235-1-1345
+nofor sufword göring 1245-246-1235-24-1345-1245
+nofor word händel 125-345-1345-1456-123
+nofor word händels 125-345-1345-1456-123-234
+nofor sufword lagerlöf 123-1-1245-156-123-246-124
+nofor sufword márquez 134-5-1-1235-6-12345-136-15-6-1356
+nofor sufword miró 134-24-1235-5-135
+nofor sufword moliè 134-135-123-24-5-15
+nofor sufword norröna 1345-1346-1235-246-1345-1
+nofor sufword tannhäus 2345-1-1345-1345-125-345-136-234
+nofor sufword tórshavn 2345-5-135-1235-234-125-1-1236-1345
+ nofor sufword václav 1236-5-1-14-123-1-1236
+nofor sufword verän 1236-156-345-1345
+nofor sufword weizsäck 6-2456-15-24-6-1356-234-345-14-13
+
+# Common combinations of one word contractions with slash
+word af/på 356-34-1234
+word du/i 145-34-24
+word eller/og 15-34-14
+word fra/til 235-34-2345
+word han/hun 13456-34-136
+word hun/han 136-34-13456
+word i/du 24-34-145
+word og/eller 14-34-15
+word over/under 1346-34-12345
+word på/af 1234-34-356
+word til/fra 2345-34-235
+word under/over 12345-34-1346
+
+# no backtrans of ^1 and `2. use contractions
+nofor always eta 346-1
+nofor always etb 346-12
+always etc 346-14
+
+# Ensure no one-letter word contraction before or after a dash
+
+endword -af 36-1-124
+begword af- 1-124-36
+endword -altid 36-1-2345-145
+begword altid- 1-2345-145-36
+endword -at 36-1-2345
+endword -a 36-6-1
+begword at- 1-2345-36
+endword -og 36-135-1245
+endword -c 36-6-14
+begword og- 135-1245-36
+endword -du 36-145-136
+endword -d 36-6-145
+begword du- 145-136-36
+endword -efter 36-15-124-2345-156
+endword -z 36-6-1356
+begword efter- 15-124-2345-156-36
+midword -efter- 36-1356-36
+endword -e 36-6-15
+endword -for 36-124-1346
+endword -f 36-6-124
+begword for- 124-1346-36
+endword -fra 36-124-1235-1
+begword fra- 124-1235-1-36
+endword -g 36-6-1245
+endword -gennem 36-1245-126-1246-134
+begword gennem- 1245-126-1246-134-36
+endword -ham 36-125-1-134
+begword ham- 125-1-134-36
+endword -han 36-125-1-1345
+endword -y 36-6-13456
+begword han- 125-1-1345-36
+endword -har 36-125-1-1235
+endword -h 36-6-125
+begword har- 125-1-1235-36
+endword -hun 36-125-136-1345
+endword -u 36-6-136
+begword hun- 125-136-1345-36
+endword -j 36-6-245
+endword -kan 36-13-1-1345
+endword -k 36-6-13
+begword kan- 13-1-1345-36
+endword -lige 36-123-24-12456
+endword -l 36-6-123
+begword lige- 123-24-12456-36
+endword -med 36-146-145
+endword -m 36-6-134
+begword med- 146-145-36
+endword -men 36-134-126
+begword men- 134-126-36
+ endword -ned 36-1246-145
+begword ned- 1246-145-36
+endword -når 36-1345-16-1235
+endword -n 36-6-1345
+begword når- 1345-16-1235-36
+endword -op 36-135-1234
+endword -o 36-6-135
+begword op- 135-1234-36
+endword -over 36-135-1236-156
+endword -x 36-6-1346
+begword over- 135-1236-156-36
+endword -på 36-1234-16
+endword -p 36-6-1234
+begword på- 1234-16-36
+midword -på- 36-1234-36
+endword -ret 36-1235-346
+begword ret- 1235-346-36
+midword -ret- 36-12356-36
+endword -rigtig 36-1235-35-2345-35
+endword -r 36-6-1235
+begword rigtig- 1235-35-2345-35-36
+midword -rigtig- 36-1235-36
+endword -skal 36-123456-1-123
+begword skal- 123456-1-123-36
+midword -skal- 36-123456-36
+endword -som 36-234-135-134
+endword -s 36-6-234
+begword som- 234-135-134-36
+midword -som- 36-234-36
+endword -så 36-234-16
+endword -å 36-6-16
+begword så- 234-16-36
+endword -til 36-2345-24-123
+endword -t 36-6-2345
+begword til- 2345-24-123-36
+midword -til- 36-2345-36
+endword -under 36-136-1345-23456
+begword under- 136-1345-23456-36
+midword -under- 36-12345-36
+endword -ved 36-1236-15-145
+endword -v 36-6-1236
+begword ved- 1236-15-145-36
+midword -ved- 36-1236-36
+
+
+### Context rules - forward translation
+
+# Exclamation at beginning of string
+noback context `["!"] @6-235
+
+# Ensure two dashes where appropriate.
+noback context $w["-"]$w @36
+noback context $sw["-"]"\xf800\xf801" @36
+noback context $sw["-"]$sw @36-36
+noback context `["-"]$sw @36-36
+noback context $sw["-"]~ @36-36
+noback context !$sw["-"]~ @36
+noback context `["-"]~ @36-36
+
+# Ensure letsign between letter and numsign
+noback context $l[]$D @6
+
+
+### context - backward translation
+
+# Ensure the correct number of dashes
+nofor context @36[@36-36] "--"
+nofor context [@36-36]@36 "--"
+nofor context $w[@36-36]$w "--"
+nofor context $sw[@36-36]$sw "-"
+nofor context `[@36-36]$sw "-"
+nofor context $sw[@36-36]~ "-"
+nofor context `@36-36~ "-"
+
+
+### Pass 2 - forward translation
+
+# No "nd", "hv", "or", or "st" after a digit and a letsign
+noback pass2 @234f-123f-2456 @6-125-1236
+noback pass2 @234f-123f-12345 @6-1345-145
+noback pass2 @234f-123f-1346 @6-135-1235
+noback pass2 @234f-123f-1356 @6-234-2345
+noback pass2 @234f-123f-1256 @6-2345-15
+# extra lines to correct hyphenation errors caused by \xf801
+noback pass2 @234f-123f-135-3456-1235 @6-135-1236-156
+noback pass2 @234f-123f-3456 @6-1236-15
+
+noback pass2 @234f-123f @6
+
+# Correct chars defined as 8 dots because they include letsign
+noback pass2 @467 @45-6
+noback pass2 @4568 @45-456
+noback pass2 @123457 @6-12345
+noback pass2 @24567 @6-2456
+noback pass2 @13467 @6-1346
+noback pass2 @13567 @6-1356
+noback pass2 @12567 @6-1256
+
+noback pass2 @6-46-5 @46-5 # no letsign before cap letters with accent
+noback pass2 @234f-123f-46-5 @46-5 # no letsign before cap letters with accent
+noback pass2 _$D[@6-46-6] *
+noback pass2 _$D[@6-46] *
+noback pass2 @6-46-6 @46-6 # Ensure correct order and no double letsign
+noback pass2 @6-46 @46-6 # Ensure correct order
+
+ ### Pass 2 - backward
+
+# Insert letsign between number (with extra punctuation) and capsletter sign
+#nofor pass2 @3456$l.$Spm$l.@3$l.@3[]@46 @6
+#nofor pass2 @3456$l.$Spm$l.@3[]@46 @6
+#nofor pass2 @3456$l.$Spm$Spm[]@46 @6
+#nofor pass2 @3456$l.$Spm[]@46 @6
+
+# Insert letsign between number (with extra punctuation) and capsword sign
+#nofor pass2 @3456$l.$Spm$l.@3$l.@3[]@456 @6
+#nofor pass2 @3456$l.$Spm$l.@34$l.@34[]@456 @6
+#nofor pass2 @3456$l.$Spm$l.@36$l.@36[]@456 @6
+#nofor pass2 @3456$l.$Spm$l.@3[]@456 @6
+#nofor pass2 @3456$l.$Spm$l.@34[]@456 @6
+#nofor pass2 @3456$l.$Spm$l.@36[]@456 @6
+#nofor pass2 @3456$l.$Spm$Spm[]@456 @6
+#nofor pass2 @3456$l.$Spm[]@456 @6
+#nofor pass2 @3456$l.[]@456 @6
+
+#nofor pass2 $l[]@46 @6
+#nofor pass2 $a[]@456 @6
+
+### Pass 3 - forward translation
+
+# Ensure there is only one letsign
+ noback pass3 @6-6 @6
+
+
+### Pass 3 - backward translation
+
+# Save letters that have been defined with letsign as part of their definitions
+nofor pass3 @6-12345 @123457
+nofor pass3 @6-2456 @24567
+nofor pass3 @6-1346 @13467
+nofor pass3 @6-1356 @13567
+nofor pass3 @6-1256 @6-12567
+
+# save ~ and | before inserting extra letsigns and endcapsword in pass 2.
+nofor pass3 @45-6 @467 # Create alternative representation of "~"
+nofor pass3 @45-456 @4568
+
+# Include hyphenation file as the last thing
+include hyph_brl_da_dk.dic
diff --git a/tables/da-dk-g26l-lit.ctb b/tables/da-dk-g26l-lit.ctb
new file mode 100644
index 0000000..8a31a21
--- /dev/null
+++ b/tables/da-dk-g26l-lit.ctb
@@ -0,0 +1,566 @@
+# Liblouis: Danish table for 6 dots grade 1.5 (grade 2l) literary, forward translation only
+#
+# Copyright (C) 2014-2017, Bue Vester-Andersen <bue@vester-andersen.dk>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# Version: Bue Vester-Andersen, 170604
+
+### Table Metadata
+
+#-index-name: Danish, partially contracted, 6-dot
+#-display-name: Danish 6-dot partially contracted braille
+
+#+locale: da
+#+type: literary
+#+contraction: partial
+#+grade: 1.5
+#+dots: 6
+#+direction: forward
+
+# Display opcodes
+include da-dk-octobraille.dis
+
+### Spaces
+
+# These ctrl-chars have to have a representation, so that they can be properly converted back and forth.
+space \t 2478 CHARACTER TABULATION
+space \n 678 LINE FEED (LF)
+space \v 1368 LINE TABULATION
+space \f 12378 FORM FEED (FF)
+space \r 257 CARRIAGE RETURN (CR)
+space \x00a0 a
+
+include spaces.uti
+
+### Character definitions
+
+# Definition of dot cells
+punctuation ! 235 EXCLAMATION MARK
+punctuation " 2356 QUOTATION MARK
+punctuation ' 4 APOSTROPHE
+punctuation ( 236 LEFT PARENTHESIS
+punctuation ) 356 RIGHT PARENTHESIS
+punctuation , 2 COMMA
+punctuation - 36 HYPHEN-MINUS
+punctuation . 3 FULL STOP
+punctuation / 34 SLASH
+punctuation : 25 COLON
+punctuation ; 23 SEMICOLON
+punctuation ? 26 QUESTION MARK
+uplow Aa 1
+uplow Bb 12
+uplow Cc 14
+uplow Dd 145
+uplow Ee 15
+uplow Ff 124
+uplow Gg 1245
+uplow Hh 125
+uplow Ii 24
+uplow Jj 245
+uplow Kk 13
+uplow Ll 123
+uplow Mm 134
+uplow Nn 1345
+uplow Oo 135
+uplow Pp 1234
+uplow Rr 1235
+uplow Ss 234
+uplow Tt 2345
+uplow Uu 136
+uplow Vv 1236
+uplow Yy 13456
+
+#use 8 dots for the following chars to avoid conflict with indicators
+uplow Qq 123457
+uplow Ww 24567
+uplow Xx 13467
+uplow Zz 13567
+punctuation | 4568 VERTICAL LINE
+punctuation ~ 467 TILDE (changed by pass 2 to not conflict with indicators
+uplow \x00dc\x00fc 12567
+
+include digits6Dots.uti
+
+punctuation \x00a7 346 SECTION SIGN (0xa7)
+
+uplow \x00c5\x00e5 16 LATIN LETTER A WITH RING ABOVE
+uplow \x00c6\x00e6 345 LATIN LETTER AE
+uplow \x00d8\x00f8 246 LATIN LETTER O WITH STROKE
+
+# cover all other Braille patterns
+include braille-patterns.cti
+
+# Characters with two or more cells
+
+punctuation # 45-3456 NUMBER SIGN
+sign $ 45-256 DOLLAR SIGN
+math % 245-356 PERCENT SIGN
+sign & 6-12346 AMPERSAND
+punctuation * 6-35 ASTERISK
+math + 45-235 PLUS SIGN
+math < 45-134 LESS-THAN SIGN
+math = 45-2356 EQUALS SIGN
+math > 45-234 GREATER-THAN SIGN
+sign @ 45-1 COMMERCIAL AT
+punctuation [ 5-236 LEFT SQUARE BRACKET
+punctuation \\ 45-16 REVERSE SLASH
+punctuation ] 5-356 RIGHT SQUARE BRACKET
+punctuation ^ 45-346 CIRCUMFLEX ACCENT
+punctuation _ 45-36 LOW LINE
+punctuation ` 4 GRAVE ACCENT
+punctuation { 45-246 LEFT CURLY BRACKET
+punctuation } 45-135 RIGHT CURLY BRACKET
+math \x00f7 45-256 DIVISION SIGN
+
+# Misc unicode characters
+include da-dk-6miscChars.cti
+
+# Litdigits
+include litdigits6Dots.uti
+
+undefined 26
+
+### Braille indicators and special characters
+
+#hyphen - 36
+
+letsign 6
+
+# No letsign before capital letters or letters with accents
+
+noletsign I\x0160\x0152\x017d\x0178\x00c0\x00c1\x00c2\x00c3\x00c7\x00c8\x00c9\x00ca\x00cb\x00cc\x00cd\x00ce\x00cf\x00d0\x00d1\x00d2\x00d3\x00d4\x00d5\x00d9\x00da\x00db\x00dc\x00dd\x00de\x008a\x008c\x008e
+noletsign i\x0161\x0153\x017e\x00ff\x00df\x00e0\x00e1\x00e2\x00e3\x00e7\x00e8\x00e9\x00ea\x00eb\x00ec\x00ed\x00ee\x00ef\x00f0\x00f1\x00f2\x00f3\x00f4\x00f5\x00f9\x00fa\x00fb\x00fd\x00fe\x009a\x009c
+
+# Emphasis opcodes
+emphclass italic
+emphclass underline
+emphclass bold
+
+begemphphrase italic 56
+endemphphrase italic after 56
+begemphword italic 56
+endemphword italic 56
+
+begemphphrase bold 56
+endemphphrase bold after 56
+begemphword bold 56
+endemphword bold 56
+
+begemphphrase underline 56
+endemphphrase underline after 56
+begemphword underline 56
+endemphword underline 56
+
+capsletter 46
+begcapsword 456
+endcapsword 68 # Used during back-translation to stop overflow of capsword
+multind 6-46 letsign capsletter
+multind 46-6 capsletter letsign
+multind 6-456 letsign begcapsword
+multind 68-6-46 endcapsword letsign capsletter
+multind 68-6-456 endcapsword letsign begcapsword
+multind 68-6 endcapsword letsign
+
+numsign 3456
+multind 6-3456 letsign numsign
+
+#class of none-space characters that demand double dashes
+# Used in context lines later.
+#must be the first class defined.
+class charsWDoubleDash .,?!/:"'() # class w
+
+### Correct - forward translation
+
+# Chars that don't require a space before percent and permille:
+class charsBeforePercent "(\x201e\x0084\x201c\x0093\x201d\x0094\x00ab\x00bb #class x
+noback correct `["%"] *
+noback correct !$sx["%"] " %"
+noback correct `["\x2030"] *
+noback correct !$sx["\x2030"] " \x2030"
+noback correct `["\x0089"] *
+noback correct !$sx["\x0089"] " \x2030"
+
+# Chars to be treated like digits when switching back to letter mode
+class extraDigits \x00bc\x00bd\x00be
+
+#Use the "correct" opcode to convert chars that can't be back-translated
+# and make the table more simple.
+
+# Dashes
+class dashes \x2013\x2014\x0096\x0097\x00ad
+noback correct %dashes "-"
+
+class quotes \x201e\x0084\x201c\x0093\x201d\x0094\x00ab\x00bb
+noback correct %quotes "\""
+
+class apostrophes `\x201a\x0082\x2039\x008b\x2018\x0091\x2019\x0092\x203a\x009b\x00b4
+noback correct %apostrophes "'"
+
+# Convert most single caps to lowercase
+
+#Special abbreviations with imbedded small letters.
+# Must be handled by case in this version of liblouis
+noback correct "KAbB" "KABB"
+noback correct "CUDiM" "CUDIM"
+
+swapcc UpperLower ABCDEFGHIJKLMNOPQRSTUVWXYZ\x0160\x0152\x017d\x0178\x00c0\x00c1\x00c2\x00c3\x00c4\x00c5\x00c6\x00c7\x00c8\x00c9\x00ca\x00cb\x00cc\x00cd\x00ce\x00cf\x00d0\x00d1\x00d2\x00d3\x00d4\x00d5\x00d6\x00d8\x00d9\x00da\x00db\x00dc\x00dd\x00de\x008a\x008c abcdefghijklmnopqrstuvwxyz\x0161\x0153\x017e\x00ff\x00e0\x00e1\x00e2\x00e3\x00e4\x00e5\x00e6\x00e7\x00e8\x00e9\x00ea\x00eb\x00ec\x00ed\x00ee\x00ef\x00f0\x00f1\x00f2\x00f3\x00f4\x00f5\x00f6\x00f8\x00f9\x00fa\x00fb\x00fc\x00fd\x00fe\x009a\x009c
+
+# I is a special case
+noback correct _$sp["I"]$sp "i"
+noback correct `["I"]$sp "i"
+noback correct _$sp["I"]~ "i"
+
+noback correct $sSpu[%UpperLower]$u %UpperLower
+noback correct `[%UpperLower]$u %UpperLower
+
+### Pass 1
+
+# Punctuations, math and numbers
+midnum , 2
+midnum . 3
+#midnum - 36
+endnum - 36
+midnum / 34
+midnum : 25
+nofor midnum ^ 346
+nofor midnum ^ 45-346
+
+midnum ^ 45-346
+midnum \x00d7 45-3-3456
+
+# various back rules for math signs etc.
+nofor midnum % 0-245-356-0-3456
+nofor endnum % 0-245-356
+nofor endnum \x2030 0-245-356-356
+nofor midnum \s 3456
+nofor midnum \x00d7 45-3-3456
+nofor midnum \x00d7 45-3
+nofor midnum \x00d7 3-3456
+
+# Punctuation
+prepunc " 2356
+postpunc " 2356
+always /\s 6-34-0
+always \s/ 0-6-34
+nofor always / 6-34
+prepunc - 36
+postpunc - 36
+nofor always \s-\s 0-36-36-0
+always :- 25-36
+always ;- 23-36
+always --- 36-36-36
+always ---- 36-36-36-36
+always ----- 36-36-36-36-36
+# Star enclosed by parentheses
+always (*) 236-35-356
+
+before punctuation before sign always ( 6-236
+
+# these characters must be separated from ")" by a letsign.
+class SepToRightpar Jj%'\x2030\x0089\x201a\x0082\x2039\x009b\x2018\x0091\x2019\x0092\x203a\x009b
+after SepToRightpar always ) 6-356
+
+prepunc ( 236
+postpunc ) 356
+always .) 3-356
+always ( 6-236
+always ) 6-356
+
+# extra back rules for ")"
+nofor after punctuation always ) 356
+nofor after punctuation always ) 68-356
+nofor always \x00b0 4-356
+nofor always ') 4-6-356
+nofor always ") 2356-356
+nofor endword j) 245-356
+nofor always ) 6-356
+
+always ... 3-3-3
+
+#inverted exclamation
+always \x00a1 6-256
+
+### Contractions ###
+
+#Special sequences, urls emails and file names.
+
+nocont $
+nocont \x005c
+nocont @
+nocont ://
+nocont www
+nocont .com
+nocont .dk
+nocont .eu
+nocont .edu
+nocont .gov
+nocont .mil
+nocont .net
+nocont .org
+nocont .uk
+nocont .doc
+nocont .exe
+nocont .htm
+nocont .tex
+nocont .txt
+nocont .gif
+nocont .jpg
+nocont .png
+nocont .wav
+nocont .tar
+nocont .zip
+
+#Words
+word at 1
+word bliver 12
+word den 12346
+word der 23456
+word det 2346
+word de 1456
+word du 145
+word efter 1356
+word eller 15
+word en 126
+word er 156
+word et 346
+word for 124
+word før 246
+word gennem 12456
+word gør 1245
+word han 13456
+word har 125
+word hun 136
+word hvad 2456
+word hvor 34
+word jeg 245
+word kan 13
+word lige 123
+word med 134
+word men 146
+word ned 1246
+word når 1345
+word og 14
+word op 135
+word over 1346
+word på 1234
+word ret 12356
+word rigtig 1235
+word skal 123456
+word som 234
+word så 16
+word te 1256
+word til 2345
+word under 12345
+word ve 3456
+word ved 1236
+word være 345
+
+# Common combinations of one word contractions with slash
+word af/på 356-34-1234
+word af/på 356-34-68-1234
+word du/i 145-34-24
+word du/i 145-34-68-24
+word eller/og 15-34-14
+word eller/og 15-34-68-14
+word fra/til 235-34-2345
+word fra/til 235-34-68-2345
+word han/hun 13456-34-136
+word han/hun 13456-34-68-136
+word hun/han 136-34-13456
+word hun/han 136-34-68-13456
+word i/du 24-34-145
+word i/du 24-34-68-145
+word og/eller 14-34-15
+word og/eller 14-34-68-15
+word over/under 1346-34-12345
+word over/under 1346-34-68-12345
+word på/af 1234-34-356
+word på/af 1234-34-68-356
+word til/fra 2345-34-235
+word til/fra 2345-34-68-235
+word under/over 12345-34-1346
+word under/over 12345-34-68-1346
+
+# no backtrans of ^1 and `2. use contractions
+nofor always eta 346-1
+nofor always etb 346-12
+always etc 346-14
+
+# Ensure no one-letter word contraction before or after a dash
+
+endword -af 36-1-124
+begword af- 1-124-36
+endword -altid 36-1-2345-145
+begword altid- 1-2345-145-36
+endword -at 36-1-2345
+endword -a 36-6-1
+begword at- 1-2345-36
+endword -og 36-135-1245
+endword -c 36-6-14
+begword og- 135-1245-36
+endword -du 36-145-136
+endword -d 36-6-145
+begword du- 145-136-36
+endword -efter 36-15-124-2345-156
+endword -z 36-6-1356
+begword efter- 15-124-2345-156-36
+midword -efter- 36-1356-36
+endword -e 36-6-15
+endword -for 36-124-1346
+endword -f 36-6-124
+begword for- 124-1346-36
+endword -fra 36-124-1235-1
+begword fra- 124-1235-1-36
+endword -g 36-6-1245
+endword -gennem 36-1245-126-1246-134
+begword gennem- 1245-126-1246-134-36
+endword -ham 36-125-1-134
+begword ham- 125-1-134-36
+endword -han 36-125-1-1345
+endword -y 36-6-13456
+begword han- 125-1-1345-36
+endword -har 36-125-1-1235
+endword -h 36-6-125
+begword har- 125-1-1235-36
+endword -hun 36-125-136-1345
+endword -u 36-6-136
+begword hun- 125-136-1345-36
+endword -j 36-6-245
+endword -kan 36-13-1-1345
+endword -k 36-6-13
+begword kan- 13-1-1345-36
+endword -lige 36-123-24-12456
+endword -l 36-6-123
+begword lige- 123-24-12456-36
+endword -med 36-146-145
+endword -m 36-6-134
+begword med- 146-145-36
+endword -men 36-134-126
+begword men- 134-126-36
+ endword -ned 36-1246-145
+begword ned- 1246-145-36
+endword -når 36-1345-16-1235
+endword -n 36-6-1345
+begword når- 1345-16-1235-36
+endword -op 36-135-1234
+endword -o 36-6-135
+begword op- 135-1234-36
+endword -over 36-135-1236-156
+endword -x 36-6-1346
+begword over- 135-1236-156-36
+endword -på 36-1234-16
+endword -p 36-6-1234
+begword på- 1234-16-36
+midword -på- 36-1234-36
+endword -ret 36-1235-346
+begword ret- 1235-346-36
+midword -ret- 36-12356-36
+endword -rigtig 36-1235-35-2345-35
+endword -r 36-6-1235
+begword rigtig- 1235-35-2345-35-36
+midword -rigtig- 36-1235-36
+endword -skal 36-123456-1-123
+begword skal- 123456-1-123-36
+midword -skal- 36-123456-36
+endword -som 36-234-135-134
+endword -s 36-6-234
+begword som- 234-135-134-36
+midword -som- 36-234-36
+endword -så 36-234-16
+endword -å 36-6-16
+begword så- 234-16-36
+endword -til 36-2345-24-123
+endword -t 36-6-2345
+begword til- 2345-24-123-36
+midword -til- 36-2345-36
+endword -under 36-136-1345-23456
+begword under- 136-1345-23456-36
+midword -under- 36-12345-36
+endword -ved 36-1236-15-145
+endword -v 36-6-1236
+begword ved- 1236-15-145-36
+midword -ved- 36-1236-36
+
+
+### Context rules - forward translation
+
+# Substitutions for joinnum rules with common math signs
+noback context $dy$s["-"$s]$dy @36
+noback context $dy$s["+"$s]$dy @235
+noback context $dy$s["\x00d7"$s]$dy @3
+noback context $dy$s["\x00f7"$s]$dy @256
+noback context $dy$s["="$s]$dy @2356
+
+# Space on each side of = when between letters or punctuation.
+noback context $lp["="]$lp @0-2356-0
+
+# Exclamation at beginning of string
+noback context `["!"] @6-235
+
+# Ensure two dashes where appropriate.
+noback context $w["-"]$w @36
+noback context $sw["-"]$sw @36-36
+noback context `["-"]$sw @36-36
+noback context $sw["-"]~ @36-36
+noback context !$sw["-"]~ @36
+noback context `["-"]~ @36-36
+
+# Ensure letsign between letter and numsign
+noback context $l[]$D @6
+
+# No "nd", "hv", "or", or "st" after a digit and a letsign
+noback context $dy["hv"] @6-125-1236
+noback context $dy$Spm["hv"] @6-125-1236
+noback context $dy["nd"] @6-1345-145
+noback context $dy$Spm["nd"] @6-1345-145
+noback context $dy["or"] @6-135-1235
+noback context $dy$Spm["or"] @6-135-1235
+noback context $dy["st"] @6-234-2345
+noback context $dy$Spm["st"] @6-234-2345
+noback context $dy["te"] @6-2345-15
+noback context $dy$Spm["te"] @6-2345-15
+
+
+#ensure dot 6 between a digit and a letter
+noback context $dy[]$u @6
+noback context $dy$Spm.[]$u @6
+
+### Pass 2 - forward translation
+
+# Correct chars defined as 8 dots because they include letsign
+noback pass2 @467 @45-6
+noback pass2 @4568 @45-456
+noback pass2 @123457 @6-12345
+noback pass2 @24567 @6-2456
+noback pass2 @13467 @6-1346
+noback pass2 @13567 @6-1356
+noback pass2 @12567 @6-1256
+
+# Show endcapsword as dot 6 (letsign)
+noback pass2 @68 @6
+
+noback pass2 @6-46-5 @46-5 # no letsign before cap letters with accent
+noback pass2 _$D[@6-46-6] *
+noback pass2 _$D[@6-46] *
+noback pass2 @6-46-6 @46-6 # Ensure correct order and no double letsign
+noback pass2 @6-46 @46-6 # Ensure correct order
+
+### Pass 3 - forward translation
+
+# Ensure there is only one letsign
+ noback pass3 @6-6 @6
diff --git a/tables/da-dk-g26l.ctb b/tables/da-dk-g26l.ctb
new file mode 100644
index 0000000..8d7840d
--- /dev/null
+++ b/tables/da-dk-g26l.ctb
@@ -0,0 +1,584 @@
+# Liblouis: Danish table for 6 dots grade 1.5 (grade 2l) forward and backward translation
+#
+# Copyright (C) 2014-2017, Bue Vester-Andersen <bue@vester-andersen.dk>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# Version: Bue Vester-Andersen, 170604
+
+### Table Metadata
+
+#-index-name: Danish, partially contracted, 6-dot
+#-display-name: Danish 6-dot partially contracted braille
+
+#+locale: da
+#+type: literary
+#+contraction: partial
+#+grade: 1.5
+#+dots: 6
+#+direction: both
+
+# Display opcodes
+include da-dk-octobraille.dis
+
+### Spaces
+
+# These ctrl-chars have to have a representation, so that they can be properly converted back and forth.
+space \t 2478 CHARACTER TABULATION
+space \n 678 LINE FEED (LF)
+space \v 1368 LINE TABULATION
+space \f 12378 FORM FEED (FF)
+space \r 257 CARRIAGE RETURN (CR)
+space \x00a0 a
+
+include spaces.uti
+
+### Character definitions
+
+# Definition of dot cells
+punctuation ! 235 EXCLAMATION MARK
+punctuation " 2356 QUOTATION MARK
+punctuation ' 4 APOSTROPHE
+punctuation ( 236 LEFT PARENTHESIS
+punctuation ) 356 RIGHT PARENTHESIS
+punctuation , 2 COMMA
+punctuation - 36 HYPHEN-MINUS
+punctuation . 3 FULL STOP
+punctuation / 34 SLASH
+punctuation : 25 COLON
+punctuation ; 23 SEMICOLON
+punctuation ? 26 QUESTION MARK
+uplow Aa 1
+uplow Bb 12
+uplow Cc 14
+uplow Dd 145
+uplow Ee 15
+uplow Ff 124
+uplow Gg 1245
+uplow Hh 125
+uplow Ii 24
+uplow Jj 245
+uplow Kk 13
+uplow Ll 123
+uplow Mm 134
+uplow Nn 1345
+uplow Oo 135
+uplow Pp 1234
+uplow Rr 1235
+uplow Ss 234
+uplow Tt 2345
+uplow Uu 136
+uplow Vv 1236
+uplow Yy 13456
+
+#use 8 dots for the following chars to avoid conflict with indicators
+uplow Qq 123457
+uplow Ww 24567
+uplow Xx 13467
+uplow Zz 13567
+punctuation | 4568 VERTICAL LINE
+punctuation ~ 467 TILDE (changed by pass 2 to not conflict with indicators
+uplow \x00dc\x00fc 12567
+
+include digits6Dots.uti
+
+punctuation \x00a7 346 SECTION SIGN (0xa7)
+
+uplow \x00c5\x00e5 16 LATIN LETTER A WITH RING ABOVE
+uplow \x00c6\x00e6 345 LATIN LETTER AE
+uplow \x00d8\x00f8 246 LATIN LETTER O WITH STROKE
+
+# cover all other Braille patterns
+include braille-patterns.cti
+
+# Characters with two or more cells
+
+punctuation # 45-3456 NUMBER SIGN
+sign $ 45-256 DOLLAR SIGN
+math % 245-356 PERCENT SIGN
+sign & 6-12346 AMPERSAND
+punctuation * 6-35 ASTERISK
+math + 45-235 PLUS SIGN
+math < 45-134 LESS-THAN SIGN
+math = 45-2356 EQUALS SIGN
+math > 45-234 GREATER-THAN SIGN
+sign @ 45-1 COMMERCIAL AT
+punctuation [ 5-236 LEFT SQUARE BRACKET
+punctuation \\ 45-16 REVERSE SLASH
+punctuation ] 5-356 RIGHT SQUARE BRACKET
+punctuation ^ 45-346 CIRCUMFLEX ACCENT
+punctuation _ 45-36 LOW LINE
+punctuation ` 4 GRAVE ACCENT
+punctuation { 45-246 LEFT CURLY BRACKET
+punctuation } 45-135 RIGHT CURLY BRACKET
+math \x00f7 45-256 DIVISION SIGN
+
+# Misc unicode characters
+include da-dk-6miscChars.cti
+
+# Litdigits
+include litdigits6Dots.uti
+midendnumericmodechars /,.:^
+
+undefined 26
+
+### Braille indicators and special characters
+
+#hyphen - 36
+
+letsign 6
+
+# No letsign before capital letters or letters with accents
+
+noletsign I\x0160\x0152\x017d\x0178\x00c0\x00c1\x00c2\x00c3\x00c7\x00c8\x00c9\x00ca\x00cb\x00cc\x00cd\x00ce\x00cf\x00d0\x00d1\x00d2\x00d3\x00d4\x00d5\x00d9\x00da\x00db\x00dc\x00dd\x00de\x008a\x008c\x008e
+noletsign i\x0161\x0153\x017e\x00ff\x00df\x00e0\x00e1\x00e2\x00e3\x00e7\x00e8\x00e9\x00ea\x00eb\x00ec\x00ed\x00ee\x00ef\x00f0\x00f1\x00f2\x00f3\x00f4\x00f5\x00f9\x00fa\x00fb\x00fd\x00fe\x009a\x009c
+
+# Emphasis opcodes
+emphclass italic
+emphclass underline
+emphclass bold
+
+begemphphrase italic 56
+endemphphrase italic after 56
+begemphword italic 56
+endemphword italic 56
+
+begemphphrase bold 56
+endemphphrase bold after 56
+begemphword bold 56
+endemphword bold 56
+
+begemphphrase underline 56
+endemphphrase underline after 56
+begemphword underline 56
+endemphword underline 56
+
+capsletter 46
+begcapsword 456
+endcapsword 6
+multind 6-46 letsign capsletter
+multind 46-6 capsletter letsign
+multind 6-456 letsign begcapsword
+
+numsign 3456
+multind 6-3456 letsign numsign
+
+#class of none-space characters that demand double dashes
+# Used in context lines later.
+#must be the first class defined.
+class charsWDoubleDash .,?!/:"'() # class w
+
+### Correct - forward translation
+
+# Chars that don't require a space before percent and permille:
+class charsBeforePercent "(\x201e\x0084\x201c\x0093\x201d\x0094\x00ab\x00bb #class x
+noback correct `["%"] *
+noback correct !$sx["%"] " %"
+noback correct `["\x2030"] *
+noback correct !$sx["\x2030"] " \x2030"
+noback correct `["\x0089"] *
+noback correct !$sx["\x0089"] " \x2030"
+
+# Chars to be treated like digits when switching back to letter mode
+class extraDigits \x00bc\x00bd\x00be
+
+#Use the "correct" opcode to convert chars that can't be back-translated
+# and make the table more simple.
+
+# Dashes
+class dashes \x2013\x2014\x0096\x0097\x00ad
+noback correct %dashes "-"
+
+class quotes \x201e\x0084\x201c\x0093\x201d\x0094\x00ab\x00bb
+noback correct %quotes "\""
+
+class apostrophes `\x201a\x0082\x2039\x008b\x2018\x0091\x2019\x0092\x203a\x009b\x00b4
+noback correct %apostrophes "'"
+
+### Correct - backward translation
+
+# characters that may get mangled by the insertion of extra letsigns
+nofor correct "\x2818" "~"
+#nofor correct "\x282f" "&"
+#nofor correct "\x2814" "*"
+
+# Try to distinguish between times (\x00d7) and bullit (\x2022),
+# which share the same Braille representation.
+nofor correct `["\x00d7"] "\x2022"
+# nofor correct $d["\s\x00d7\s"]$d * #apparently doesn't work now
+nofor correct ["\x00d7"]!$d "\x2022"
+nofor correct !$d["\x00d7"] "\x2022"
+
+nofor correct "\x28a0" ? # Extraneous endcaps signs
+#nofor correct "\x2820" ?
+nofor correct "~\\456/" "|"
+
+### Pass 1 - Forward and backward
+
+# Punctuations, math and numbers
+#midnum , 2
+#midnum . 3
+#midnum - 36
+endnum - 36
+#midnum / 34
+#midnum : 25
+nofor midnum ^ 346
+nofor midnum ^ 45-346
+
+midnum ^ 45-346
+midnum \x00d7 45-3
+
+# various back rules for math signs etc.
+nofor midnum % 0-245-356-0-3456
+nofor endnum % 0-245-356
+nofor endnum \x2030 0-245-356-356
+nofor midnum \s 3456
+nofor midnum \x00d7 45-3-3456
+nofor midnum \x00d7 45-3
+nofor midnum \x00d7 3-3456
+
+# Punctuation
+prepunc " 2356
+postpunc " 2356
+always /\s 6-34-0
+always \s/ 0-6-34
+nofor always / 6-34
+prepunc - 36
+postpunc - 36
+nofor always \s-\s 0-36-36-0
+always :- 25-36
+always ;- 23-36
+always --- 36-36-36
+always ---- 36-36-36-36
+always ----- 36-36-36-36-36
+# Star enclosed by parentheses
+always (*) 236-35-356
+
+before punctuation before sign always ( 6-236
+
+# these characters must be separated from ")" by a letsign.
+class SepToRightpar Jj%'\x2030\x0089\x201a\x0082\x2039\x009b\x2018\x0091\x2019\x0092\x203a\x009b
+after SepToRightpar always ) 6-356
+
+prepunc ( 236
+postpunc ) 356
+always .) 3-356
+always ( 6-236
+always ) 6-356
+
+# extra back rules for ")"
+nofor after punctuation always ) 356
+nofor always \x00b0 4-356
+nofor always ') 4-6-356
+nofor always ") 2356-356
+nofor endword j) 245-356
+nofor always ) 6-356
+
+always ... 3-3-3
+
+#inverted exclamation
+always \x00a1 6-256
+
+### Contractions ###
+
+#Special sequences, urls emails and file names.
+
+nocont $
+nocont \x005c
+nocont @
+nocont ://
+nocont www
+nocont .com
+nocont .dk
+nocont .eu
+nocont .edu
+nocont .gov
+nocont .mil
+nocont .net
+nocont .org
+nocont .uk
+nocont .doc
+nocont .exe
+nocont .htm
+nocont .tex
+nocont .txt
+nocont .gif
+nocont .jpg
+nocont .png
+nocont .wav
+nocont .tar
+nocont .zip
+
+#Words
+word at 1
+word bliver 12
+word den 12346
+word der 23456
+word det 2346
+word de 1456
+word du 145
+word efter 1356
+word eller 15
+word en 126
+word er 156
+word et 346
+word for 124
+word før 246
+word gennem 12456
+word gør 1245
+word han 13456
+word har 125
+word hun 136
+word hvad 2456
+word hvor 34
+word jeg 245
+word kan 13
+word lige 123
+word med 134
+word men 146
+word ned 1246
+word når 1345
+word og 14
+word op 135
+word over 1346
+word på 1234
+word ret 12356
+word rigtig 1235
+word skal 123456
+word som 234
+word så 16
+word te 1256
+word til 2345
+word under 12345
+word ve 3456
+word ved 1236
+word være 345
+
+# Common combinations of one word contractions with slash
+word af/på 356-34-1234
+word du/i 145-34-24
+word eller/og 15-34-14
+word fra/til 235-34-2345
+word han/hun 13456-34-136
+word hun/han 136-34-13456
+word i/du 24-34-145
+word og/eller 14-34-15
+word over/under 1346-34-12345
+word på/af 1234-34-356
+word til/fra 2345-34-235
+word under/over 12345-34-1346
+
+# no backtrans of ^1 and `2. use contractions
+nofor always eta 346-1
+nofor always etb 346-12
+always etc 346-14
+
+# Ensure no one-letter word contraction before or after a dash
+
+endword -af 36-1-124
+begword af- 1-124-36
+endword -altid 36-1-2345-145
+begword altid- 1-2345-145-36
+endword -at 36-1-2345
+endword -a 36-6-1
+begword at- 1-2345-36
+endword -og 36-135-1245
+endword -c 36-6-14
+begword og- 135-1245-36
+endword -du 36-145-136
+endword -d 36-6-145
+begword du- 145-136-36
+endword -efter 36-15-124-2345-156
+endword -z 36-6-1356
+begword efter- 15-124-2345-156-36
+midword -efter- 36-1356-36
+endword -e 36-6-15
+endword -for 36-124-1346
+endword -f 36-6-124
+begword for- 124-1346-36
+endword -fra 36-124-1235-1
+begword fra- 124-1235-1-36
+endword -g 36-6-1245
+endword -gennem 36-1245-126-1246-134
+begword gennem- 1245-126-1246-134-36
+endword -ham 36-125-1-134
+begword ham- 125-1-134-36
+endword -han 36-125-1-1345
+endword -y 36-6-13456
+begword han- 125-1-1345-36
+endword -har 36-125-1-1235
+endword -h 36-6-125
+begword har- 125-1-1235-36
+endword -hun 36-125-136-1345
+endword -u 36-6-136
+begword hun- 125-136-1345-36
+endword -j 36-6-245
+endword -kan 36-13-1-1345
+endword -k 36-6-13
+begword kan- 13-1-1345-36
+endword -lige 36-123-24-12456
+endword -l 36-6-123
+begword lige- 123-24-12456-36
+endword -med 36-146-145
+endword -m 36-6-134
+begword med- 146-145-36
+endword -men 36-134-126
+begword men- 134-126-36
+ endword -ned 36-1246-145
+begword ned- 1246-145-36
+endword -når 36-1345-16-1235
+endword -n 36-6-1345
+begword når- 1345-16-1235-36
+endword -op 36-135-1234
+endword -o 36-6-135
+begword op- 135-1234-36
+endword -over 36-135-1236-156
+endword -x 36-6-1346
+begword over- 135-1236-156-36
+endword -på 36-1234-16
+endword -p 36-6-1234
+begword på- 1234-16-36
+midword -på- 36-1234-36
+endword -ret 36-1235-346
+begword ret- 1235-346-36
+midword -ret- 36-12356-36
+endword -rigtig 36-1235-35-2345-35
+endword -r 36-6-1235
+begword rigtig- 1235-35-2345-35-36
+midword -rigtig- 36-1235-36
+endword -skal 36-123456-1-123
+begword skal- 123456-1-123-36
+midword -skal- 36-123456-36
+endword -som 36-234-135-134
+endword -s 36-6-234
+begword som- 234-135-134-36
+midword -som- 36-234-36
+endword -så 36-234-16
+endword -å 36-6-16
+begword så- 234-16-36
+endword -til 36-2345-24-123
+endword -t 36-6-2345
+begword til- 2345-24-123-36
+midword -til- 36-2345-36
+endword -under 36-136-1345-23456
+begword under- 136-1345-23456-36
+midword -under- 36-12345-36
+endword -ved 36-1236-15-145
+endword -v 36-6-1236
+begword ved- 1236-15-145-36
+midword -ved- 36-1236-36
+
+
+### Context rules - forward translation
+
+# Exclamation at beginning of string
+noback context `["!"] @6-235
+
+# Ensure two dashes where appropriate.
+noback context $w["-"]$w @36
+noback context $sw["-"]$sw @36-36
+noback context `["-"]$sw @36-36
+noback context $sw["-"]~ @36-36
+noback context !$sw["-"]~ @36
+noback context `["-"]~ @36-36
+
+# Ensure letsign between letter and numsign
+noback context $l[]$D @6
+
+# No "nd", "hv", "or", or "st" after a digit and a letsign
+noback context $dy["hv"] @6-125-1236
+noback context $dy$Spm["hv"] @6-125-1236
+noback context $dy["nd"] @6-1345-145
+noback context $dy$Spm["nd"] @6-1345-145
+noback context $dy["or"] @6-135-1235
+noback context $dy$Spm["or"] @6-135-1235
+noback context $dy["st"] @6-234-2345
+noback context $dy$Spm["st"] @6-234-2345
+noback context $dy["te"] @6-2345-15
+noback context $dy$Spm["te"] @6-2345-15
+
+
+#ensure dot 6 between a digit and a letter
+noback context $dy[]$u @6
+noback context $dy$Spm.[]$u @6
+
+### context - backward translation
+
+# Ensure the correct number of dashes
+nofor context @36[@36-36] "--"
+nofor context [@36-36]@36 "--"
+nofor context $w[@36-36]$w "--"
+nofor context $sw[@36-36]$sw "-"
+nofor context `[@36-36]$sw "-"
+nofor context $sw[@36-36]~ "-"
+nofor context `@36-36~ "-"
+
+
+### Pass 2 - forward translation
+
+# Correct chars defined as 8 dots because they include letsign
+noback pass2 @467 @45-6
+noback pass2 @4568 @45-456
+noback pass2 @123457 @6-12345
+noback pass2 @24567 @6-2456
+noback pass2 @13467 @6-1346
+noback pass2 @13567 @6-1356
+noback pass2 @12567 @6-1256
+
+noback pass2 @6-46-5 @46-5 # no letsign before cap letters with accent
+noback pass2 _$D[@6-46-6] *
+noback pass2 _$D[@6-46] *
+noback pass2 @6-46-6 @46-6 # Ensure correct order and no double letsign
+noback pass2 @6-46 @46-6 # Ensure correct order
+
+ ### Pass 2 - backward
+
+# Insert letsign between number (with extra punctuation) and capsletter sign
+#nofor pass2 @3456$l.$Spm$l.@3$l.@3[]@46 @6
+#nofor pass2 @3456$l.$Spm$l.@3[]@46 @6
+#nofor pass2 @3456$l.$Spm$Spm[]@46 @6
+#nofor pass2 @3456$l.$Spm[]@46 @6
+
+## Insert letsign between number (with extra punctuation) and capsword sign
+#nofor pass2 @3456$l.$Spm$l.@3$l.@3[]@456 @6
+#nofor pass2 @3456$l.$Spm$l.@34$l.@34[]@456 @6
+#nofor pass2 @3456$l.$Spm$l.@36$l.@36[]@456 @6
+#nofor pass2 @3456$l.$Spm$l.@3[]@456 @6
+#nofor pass2 @3456$l.$Spm$l.@34[]@456 @6
+#nofor pass2 @3456$l.$Spm$l.@36[]@456 @6
+#nofor pass2 @3456$l.$Spm$Spm[]@456 @6
+#nofor pass2 @3456$l.$Spm[]@456 @6
+#nofor pass2 @3456$l.[]@456 @6
+
+### Pass 3 - forward translation
+
+# Ensure there is only one letsign
+ noback pass3 @6-6 @6
+
+
+### Pass 3 - backward translation
+
+# Save letters that have been defined with letsign as part of their definitions
+nofor pass3 @6-12345 @6-123457
+nofor pass3 @6-2456 @6-24567
+nofor pass3 @6-1346 @6-13467
+nofor pass3 @6-1356 @13567
+nofor pass3 @6-1256 @6-12567
+
+# save ~ and | before inserting extra letsigns and endcapsword in pass 2.
+nofor pass3 @45-6 @467 # Create alternative representation of "~"
+nofor pass3 @45-456 @4568
diff --git a/tables/da-dk-g28.ctb b/tables/da-dk-g28.ctb
new file mode 100644
index 0000000..3d2b313
--- /dev/null
+++ b/tables/da-dk-g28.ctb
@@ -0,0 +1,1502 @@
+# liblouis: Danish, table for 8 dots grade 2 (forward and backward translation)
+#
+# Copyright (C) 2014-2017, Bue Vester-Andersen <bue@vester-andersen.dk>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#------------
+#
+# This is the Danish table for 8 dots grade 2 (stor forkortelse).
+# Use this table for translation and back-translation of Danish 8 dots grade 2.
+#
+# Version: Bue Vester-Andersen, 160713
+
+### Table Metadata
+
+#-name: Dansk forkortet 8-punkt
+#-index-name: Danish, contracted, 8-dot
+#-display-name: Danish 8-dot contracted braille
+
+#+locale: da
+#+type: literary
+#+contraction: full
+#+grade: 2
+#+dots: 8
+#+direction: both
+
+#-has-nocross: yes
+
+# Display upcodes
+include da-dk-octobraille.dis
+
+### Character definitions ###
+
+sign \x0000 8 NULL
+sign \x0001 178 START OF HEADING
+sign \x0002 1278 START OF TEXT
+sign \x0003 1478 END OF TEXT
+sign \x0004 14578 END OF TRANSMISSION
+sign \x0005 24568 ENQUIRY
+sign \x0006 12478 ACKNOWLEDGE
+sign \x0007 124578 BELL
+sign \x0008 12578 BACKSPACE
+space \t 2478 CHARACTER TABULATION
+space \n 678 LINE FEED (LF)
+space \v 1368 LINE TABULATION
+space \f 12378 FORM FEED (FF)
+space \r 257 CARRIAGE RETURN (CR)
+sign \x000e 134578 SHIFT OUT
+sign \x000f 12358 SHIFT IN
+sign \x0010 123478 DATA LINK ESCAPE
+sign \x0011 1234578 DEVICE CONTROL ONE
+sign \x0012 13568 DEVICE CONTROL TWO
+sign \x0013 4578 DEVICE CONTROL THREE
+sign \x0014 268 DEVICE CONTROL FOUR
+sign \x0015 13678 NEGATIVE ACKNOWLEDGE
+sign \x0016 278 SYNCHRONOUS IDLE
+sign \x0017 3578 END OF TRANSMISSION BLOCK
+sign \x0018 78 CANCEL
+sign \x0019 68 END OF MEDIUM
+sign \x001a 135678 SUBSTITUTE
+sign \x001b 2678 ESCAPE
+sign \x001c 45678 INFORMATION SEPARATOR FOUR
+sign \x001d 12368 INFORMATION SEPARATOR THREE
+sign \x001e 1234678 INFORMATION SEPARATOR TWO
+sign \x001f 235678 INFORMATION SEPARATOR ONE
+space \s 0 SPACE
+punctuation ! 235 EXCLAMATION MARK
+punctuation " 2356 QUOTATION MARK
+punctuation # 34568 NUMBER SIGN
+sign $ 25678 DOLLAR SIGN
+math % 24578 PERCENT SIGN
+sign & 123468 AMPERSAND
+punctuation ' 4 APOSTROPHE
+punctuation ( 2368 LEFT PARENTHESIS
+punctuation ) 3568 RIGHT PARENTHESIS
+math + 2358 PLUS SIGN
+punctuation , 2 COMMA
+punctuation - 368 HYPHEN-MINUS
+punctuation . 3 FULL STOP
+punctuation / 348 SLASH
+include digits8Dots.uti
+punctuation : 25 COLON
+punctuation ; 23 SEMICOLON
+math < 358 LESS-THAN SIGN
+math = 23568 EQUALS SIGN
+math > 267 GREATER-THAN SIGN
+punctuation ? 26 QUESTION MARK
+sign @ 478 COMMERCIAL AT
+uplow Aa 17,1 LATIN LETTER A
+uplow Bb 127,12 LATIN LETTER B
+uplow Cc 147,14 LATIN LETTER C
+uplow Dd 1457,145 LATIN LETTER D
+uplow Ee 157,15 LATIN LETTER E
+uplow Ff 1247,124 LATIN LETTER F
+uplow Gg 12457,1245 LATIN LETTER G
+uplow Hh 1257,125 LATIN LETTER H
+uplow Ii 247,24 LATIN LETTER I
+uplow Jj 2457,245 LATIN LETTER J
+uplow Kk 137,13 LATIN LETTER K
+uplow Ll 1237,123 LATIN LETTER L
+uplow Mm 1347,134 LATIN LETTER M
+uplow Nn 13457,1345 LATIN LETTER N
+uplow Oo 1357,135 LATIN LETTER O
+uplow Pp 12347,1234 LATIN CAPITAL LETTER P
+uplow Rr 12357,1235 LATIN LETTER R
+uplow Ss 2347,234 LATIN LETTER S
+uplow Tt 23457,2345 LATIN LETTER T
+uplow Uu 1367,136 LATIN LETTER U
+uplow Vv 12367,1236 LATIN LETTER V
+uplow Yy 134567,13456 LATIN LETTER Y
+punctuation [ 23678 LEFT SQUARE BRACKET
+punctuation ] 35678 RIGHT SQUARE BRACKET
+punctuation ^ 12348 CIRCUMFLEX ACCENT
+punctuation _ 3678 LOW LINE
+punctuation ` 5 GRAVE ACCENT
+punctuation { 123678 LEFT CURLY BRACKET
+punctuation | 4568 VERTICAL LINE
+punctuation } 345678 RIGHT CURLY BRACKET
+punctuation ~ 467 TILDE
+sign \x007f 7 DELETE
+sign \x20AC 1578 #EURO SIGN (0x80)
+noback sign \x0080 1578 #EURO SIGN (0x80)
+sign \x0081 45 <control-0081>
+punctuation \x201A 457 #Low single quote (0x82)
+noback punctuation \x0082 457 #Low single quote (0x82)
+sign \x0192 58 #Flurihn (0x83)
+noback sign \x0083 58 #Flurihn (0x83)
+punctuation \x201E 2378 #Low quote (0x84)
+noback punctuation \x0084 2378 #Low quote (0x84)
+letter \x2020 2357 #Dagger (0x86
+noback letter \x0086 2357 #Dagger (0x86
+letter \x2021 23578 #Double dagger (0x87
+noback letter \x0087 23578 #Double dagger (0x87
+letter \x02c6 5678 #Modifier letter circumflex (0x88)
+noback letter \x0088 5678 #Modifier letter circumflex (0x88)
+math \x2030 245678 #permille sign (0x89)
+noback math \x0089 245678 #permille sign (0x89)
+uplow \x0160\x0161 23478,2348 #LATIN CAPITAL LETTER S WITH CARON (0x8a)
+noback uplow \x008a\x009a 23478,2348 #LATIN LETTER S WITH CARON (0x8a)
+punctuation \x2039 456 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK (0x8b)
+noback punctuation \x008b 456 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK (0x8b)
+uplow \x0152\x0153 13578,1358 #LATIN CAPITAL LIGATURE OE (0x8c)
+noback uplow \x008c\x009c 13578,1358 #LATIN LIGATURE OE (0x8c)
+sign \x008d 3567 REVERSE LINE FEED (not defined in cp1252)
+letter \x008f 27 SINGLE SHIFT THREE (not defined in cp1252)
+letter \x0090 357 DEVICE CONTROL STRING (not defined in cp1252)
+punctuation \x2018 47 #LEFT SINGLE QUOTATION MARK (0x91)
+noback punctuation \x0091 47 #LEFT SINGLE QUOTATION MARK (0x91)
+punctuation \x2019 48 #RIGHT SINGLE QUOTATION MARK (0x92)
+noback punctuation \x0092 48 #RIGHT SINGLE QUOTATION MARK (0x92)
+punctuation \x201c 237 #LEFT DOUBLE QUOTATION MARK (0x93)
+noback punctuation \x0093 237 #LEFT DOUBLE QUOTATION MARK (0x93)
+punctuation \x201d 568 #RIGHT DOUBLE QUOTATION MARK (0x94)
+noback punctuation \x0094 568 #RIGHT DOUBLE QUOTATION MARK (0x94)
+sign \x2022 37 #Bullit (0x95)
+noback sign \x0095 37 #Bullit (0x95)
+sign \x02DC 46 #SMALL TILDE (0x98)
+noback sign \x0098 46 #SMALL TILDE (0x98)
+sign \x2122 234578 #TRADE MARK SIGN (0x99)
+noback sign \x0099 234578 #TRADE MARK SIGN (0x99)
+punctuation \x203A 4567 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (0x9b)
+noback punctuation \x009b 4567 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (0x9b)
+letter \x009d 2567 OPERATING SYSTEM COMMAND
+uplow \x0178\x00ff 2345678,234568 #LATIN LETTER Y WITH DIAERESIS (0x9f)
+noback uppercase \x009f 2345678 #LATIN LETTER Y WITH DIAERESIS (0x9f)
+punctuation \x00a0 23458 NO-BREAK SPACE (0xa0)
+punctuation \x00a1 256 INVERTED EXCLAMATION MARK )0xa1)
+punctuation \x00a2 2578 CENT SIGN (0xa2)
+punctuation \x00a3 1238 POUND SIGN (0xa3)
+punctuation \x00a5 67 YEN SIGN (0xa5)
+punctuation \x00a6 3478 BROKEN BAR (0xa6)
+punctuation \x00a7 578 SECTION SIGN (0xa7)
+punctuation \x00a9 134678 COPYRIGHT SIGN (0xa9)
+letter \x00aa 234678 FEMININE ORDINAL INDICATOR (0xaa)
+punctuation \x00ab 57 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (0xab)
+letter \x00ad 378 SOFT HYPHEN (0xad)
+punctuation \x00ae 123578 REGISTERED SIGN (0xae)
+punctuation \x00af 23567 MACRON (0xaf)
+math \x00b1 123458 PLUS-MINUS SIGN
+punctuation \x00b2 238 SUPERSCRIPT TWO
+punctuation \x00b3 258 SUPERSCRIPT THREE
+punctuation \x00b4 468 ACUTE ACCENT
+punctuation \x00b6 1234568 PILCROW SIGN
+punctuation \x00b7 38 MIDDLE DOT
+punctuation \x00b8 4678 CEDILLA
+punctuation \x00b9 28 SUPERSCRIPT ONE
+letter \x00ba 12345678 MASCULINE ORDINAL INDICATOR
+punctuation \x00bb 567 RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+punctuation \x00bc 13458 VULGAR FRACTION ONE QUARTER
+punctuation \x00bd 458 VULGAR FRACTION ONE HALF
+uplow \x00c1\x00e1 1235678,123568 LATIN LETTER A WITH ACUTE
+uplow \x00c2\x00e2 1678,168 LATIN LETTER A WITH CIRCUMFLEX
+uplow \x00c3\x00e3 14678,1468 LATIN LETTER A WITH TILDE
+uplow \x00c4\x00e4 34578,3458 LATIN LETTER A WITH DIAERESIS
+uplow \x00c5\x00e5 167,16 LATIN LETTER A WITH RING ABOVE
+uplow \x00c6\x00e6 3457,345 LATIN LETTER AE
+uplow \x00cc\x00ec 15678,1568 LATIN LETTER I WITH GRAVE
+uplow \x00cd\x00ed 12678,1268 LATIN LETTER I WITH ACUTE
+uplow \x00d0\x00f0 1345678,134568 LATIN LETTER ETH
+uplow \x00d1\x00f1 1245678,124568 LATIN LETTER N WITH TILDE
+uplow \x00d2\x00f2 124678,12468 LATIN LETTER O WITH GRAVE
+uplow \x00d3\x00f3 34678,3468 LATIN LETTER O WITH ACUTE
+uplow \x00d5\x00f5 145678,14568 LATIN LETTER O WITH TILDE
+uplow \x00d6\x00f6 24678,2468 LATIN LETTER O WITH DIAERESIS
+math \x00d7 13468 MULTIPLICATION SIGN
+uplow \x00d8\x00f8 2467,246 LATIN LETTER O WITH STROKE
+uplow \x00da\x00fa 125678,12568 LATIN LETTER U WITH ACUTE
+uplow \x00dd\x00fd 13478,1348 LATIN LETTER Y WITH ACUTE (infinite?)
+uplow \x00de\x00fe 1378,138 LATIN LETTER THORN
+lowercase \x00df 23468 LATIN SMALL LETTER SHARP S
+math \x00f7 2568 DIVISION SIGN
+
+# Character used for capslettersign
+# Resides in the "private use area", and shouldn't conflict with anything.
+sign \xf8ff f
+
+# Used as dash where dash should act as space.
+space \xf8fe ef
+
+#Unicode Braille patterns
+include braille-patterns.cti
+
+# characters that have letsign as part of their definition
+# (to be removed when the alwaysletsign opcode has been implemented).
+punctuation * 6-35 ASTERISK
+uplow Qq 6-123457,6-12345 LATIN LETTER Q
+uplow Ww 6-24567,6-2456 LATIN LETTER W
+uplow Xx 6-13467,6-1346 LATIN LETTER X
+uplow Zz 6-13567,6-1356 LATIN LETTER Z
+punctuation \\ 6-347 REVERSE SLASH
+punctuation \x2026 6-3-3-3 #Elipsis (0x85)
+noback punctuation \x0085 6-3-3-3 #Elipsis (0x85)
+uplow \x017d\x017e 6-3467,6-346 #LATIN LETTER Z WITH CARON (0x8e)
+noback uplow \x008e\x009e 6-3467,6-346 #LATIN LETTER Z WITH CARON (0x8e)
+letter \x2013 6-36 #EN DASH (0x96)
+noback sign \x0096 6-36 #EN DASH (0x96)
+letter \x2014 6-367 #Em DASH (0x97)
+noback sign \x0097 6-367 #Em DASH (0x97)
+punctuation \x00a4 6-2367 CURRENCY SIGN (0xa4)
+punctuation \x00a8 6-56 DIAERESIS (0xa8)
+punctuation \x00ac 6-34567 NOT SIGN (0xac)
+sign \x00b0 4-356 DEGREE SIGN (0xb0)
+sign \x00b5 6-236 MICRO SIGN
+punctuation \x00be 6-3456 VULGAR FRACTION THREE QUARTERS
+punctuation \x00bf 6-34 INVERTED QUESTION MARK
+uplow \x00c0\x00e0 6-123567,6-12356 LATIN LETTER A WITH GRAVE
+uplow \x00c7\x00e7 6-123467,6-12346 LATIN LETTER C WITH CEDILLA
+uplow \x00c8\x00e8 6-23467,6-2346 LATIN LETTER E WITH GRAVE
+uplow \x00c9\x00e9 6-1234567,6-123456 LATIN LETTER E WITH ACUTE
+uplow \x00ca\x00ea 6-1267,6-126 LATIN LETTER E WITH CIRCUMFLEX
+uplow \x00cb\x00eb 6-12467,6-1246 LATIN LETTER E WITH DIAERESIS
+uplow \x00ce\x00ee 6-1467,6-146 LATIN LETTER I WITH CIRCUMFLEX
+uplow \x00cf\x00ef 6-124567,6-12456 LATIN LETTER I WITH DIAERESIS
+uplow \x00d4\x00f4 6-14567,6-1456 LATIN LETTER O WITH CIRCUMFLEX
+uplow \x00d9\x00f9 6-234567,6-23456 LATIN LETTER U WITH GRAVE
+uplow \x00db\x00fb 6-1567,6-156 LATIN LETTER U WITH CIRCUMFLEX
+uplow \x00dc\x00fc 6-12567,6-1256 LATIN LETTER U WITH DIAERESIS
+
+# Misc unicode characters
+include da-dk-8miscChars.cti
+
+### misc opcodes ###
+
+# Emphasis opcodes
+# Emphasis opcodes
+emphclass italic
+emphclass underline
+emphclass bold
+
+begemphphrase italic 56
+endemphphrase italic after 56
+begemphword italic 56
+endemphword italic 56
+
+begemphphrase bold 56
+endemphphrase bold after 56
+begemphword bold 56
+endemphword bold 56
+
+begemphphrase underline 56
+endemphphrase underline after 56
+begemphword underline 56
+endemphword underline 56
+
+# special symbols
+decpoint , 2
+hyphen - 368
+letsign 6
+noletsign IQWXZiqwxz
+noletsignbefore 1234567890
+
+capsletter f
+multind f-6 capsletter letsign
+multind 6-f letsign capsletter
+capsnocont
+
+# The Danish use of letsign differs somewhat from the LibLouis way.
+# In order to be sure that we are getting a letsign when we want one, we are sometimes getting an overlap.
+
+# Ensure that we have letsign between a digit and "st"
+# and nd after a digit is not contracted
+noback context _$d["st"]!$l @6-234-2345
+noback context _$d["st"]~ @6-234-2345
+noback context _$d["nd"]!$l @1345-145
+noback context _$d["nd"]~ @1345-145
+# The following lines are to ensure that we get a letsign between a digit and a single letter.
+noback context $d[]$l!$l @6
+noback context $d[]$l~ @6
+
+### Correct - Forward translation
+
+# Ensure that capsnocont does not stretch across dashes
+noback correct $U["-"] "\xf8fe"
+
+# Special characters that always need letsigns because they represent contractions
+always \x00a1 6-256 # inverted exclamationmark
+
+#Special sequences, urls emails and file names.
+nocont $
+nocont \\ # line cannot end with a backslash
+nocont @
+nocont ://
+nocont www
+nocont .com
+nocont .dk
+nocont .eu
+nocont .edu
+nocont .gov
+nocont .mil
+nocont .net
+nocont .org
+nocont .uk
+nocont .doc
+nocont .exe
+nocont .htm
+nocont .tex
+nocont .txt
+nocont .gif
+nocont .jpg
+nocont .png
+nocont .wav
+nocont .tar
+nocont .zip
+
+#Words
+word af 356
+word aldrig 1-35
+word aig =
+word alle 1-15
+begnum ae 6-1-15
+contraction ae
+word allerede 1-123-1235
+begnum alr 6-1-123-1235
+contraction alr
+word alligevel 1-123-1236
+begnum alv 6-1-123-1236
+contraction alv
+word altid 1-2345-145
+begnum atd 6-1-2345-145
+contraction atd
+word altså 1-16
+begnum aå 6-1-16
+contraction aå
+word at 1
+
+word blevet 12-2345
+begnum bt 6-12-2345
+contraction bt
+word blev 12-1236
+begnum bv 6-12-1236
+contraction bv
+word blive 12-3456
+word bve 12-1236-15
+word bliver 12
+
+word derefter 23456-1356
+word derst =
+word deres 256
+word derfor 23456-124
+word derf =
+word derigennem 23456-24-12456
+word derige 1456-1235-24-12456
+word dermed 23456-134
+word derm =
+word derned 23456-1246
+word derne =
+word derop 23456-135
+word dero =
+word derover 23456-1346
+word deror =
+word derpå 23456-1234
+word derp =
+word dersom 23456-234
+word ders =
+word dertil 23456-2345
+word dert =
+word derunder 23456-12345
+word derved 23456-1236
+word din 145-1345
+begnum dn 6-145-1345
+contraction dn
+word disse 145-234
+begnum ds 6-145-234
+contraction ds
+word dit 145-2345
+begnum dt 6-145-2345
+contraction dt
+word du 145
+
+word efter 1356
+word eller 15
+word endnu 15-136
+begnum eu 6-15-136
+contraction eu
+
+word fik 124-13
+begnum fk 6-124-13
+contraction fk
+word fordi 124-145
+begnum fd 6-124-145
+contraction fd
+word forskellige 124-123456-15
+word fske =
+word forskelligt 124-123456-2345
+word fskt =
+word forskellig 124-123456
+word fsk =
+word for 124
+word fra 235
+word første 124-1356-15
+word først 124-1356
+word før 246
+
+word ganske 1245-123456
+word gennem 12456
+word ge =
+word gik 1245-13
+begnum gk 6-1245-13
+contraction gk
+word gør 1245
+
+word ham 236
+word hans 13456-234
+begnum ys 6-13456-234
+contraction ys
+word han 13456
+word har 125
+word havde 125-1456
+word hde =
+word have 125-3456
+word hve =
+word helt 125-2345
+begnum ht 6-125-2345
+contraction ht
+word hendes 125-234
+begnum hs 6-125-234
+contraction hs
+word hende 125-145
+begnum hd 6-125-145
+contraction hd
+word hun 136
+word hvad 2456
+word hv =
+word hvis 2456-234
+word hvs =
+word hvordan 34-1
+word hvora 34-6-1
+word hvorefter 34-1356
+word hvorst 34-234-2345
+word hvorfor 34-124
+word hvorf 34-6-124
+word hvorigennem 34-24-12456
+word hvorledes 34-15
+word hvore 34-6-15
+word hvormed 34-134
+word hvorm 34-6-134
+word hvornår 34-1345
+word hvorn 34-6-1345
+word hvorover 34-1346
+word hvoror 34-135-1235
+word hvorpå 34-1234
+word hvorp 34-6-1234
+word hvortil 34-2345
+word hvort 34-6-2345
+word hvorunder 34-12345
+word hvornd 34-1345-145
+word hvorved 34-1236
+word hvorv 34-6-1236
+word hvor 34
+
+word igennem 24-12456
+word ige =
+word igen 35
+word ig =
+word ikke 24-13
+begnum ik 6-24-13
+contraction ik
+word imidlertid 24-24
+begnum ii 6-24-24
+contraction ii
+
+word jeg 245
+
+word kan 13
+word kommer 13-156
+word ker =
+word kommet 13-346
+word ket =
+word komme 13-146
+word kme =
+word kom 13-134
+begnum km 6-13-134
+contraction km
+word kunne 13-1246
+word kne =
+
+word ligesom 123-234
+begnum ls 6-123-234
+contraction ls
+word lige 123
+word lille 123-123
+begnum ll 6-123-123
+contraction ll
+
+word mange 134-12456
+word mge =
+word med 134
+word megen 146-126
+word meen =
+word meget 146-346
+word meet =
+word mellem 146-134
+word mem =
+word men 146
+word me =
+word min 134-1345
+begnum mn 6-134-1345
+contraction mn
+word mit 134-2345
+begnum mt 6-145-2345
+contraction mt
+word måske 134-123456
+word msk =
+word måtte 134-1256
+word mte =
+
+word naturligvis 1345-2345-1236
+begnum ntv 6-1345-2345-1236
+contraction ntv
+word nd =
+word ned 1246
+word ne =
+word nogen 1345-1345
+begnum nn 6-1345-1345
+contraction nn
+word noget 1345-2345
+begnum nt 6-1345-2345
+contraction nt
+word nogle 1345-123-15
+begnum nle 6-1345-123-15
+contraction nle
+word når 1345
+
+word også 14-16
+begnum cå 6-14-16
+contraction cå
+word og 14
+word omkring 135-134-13
+begnum omk 6-135-134-13
+contraction omk
+word op 135
+word or =
+word over 1346
+
+word på 1234
+
+word ret 12356
+word re 1235-15
+word rigtige 1235-12456
+word rge =
+word rigtigt 1235-2345
+begnum rt 6-1235-2345
+contraction rt
+word rigtig 1235
+
+word sagde 234-1456
+word sammen 234-134
+begnum sm 6-234-134
+contraction sm
+word samme 234-146
+word sme =
+word selvfølgelig 234-1236-124
+begnum svf 6-234-1236-124
+contraction svf
+word selv 234-1236
+begnum sv 6-234-1236
+contraction sv
+word sidste 234-1356-15
+word sste =
+word sidst 234-1356
+word sst =
+word sin 234-1345
+begnum sn 6-234-1345
+contraction sn
+word sit 234-2345
+begnum st 6-234-2345
+contraction st
+word skal 123456
+word sk =
+word skulle 123456-123-15
+word skle =
+word snart 234-1235
+begnum sr 6-234-1235
+contraction sr
+word som 234
+word sådan 16-1
+begnum åa 6-16-1
+contraction åa
+word således 16-15
+begnum åe 6-16-15
+contraction åe
+word så 16
+
+word te 1256
+word tid 2345-145
+begnum td 6-2345-145
+contraction td
+word tilbage 2345-12
+begnum tb 6-2345-12
+contraction tb
+word til 2345
+
+word under 12345
+
+word var- =
+word var. =
+word var 36
+word ve 3456
+word ved 1236
+word ville 1236-123-15
+begnum vle 6-1236-123-15
+contraction vle
+word vil 1236-123
+begnum vl 6-1236-123
+contraction vl
+word været 1236-2345
+begnum vt 6-1236-2345
+contraction vt
+word være 345
+
+#Part words
+nocross den 12346
+nocross der 23456
+nocross det 2346
+nocross de 1456
+nocross en 126
+nocross er 156
+nocross et 346
+nocross ge 12456
+nocross hvor 34
+nocross hv 2456
+nocross ig 35
+nocross me 146
+nocross nd 12345
+nocross ne 1246
+nocross or 1346
+nocross re 12356
+nocross sk 123456
+nocross st 1356
+nocross te 1256
+nocross ve 3456
+
+#special cases with dropped signs
+# which can be both punctuations and contractions.
+
+always fra! 124-1235-1-235
+always !fra 235-124-1235-1
+always !! 235-235
+always !!! 235-235-235
+always "fra" 2356-124-1235-1-2356
+after punctuation always ! 6-235
+always 'af 4-1-124
+
+always \s! 0-6-235
+prepunc ! 6-235
+nofor always ! 6-235
+noback context `["!"] @6-235
+
+
+# Ensure no one-letter word contraction before or after a dash
+
+prfword -af 368-1-124
+sufword af- 1-124-368
+prfword -at 368-1-2345
+sufword at- 1-2345-368
+prfword -deres 368-1456-12356-234
+sufword deres- 1456-12356-234-368
+prfword -du 368-145-136
+sufword du- 145-136-368
+prfword -efter 368-15-124-2345-156
+sufword efter- 15-124-2345-156-368
+prfword -for 368-124-1346
+sufword for- 124-1346-368
+prfword -fra 368-124-1235-1
+sufword fra- 124-1235-1-368
+prfword -gennem 368-1245-126-1246-134
+sufword gennem- 1245-126-1246-134-368
+prfword -ham 368-125-1-134
+sufword ham- 125-1-134-368
+prfword -han 368-125-1-1345
+sufword han- 125-1-1345-368
+prfword -har 368-125-1-1235
+sufword har- 125-1-1235-368
+prfword -hun 368-125-136-1345
+sufword hun- 125-136-1345-368
+prfword -kan 368-13-1-1345
+sufword kan- 13-1-1345-368
+prfword -lige 368-123-24-12456
+sufword lige- 123-24-12456-368
+prfword -med 368-146-145
+sufword med- 146-145-368
+prfword -men 368-134-126
+sufword men- 134-126-368
+prfword -ned 368-1246-145
+sufword ned- 1246-145-368
+prfword -når 368-1345-16-1235
+sufword når- 1345-16-1235-368
+prfword -og 368-135-1245
+sufword og- 135-1245-368
+prfword -op 368-135-1234
+sufword op- 135-1234-368
+prfword -over 368-135-1236-156
+sufword over- 135-1236-156-368
+prfword -på 368-1234-16
+sufword på- 1234-16-368
+prfword -ret 368-1235-346
+sufword ret- 1235-346-368
+prfword -rigtig 368-1235-35-2345-35
+sufword rigtig- 1235-35-2345-35-368
+prfword -skal 368-123456-1-123
+sufword skal- 123456-1-123-368
+prfword -som 368-234-135-134
+sufword som- 234-135-134-368
+prfword -så 368-234-16
+sufword så- 234-16-368
+prfword -til 368-2345-24-123
+sufword til- 2345-24-123-368
+prfword -under 368-136-1345-23456
+sufword under- 136-1345-23456-368
+prfword -ved 368-1236-15-145
+sufword ved- 1236-15-145-368
+prfword -være 368-1236-345-12356
+sufword være- 1236-345-12356-368
+
+# *** patches for various Liblouis bugs
+# this file will be removed when the bugs are fixed
+
+nofor always a 6-1
+nofor always b 6-12
+nofor always c 6-14
+nofor always d 6-145
+nofor always e 6-15
+nofor always f 6-124
+nofor always g 6-1245
+nofor always h 6-125
+nofor always j 6-245
+nofor always k 6-13
+nofor always l 6-123
+nofor always m 6-134
+nofor always n 6-1345
+nofor always o 6-135
+nofor always p 6-1234
+nofor always q 6-12345
+nofor always r 6-1235
+nofor always s 6-234
+nofor always t 6-2345
+nofor always u 6-136
+nofor always v 6-1236
+nofor always w 6-2456
+nofor always x 6-1346
+nofor always y 6-13456
+nofor always z 6-1356
+nofor always æ 6-345
+nofor always ø 6-246
+nofor always å 6-16
+
+nofor always A 6-17
+nofor always B 6-127
+nofor always C 6-147
+nofor always D 6-1457
+nofor always E 6-157
+nofor always F 6-1247
+nofor always G 6-12457
+nofor always H 6-1257
+nofor always J 6-2457
+nofor always K 6-137
+nofor always L 6-1237
+nofor always M 6-1347
+nofor always N 6-13457
+nofor always O 6-1357
+nofor always P 6-12347
+nofor always Q 6-123457
+nofor always R 6-12357
+nofor always S 6-2347
+nofor always T 6-23457
+nofor always U 6-1367
+nofor always V 6-12367
+nofor always W 6-24567
+nofor always X 6-13467
+nofor always Y 6-134567
+nofor always Z 6-13567
+nofor always Æ 6-3457
+nofor always Ø 6-2467
+nofor always Å 6-167
+
+# if a word contraction is followed by a punctuation and another word immediately after,
+# The contracted word before the punctuation will back-translate as its components
+class wordlimit /,!.:’()?"'\x00ab_\x201d\x0094\x2019\x0092\x00bb
+nofor before wordlimit begword af 356
+nofor before wordlimit begword aldrig 1-35
+nofor before wordlimit begword aig =
+nofor before wordlimit begword alle 1-15
+nofor before wordlimit begword allerede 1-123-1235
+nofor before wordlimit begword alligevel 1-123-1236
+nofor before wordlimit begword altid 1-2345-145
+nofor before wordlimit begword altså 1-16
+nofor before wordlimit begword at 1
+
+nofor before wordlimit begword blevet 12-2345
+nofor before wordlimit begword blev 12-1236
+nofor before wordlimit begword blive 12-3456
+nofor before wordlimit begword bve 12-1236-15
+nofor before wordlimit begword bliver 12
+
+nofor before wordlimit begword derefter 23456-1356
+nofor before wordlimit begword derst =
+nofor before wordlimit begword deres 256
+nofor before wordlimit begword derfor 23456-124
+nofor before wordlimit begword derf =
+nofor before wordlimit begword derigennem 23456-24-12456
+nofor before wordlimit begword derige 1456-1235-24-12456
+nofor before wordlimit begword dermed 23456-134
+nofor before wordlimit begword derm =
+nofor before wordlimit begword derned 23456-1246
+nofor before wordlimit begword derne =
+nofor before wordlimit begword derop 23456-135
+nofor before wordlimit begword dero =
+nofor before wordlimit begword derover 23456-1346
+nofor before wordlimit begword deror =
+nofor before wordlimit begword derpå 23456-1234
+nofor before wordlimit begword derp =
+nofor before wordlimit begword dersom 23456-234
+nofor before wordlimit begword ders =
+nofor before wordlimit begword dertil 23456-2345
+nofor before wordlimit begword dert =
+nofor before wordlimit begword derunder 23456-12345
+nofor before wordlimit begword derved 23456-1236
+nofor before wordlimit begword din 145-1345
+nofor before wordlimit begword disse 145-234
+nofor before wordlimit begword dit 145-2345
+nofor before wordlimit begword du 145
+
+nofor before wordlimit begword efter 1356
+nofor before wordlimit begword eller 15
+nofor before wordlimit begword endnu 15-136
+
+nofor before wordlimit begword fik 124-13
+nofor before wordlimit begword fordi 124-145
+nofor before wordlimit begword forskellige 124-123456-15
+nofor before wordlimit begword fske =
+nofor before wordlimit begword forskelligt 124-123456-2345
+nofor before wordlimit begword fskt =
+nofor before wordlimit begword forskellig 124-123456
+nofor before wordlimit begword fsk =
+nofor before wordlimit begword for 124
+nofor before wordlimit begword fra 235
+nofor before wordlimit begword første 124-1356-15
+nofor before wordlimit begword først 124-1356
+nofor before wordlimit begword før 246
+
+nofor before wordlimit begword ganske 1245-123456
+nofor before wordlimit begword gennem 12456
+nofor before wordlimit begword ge =
+nofor before wordlimit begword gik 1245-13
+nofor before wordlimit begword gør 1245
+
+nofor before wordlimit begword ham 236
+nofor before wordlimit begword hans 13456-234
+nofor before wordlimit begword han 13456
+nofor before wordlimit begword har 125
+nofor before wordlimit begword havde 125-1456
+nofor before wordlimit begword hde =
+nofor before wordlimit begword have 125-3456
+nofor before wordlimit begword hve =
+nofor before wordlimit begword helt 125-2345
+nofor before wordlimit begword hendes 125-234
+nofor before wordlimit begword hende 125-145
+nofor before wordlimit begword hun 136
+nofor before wordlimit begword hvad 2456
+nofor before wordlimit begword hv =
+nofor before wordlimit begword hvis 2456-234
+nofor before wordlimit begword hvs =
+nofor before wordlimit begword hvordan 34-1
+nofor before wordlimit begword hvorefter 34-1356
+nofor before wordlimit begword hvorfor 34-124
+nofor before wordlimit begword hvorigennem 34-24-12456
+nofor before wordlimit begword hvorledes 34-15
+nofor before wordlimit begword hvormed 34-134
+nofor before wordlimit begword hvornår 34-1345
+nofor before wordlimit begword hvorover 34-1346
+nofor before wordlimit begword hvorpå 34-1234
+nofor before wordlimit begword hvortil 34-2345
+nofor before wordlimit begword hvorunder 34-12345
+nofor before wordlimit begword hvorved 34-1236
+nofor before wordlimit begword hvor 34
+
+nofor before wordlimit begword igennem 24-12456
+nofor before wordlimit begword ige =
+nofor before wordlimit begword igen 35
+nofor before wordlimit begword ig =
+nofor before wordlimit begword ikke 24-13
+nofor before wordlimit begword imidlertid 24-24
+
+nofor before wordlimit begword jeg 245
+
+nofor before wordlimit begword kan 13
+nofor before wordlimit begword kommer 13-156
+nofor before wordlimit begword ker =
+nofor before wordlimit begword kommet 13-346
+nofor before wordlimit begword ket =
+nofor before wordlimit begword komme 13-146
+nofor before wordlimit begword kme =
+nofor before wordlimit begword kom 13-134
+nofor before wordlimit begword kunne 13-1246
+nofor before wordlimit begword kne =
+
+nofor before wordlimit begword ligesom 123-234
+nofor before wordlimit begword lige 123
+nofor before wordlimit begword lille 123-123
+
+nofor before wordlimit begword mange 134-12456
+nofor before wordlimit begword mge =
+nofor before wordlimit begword med 134
+nofor before wordlimit begword megen 146-126
+nofor before wordlimit begword meen =
+nofor before wordlimit begword meget 146-346
+nofor before wordlimit begword meet =
+nofor before wordlimit begword mellem 146-134
+nofor before wordlimit begword mem =
+nofor before wordlimit begword men 146
+nofor before wordlimit begword me =
+nofor before wordlimit begword min 134-1345
+nofor before wordlimit begword mit 134-2345
+nofor before wordlimit begword måske 134-123456
+nofor before wordlimit begword msk =
+nofor before wordlimit begword måtte 134-1256
+nofor before wordlimit begword mte =
+
+nofor before wordlimit begword naturligvis 1345-2345-1236
+nofor before wordlimit begword nd =
+nofor before wordlimit begword ned 1246
+nofor before wordlimit begword ne =
+nofor before wordlimit begword nogen 1345-1345
+nofor before wordlimit begword noget 1345-2345
+nofor before wordlimit begword nogle 1345-123-15
+nofor before wordlimit begword når 1345
+
+nofor before wordlimit begword også 14-16
+nofor before wordlimit begword og 14
+nofor before wordlimit begword omkring 135-134-13
+nofor before wordlimit begword op 135
+nofor before wordlimit begword or =
+nofor before wordlimit begword over 1346
+
+nofor before wordlimit begword på 1234
+
+nofor before wordlimit begword ret 12356
+nofor before wordlimit begword re 1235-15
+nofor before wordlimit begword rigtige 1235-12456
+nofor before wordlimit begword rge =
+nofor before wordlimit begword rigtigt 1235-2345
+nofor before wordlimit begword rigtig 1235
+
+nofor before wordlimit begword sagde 234-1456
+nofor before wordlimit begword sammen 234-134
+nofor before wordlimit begword samme 234-146
+nofor before wordlimit begword sme =
+nofor before wordlimit begword selvfølgelig 234-1236-124
+nofor before wordlimit begword selv 234-1236
+nofor before wordlimit begword sidste 234-1356-15
+nofor before wordlimit begword sste =
+nofor before wordlimit begword sidst 234-1356
+nofor before wordlimit begword sst =
+nofor before wordlimit begword sin 234-1345
+nofor before wordlimit begword sit 234-2345
+nofor before wordlimit begword skal 123456
+nofor before wordlimit begword sk =
+nofor before wordlimit begword skulle 123456-123-15
+nofor before wordlimit begword skle =
+nofor before wordlimit begword snart 234-1235
+nofor before wordlimit begword som 234
+nofor before wordlimit begword sådan 16-1
+nofor before wordlimit begword således 16-15
+nofor before wordlimit begword så 16
+
+nofor before wordlimit begword tid 2345-145
+nofor before wordlimit begword tilbage 2345-12
+nofor before wordlimit begword til 2345
+
+nofor before wordlimit begword under 12345
+
+nofor before wordlimit begword var- =
+nofor before wordlimit begword var 36
+nofor before wordlimit begword ved 1236
+nofor before wordlimit begword ville 1236-123-15
+nofor before wordlimit begword vil 1236-123
+nofor before wordlimit begword været 1236-2345
+nofor before wordlimit begword være 345
+
+# Problems solved with pass 2
+
+# Convert the fake "space hyphen" back to a normal hyphen.
+noback pass2 @ef @368
+
+### Multi-pass opcodes for converting the virtual capsletter sign @f into dot 7.
+
+# Most of these lines are temporary.
+# They will be written with a few swap sets when the swapdd opcode has been fixed.
+
+
+# Generic forward convert of @f-... to @...7
+noback pass2 @f-235 @2357
+# Conversion with letsign.
+noback pass2 @f-6-235 @6-2357
+# Conversion with dot 5, which is used for accent marker in higher unicode pages.
+noback pass2 @f-5-235 @5-2357
+# Generic backward conversion.
+nofor pass2 @2357 @f-235
+# Conversion with dot 5 (letsign is handled below).
+nofor pass2 @5-2357 @f-5-235
+
+# Same for the following characters.
+
+noback pass2 @f-35 @357
+noback pass2 @f-6-35 @6-357
+noback pass2 @f-5-35 @5-357
+nofor pass2 @357 @f-35
+nofor pass2 @5-357 @f-5-35
+
+noback pass2 @f-36 @367
+noback pass2 @f-6-36 @6-367
+noback pass2 @f-5-36 @5-367
+nofor pass2 @367 @f-36
+nofor pass2 @5-367 @f-5-36
+
+noback pass2 @f-1 @17
+noback pass2 @f-6-1 @6-17
+noback pass2 @f-5-1 @5-17
+nofor pass2 @17 @f-1
+nofor pass2 @5-17 @f-5-1
+
+noback pass2 @f-12 @127
+noback pass2 @f-6-12 @6-127
+noback pass2 @f-5-12 @5-127
+nofor pass2 @127 @f-12
+nofor pass2 @5-127 @f-5-12
+
+noback pass2 @f-14 @147
+noback pass2 @f-6-14 @6-147
+noback pass2 @f-5-14 @5-147
+nofor pass2 @147 @f-14
+nofor pass2 @5-147 @f-5-14
+
+noback pass2 @f-145 @1457
+noback pass2 @f-6-145 @6-1457
+noback pass2 @f-5-145 @5-1457
+nofor pass2 @1457 @f-145
+nofor pass2 @5-1457 @f-5-145
+
+noback pass2 @f-15 @157
+noback pass2 @f-6-15 @6-157
+noback pass2 @f-5-15 @5-157
+nofor pass2 @157 @f-15
+nofor pass2 @5-157 @f-5-15
+
+noback pass2 @f-124 @1247
+noback pass2 @f-6-124 @6-1247
+noback pass2 @f-5-124 @5-1247
+nofor pass2 @1247 @f-124
+nofor pass2 @5-1247 @f-5-124
+
+noback pass2 @f-1245 @12457
+noback pass2 @f-6-1245 @6-12457
+noback pass2 @f-5-1245 @5-12457
+nofor pass2 @12457 @f-1245
+nofor pass2 @5-12457 @f-5-1245
+
+noback pass2 @f-125 @1257
+noback pass2 @f-6-125 @6-1257
+noback pass2 @f-5-125 @5-1257
+nofor pass2 @1257 @f-125
+nofor pass2 @5-1257 @f-5-125
+
+noback pass2 @f-24 @247
+noback pass2 @f-6-24 @6-247
+noback pass2 @f-5-24 @5-247
+nofor pass2 @247 @f-24
+nofor pass2 @5-247 @f-5-24
+
+noback pass2 @f-245 @2457
+noback pass2 @f-6-245 @6-2457
+noback pass2 @f-5-245 @5-2457
+nofor pass2 @2457 @f-245
+nofor pass2 @5-2457 @f-5-245
+
+noback pass2 @f-13 @137
+noback pass2 @f-6-13 @6-137
+noback pass2 @f-5-13 @5-137
+nofor pass2 @137 @f-13
+nofor pass2 @5-137 @f-5-13
+
+noback pass2 @f-123 @1237
+noback pass2 @f-6-123 @6-1237
+noback pass2 @f-5-123 @5-1237
+nofor pass2 @1237 @f-123
+nofor pass2 @5-1237 @f-5-123
+
+noback pass2 @f-134 @1347
+noback pass2 @f-6-134 @6-1347
+noback pass2 @f-5-134 @5-1347
+nofor pass2 @1347 @f-134
+nofor pass2 @5-1347 @f-5-134
+
+noback pass2 @f-1345 @13457
+noback pass2 @f-6-1345 @6-13457
+noback pass2 @f-5-1345 @5-13457
+nofor pass2 @13457 @f-1345
+nofor pass2 @5-13457 @f-5-1345
+
+noback pass2 @f-135 @1357
+noback pass2 @f-6-135 @6-1357
+noback pass2 @f-5-135 @5-1357
+nofor pass2 @1357 @f-135
+nofor pass2 @5-1357 @f-5-135
+
+noback pass2 @f-1234 @12347
+noback pass2 @f-6-1234 @6-12347
+noback pass2 @f-5-1234 @5-12347
+nofor pass2 @12347 @f-1234
+nofor pass2 @5-12347 @f-5-1234
+
+noback pass2 @f-12345 @123457
+noback pass2 @f-6-12345 @6-123457
+noback pass2 @f-5-12345 @5-123457
+nofor pass2 @123457 @f-12345
+nofor pass2 @5-123457 @f-5-12345
+
+noback pass2 @f-1235 @12357
+noback pass2 @f-6-1235 @6-12357
+noback pass2 @f-5-1235 @5-12357
+nofor pass2 @12357 @f-1235
+nofor pass2 @5-12357 @f-5-1235
+
+noback pass2 @f-234 @2347
+noback pass2 @f-6-234 @6-2347
+noback pass2 @f-5-234 @5-2347
+nofor pass2 @2347 @f-234
+nofor pass2 @5-2347 @f-5-234
+
+noback pass2 @f-2345 @23457
+noback pass2 @f-6-2345 @6-23457
+noback pass2 @f-5-2345 @5-23457
+nofor pass2 @23457 @f-2345
+nofor pass2 @5-23457 @f-5-2345
+
+noback pass2 @f-136 @1367
+noback pass2 @f-6-136 @6-1367
+noback pass2 @f-5-136 @5-1367
+nofor pass2 @1367 @f-136
+nofor pass2 @5-1367 @f-5-136
+
+noback pass2 @f-1236 @12367
+noback pass2 @f-6-1236 @6-12367
+noback pass2 @f-5-1236 @5-12367
+nofor pass2 @12367 @f-1236
+nofor pass2 @5-12367 @f-5-1236
+
+noback pass2 @f-2456 @24567
+noback pass2 @f-6-2456 @6-24567
+noback pass2 @f-5-2456 @5-24567
+nofor pass2 @24567 @f-2456
+nofor pass2 @5-24567 @f-5-2456
+
+noback pass2 @f-1346 @13467
+noback pass2 @f-6-1346 @6-13467
+noback pass2 @f-5-1346 @5-13467
+nofor pass2 @13467 @f-1346
+nofor pass2 @5-13467 @f-5-1346
+
+noback pass2 @f-13456 @134567
+noback pass2 @f-6-13456 @6-134567
+noback pass2 @f-5-13456 @5-134567
+nofor pass2 @134567 @f-13456
+nofor pass2 @5-134567 @f-5-13456
+
+noback pass2 @f-1356 @13567
+noback pass2 @f-6-1356 @6-13567
+noback pass2 @f-5-1356 @5-13567
+nofor pass2 @13567 @f-1356
+nofor pass2 @5-13567 @f-5-1356
+
+noback pass2 @f-34 @347
+noback pass2 @f-6-34 @6-347
+noback pass2 @f-5-34 @5-347
+nofor pass2 @347 @f-34
+nofor pass2 @5-347 @f-5-34
+
+noback pass2 @f-346 @3467
+noback pass2 @f-6-346 @6-3467
+noback pass2 @f-5-346 @5-3467
+nofor pass2 @3467 @f-346
+nofor pass2 @5-3467 @f-5-346
+
+noback pass2 @f-2348 @23478
+noback pass2 @f-6-2348 @6-23478
+noback pass2 @f-5-2348 @5-23478
+nofor pass2 @23478 @f-2348
+nofor pass2 @5-23478 @f-5-2348
+
+noback pass2 @f-1358 @13578
+noback pass2 @f-6-1358 @6-13578
+noback pass2 @f-5-1358 @5-13578
+nofor pass2 @13578 @f-1358
+nofor pass2 @5-13578 @f-5-1358
+
+noback pass2 @f-234568 @2345678
+noback pass2 @f-6-234568 @6-2345678
+noback pass2 @f-5-234568 @5-2345678
+nofor pass2 @2345678 @f-234568
+nofor pass2 @5-2345678 @f-5-234568
+
+noback pass2 @f-236 @2367
+noback pass2 @f-6-236 @6-2367
+noback pass2 @f-5-236 @5-2367
+nofor pass2 @2367 @f-236
+nofor pass2 @5-2367 @f-5-236
+
+noback pass2 @f-256 @2567
+noback pass2 @f-6-256 @6-2567
+noback pass2 @f-5-256 @5-2567
+nofor pass2 @2567 @f-256
+nofor pass2 @5-2567 @f-5-256
+
+noback pass2 @f-356 @3567
+noback pass2 @f-6-356 @6-3567
+noback pass2 @f-5-356 @5-3567
+nofor pass2 @3567 @f-356
+nofor pass2 @5-3567 @f-5-356
+
+noback pass2 @f-3456 @34567
+noback pass2 @f-6-3456 @6-34567
+noback pass2 @f-5-3456 @5-34567
+nofor pass2 @34567 @f-3456
+nofor pass2 @5-34567 @f-5-3456
+
+noback pass2 @f-12356 @123567
+noback pass2 @f-6-12356 @6-123567
+noback pass2 @f-5-12356 @5-123567
+nofor pass2 @123567 @f-12356
+nofor pass2 @5-123567 @f-5-12356
+
+noback pass2 @f-123568 @1235678
+noback pass2 @f-6-123568 @6-1235678
+noback pass2 @f-5-123568 @5-1235678
+nofor pass2 @1235678 @f-123568
+nofor pass2 @5-1235678 @f-5-123568
+
+noback pass2 @f-168 @1678
+noback pass2 @f-6-168 @6-1678
+noback pass2 @f-5-168 @5-1678
+nofor pass2 @1678 @f-168
+nofor pass2 @5-1678 @f-5-168
+
+noback pass2 @f-1468 @14678
+noback pass2 @f-6-1468 @6-14678
+noback pass2 @f-5-1468 @5-14678
+nofor pass2 @14678 @f-1468
+nofor pass2 @5-14678 @f-5-1468
+
+noback pass2 @f-3458 @34578
+noback pass2 @f-6-3458 @6-34578
+noback pass2 @f-5-3458 @5-34578
+nofor pass2 @34578 @f-3458
+nofor pass2 @5-34578 @f-5-3458
+
+noback pass2 @f-16 @167
+noback pass2 @f-6-16 @6-167
+noback pass2 @f-5-16 @5-167
+nofor pass2 @167 @f-16
+nofor pass2 @5-167 @f-5-16
+
+noback pass2 @f-345 @3457
+noback pass2 @f-6-345 @6-3457
+noback pass2 @f-5-345 @5-3457
+nofor pass2 @3457 @f-345
+nofor pass2 @5-3457 @f-5-345
+
+noback pass2 @f-12346 @123467
+noback pass2 @f-6-12346 @6-123467
+noback pass2 @f-5-12346 @5-123467
+nofor pass2 @123467 @f-12346
+nofor pass2 @5-123467 @f-5-12346
+
+noback pass2 @f-2346 @23467
+noback pass2 @f-6-2346 @6-23467
+noback pass2 @f-5-2346 @5-23467
+nofor pass2 @23467 @f-2346
+nofor pass2 @5-23467 @f-5-2346
+
+noback pass2 @f-123456 @1234567
+noback pass2 @f-6-123456 @6-1234567
+noback pass2 @f-5-123456 @5-1234567
+nofor pass2 @1234567 @f-123456
+nofor pass2 @5-1234567 @f-5-123456
+
+noback pass2 @f-126 @1267
+noback pass2 @f-6-126 @6-1267
+noback pass2 @f-5-126 @5-1267
+nofor pass2 @1267 @f-126
+nofor pass2 @5-1267 @f-5-126
+
+noback pass2 @f-1246 @12467
+noback pass2 @f-6-1246 @6-12467
+noback pass2 @f-5-1246 @5-12467
+nofor pass2 @12467 @f-1246
+nofor pass2 @5-12467 @f-5-1246
+
+noback pass2 @f-1568 @15678
+noback pass2 @f-6-1568 @6-15678
+noback pass2 @f-5-1568 @5-15678
+nofor pass2 @15678 @f-1568
+nofor pass2 @5-15678 @f-5-1568
+
+noback pass2 @f-1268 @12678
+noback pass2 @f-6-1268 @6-12678
+noback pass2 @f-5-1268 @5-12678
+nofor pass2 @12678 @f-1268
+nofor pass2 @5-12678 @f-5-1268
+
+noback pass2 @f-146 @1467
+noback pass2 @f-6-146 @6-1467
+noback pass2 @f-5-146 @5-1467
+nofor pass2 @1467 @f-146
+nofor pass2 @5-1467 @f-5-146
+
+noback pass2 @f-12456 @124567
+noback pass2 @f-6-12456 @6-124567
+noback pass2 @f-5-12456 @5-124567
+nofor pass2 @124567 @f-12456
+nofor pass2 @5-124567 @f-5-12456
+
+noback pass2 @f-134568 @1345678
+noback pass2 @f-6-134568 @6-1345678
+noback pass2 @f-5-134568 @5-1345678
+nofor pass2 @1345678 @f-134568
+nofor pass2 @5-1345678 @f-5-134568
+
+noback pass2 @f-124568 @1245678
+noback pass2 @f-6-124568 @6-1245678
+noback pass2 @f-5-124568 @5-1245678
+nofor pass2 @1245678 @f-124568
+nofor pass2 @5-1245678 @f-5-124568
+
+noback pass2 @f-12468 @124678
+noback pass2 @f-6-12468 @6-124678
+noback pass2 @f-5-12468 @5-124678
+nofor pass2 @124678 @f-12468
+nofor pass2 @5-124678 @f-5-12468
+
+noback pass2 @f-3468 @34678
+noback pass2 @f-6-3468 @6-34678
+noback pass2 @f-5-3468 @5-34678
+nofor pass2 @34678 @f-3468
+nofor pass2 @5-34678 @f-5-3468
+
+noback pass2 @f-1456 @14567
+noback pass2 @f-6-1456 @6-14567
+noback pass2 @f-5-1456 @5-14567
+nofor pass2 @14567 @f-1456
+nofor pass2 @5-14567 @f-5-1456
+
+noback pass2 @f-14568 @145678
+noback pass2 @f-6-14568 @6-145678
+noback pass2 @f-5-14568 @5-145678
+nofor pass2 @145678 @f-14568
+nofor pass2 @5-145678 @f-5-14568
+
+noback pass2 @f-2468 @24678
+noback pass2 @f-6-2468 @6-24678
+noback pass2 @f-5-2468 @5-24678
+nofor pass2 @24678 @f-2468
+nofor pass2 @5-24678 @f-5-2468
+
+noback pass2 @f-246 @2467
+noback pass2 @f-6-246 @6-2467
+noback pass2 @f-5-246 @5-2467
+nofor pass2 @2467 @f-246
+nofor pass2 @5-2467 @f-5-246
+
+noback pass2 @f-23456 @234567
+noback pass2 @f-6-23456 @6-234567
+noback pass2 @f-5-23456 @5-234567
+nofor pass2 @234567 @f-23456
+nofor pass2 @5-234567 @f-5-23456
+
+noback pass2 @f-12568 @125678
+noback pass2 @f-6-12568 @6-125678
+noback pass2 @f-5-12568 @5-125678
+nofor pass2 @125678 @f-12568
+nofor pass2 @5-125678 @f-5-12568
+
+noback pass2 @f-156 @1567
+noback pass2 @f-6-156 @6-1567
+noback pass2 @f-5-156 @5-1567
+nofor pass2 @1567 @f-156
+nofor pass2 @5-1567 @f-5-156
+
+noback pass2 @f-1256 @12567
+noback pass2 @f-6-1256 @6-12567
+noback pass2 @f-5-1256 @5-12567
+nofor pass2 @12567 @f-1256
+nofor pass2 @5-12567 @f-5-1256
+
+noback pass2 @f-1348 @13478
+noback pass2 @f-6-1348 @6-13478
+noback pass2 @f-5-1348 @5-13478
+nofor pass2 @13478 @f-1348
+nofor pass2 @5-13478 @f-5-1348
+
+noback pass2 @f-138 @1378
+noback pass2 @f-6-138 @6-1378
+noback pass2 @f-5-138 @5-1378
+nofor pass2 @1378 @f-138
+nofor pass2 @5-1378 @f-5-138
+
+noback pass2 @f-234568 @2345678
+noback pass2 @f-6-234568 @6-2345678
+noback pass2 @f-5-234568 @5-2345678
+nofor pass2 @2345678 @f-234568
+nofor pass2 @5-2345678 @f-5-234568
+
+# Tweak to keep letsign for letters that should always have letsign.
+# Letsign will be removed by the multind opcode. So we insert an extra one.
+nofor pass2 @6-123457 @f-6-6-12345
+nofor pass2 @6-24567 @f-6-6-2456
+nofor pass2 @6-13467 @f-6-6-1346
+nofor pass2 @6-134567 @f-6-6-13456
+nofor pass2 @6-13567 @f-6-6-1356
+nofor pass2 @6-123567 @f-6-6-12356
+nofor pass2 @6-123467 @f-6-6-12346
+nofor pass2 @6-23467 @f-6-6-2346
+nofor pass2 @6-1234567 @f-6-6-123456
+nofor pass2 @6-1267 @f-6-6-126
+nofor pass2 @6-12467 @f-6-6-1246
+nofor pass2 @6-1467 @f-6-6-146
+nofor pass2 @6-124567 @f-6-6-12456
+nofor pass2 @6-14567 @f-6-6-1456
+nofor pass2 @6-234567 @f-6-6-23456
+nofor pass2 @6-1567 @f-6-6-156
+nofor pass2 @6-12567 @f-6-6-1256
+
+# Ensure that punctuation signs etc. are not "tolowered" when they have a letsign, but only when they act as a partword contraction.
+nofor pass2 @6-347 *
+nofor pass2 @6-2357 *
+nofor pass2 @6-3467 *
+nofor pass2 @6-2567 *
+nofor pass2 @6-2367 *
+nofor pass2 @6-34567 *
+nofor pass2 @6-367 *
+
+# remove any superfluous capsletter marks.
+noback pass2 @f ?
+
+# Remove any superfluous letsigns and only keep one.
+noback pass3 @6-6 @6
+
+# Include hyphenation file as the last thing
+include hyph_brl_da_dk.dic
diff --git a/tables/da-dk-g28l.ctb b/tables/da-dk-g28l.ctb
new file mode 100644
index 0000000..6df7774
--- /dev/null
+++ b/tables/da-dk-g28l.ctb
@@ -0,0 +1,1035 @@
+# liblouis: Danish, table for 8 dots grade 1.5, partial contraction (forward and backward translation)
+#
+# Copyright (C) 2014-2017, Bue Vester-Andersen <bue@vester-andersen.dk>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#------------
+#
+#
+# This is the Danish table for 8 dots grade 2l/1.5 limited contractions (lille forkortelse).
+# Use this table for translation and back-translation of Danish 8 dots grade 2 limited.
+#
+# Version: Bue Vester-Andersen, 160713
+
+### Table Metadata
+
+#-index-name: Danish, partially contracted, 8-dot
+#-display-name: Danish 8-dot partially contracted braille
+
+#+locale: da
+#+type: literary
+#+contraction: partial
+#+grade: 1.5
+#+dots: 8
+#+direction: both
+
+
+# Display opcodes
+include da-dk-octobraille.dis
+
+### Character definitions ###
+
+sign \x0000 8 NULL
+sign \x0001 178 START OF HEADING
+sign \x0002 1278 START OF TEXT
+sign \x0003 1478 END OF TEXT
+sign \x0004 14578 END OF TRANSMISSION
+sign \x0005 24568 ENQUIRY
+sign \x0006 12478 ACKNOWLEDGE
+sign \x0007 124578 BELL
+sign \x0008 12578 BACKSPACE
+space \t 2478 CHARACTER TABULATION
+space \n 678 LINE FEED (LF)
+space \v 1368 LINE TABULATION
+space \f 12378 FORM FEED (FF)
+space \r 257 CARRIAGE RETURN (CR)
+sign \x000e 134578 SHIFT OUT
+sign \x000f 12358 SHIFT IN
+sign \x0010 123478 DATA LINK ESCAPE
+sign \x0011 1234578 DEVICE CONTROL ONE
+sign \x0012 13568 DEVICE CONTROL TWO
+sign \x0013 4578 DEVICE CONTROL THREE
+sign \x0014 268 DEVICE CONTROL FOUR
+sign \x0015 13678 NEGATIVE ACKNOWLEDGE
+sign \x0016 278 SYNCHRONOUS IDLE
+sign \x0017 3578 END OF TRANSMISSION BLOCK
+sign \x0018 78 CANCEL
+sign \x0019 68 END OF MEDIUM
+sign \x001a 135678 SUBSTITUTE
+sign \x001b 2678 ESCAPE
+sign \x001c 45678 INFORMATION SEPARATOR FOUR
+sign \x001d 12368 INFORMATION SEPARATOR THREE
+sign \x001e 1234678 INFORMATION SEPARATOR TWO
+sign \x001f 235678 INFORMATION SEPARATOR ONE
+space \s 0 SPACE
+punctuation ! 235 EXCLAMATION MARK
+punctuation " 2356 QUOTATION MARK
+punctuation # 34568 NUMBER SIGN
+sign $ 25678 DOLLAR SIGN
+math % 24578 PERCENT SIGN
+sign & 123468 AMPERSAND
+punctuation ' 4 APOSTROPHE
+punctuation ( 2368 LEFT PARENTHESIS
+punctuation ) 3568 RIGHT PARENTHESIS
+math + 2358 PLUS SIGN
+punctuation , 2 COMMA
+punctuation - 368 HYPHEN-MINUS
+punctuation . 3 FULL STOP
+punctuation / 348 SLASH
+include digits8Dots.uti
+punctuation : 25 COLON
+punctuation ; 23 SEMICOLON
+math < 358 LESS-THAN SIGN
+math = 23568 EQUALS SIGN
+math > 267 GREATER-THAN SIGN
+punctuation ? 26 QUESTION MARK
+sign @ 478 COMMERCIAL AT
+uplow Aa 17,1 LATIN LETTER A
+uplow Bb 127,12 LATIN LETTER B
+uplow Cc 147,14 LATIN LETTER C
+uplow Dd 1457,145 LATIN LETTER D
+uplow Ee 157,15 LATIN LETTER E
+uplow Ff 1247,124 LATIN LETTER F
+uplow Gg 12457,1245 LATIN LETTER G
+uplow Hh 1257,125 LATIN LETTER H
+uplow Ii 247,24 LATIN LETTER I
+uplow Jj 2457,245 LATIN LETTER J
+uplow Kk 137,13 LATIN LETTER K
+uplow Ll 1237,123 LATIN LETTER L
+uplow Mm 1347,134 LATIN LETTER M
+uplow Nn 13457,1345 LATIN LETTER N
+uplow Oo 1357,135 LATIN LETTER O
+uplow Pp 12347,1234 LATIN CAPITAL LETTER P
+uplow Rr 12357,1235 LATIN LETTER R
+uplow Ss 2347,234 LATIN LETTER S
+uplow Tt 23457,2345 LATIN LETTER T
+uplow Uu 1367,136 LATIN LETTER U
+uplow Vv 12367,1236 LATIN LETTER V
+uplow Yy 134567,13456 LATIN LETTER Y
+punctuation [ 23678 LEFT SQUARE BRACKET
+punctuation ] 35678 RIGHT SQUARE BRACKET
+punctuation ^ 12348 CIRCUMFLEX ACCENT
+punctuation _ 3678 LOW LINE
+punctuation ` 5 GRAVE ACCENT
+punctuation { 123678 LEFT CURLY BRACKET
+punctuation | 4568 VERTICAL LINE
+punctuation } 345678 RIGHT CURLY BRACKET
+punctuation ~ 467 TILDE
+sign \x007f 7 DELETE
+sign \x20AC 1578 #EURO SIGN (0x80)
+noback sign \x0080 1578 #EURO SIGN (0x80)
+sign \x0081 45 <control-0081>
+punctuation \x201A 457 #Low single quote (0x82)
+noback punctuation \x0082 457 #Low single quote (0x82)
+sign \x0192 58 #Flurihn (0x83)
+noback sign \x0083 58 #Flurihn (0x83)
+punctuation \x201E 2378 #Low quote (0x84)
+noback punctuation \x0084 2378 #Low quote (0x84)
+letter \x2020 2357 #Dagger (0x86
+noback letter \x0086 2357 #Dagger (0x86
+letter \x2021 23578 #Double dagger (0x87
+noback letter \x0087 23578 #Double dagger (0x87
+letter \x02c6 5678 #Modifier letter circumflex (0x88)
+noback letter \x0088 5678 #Modifier letter circumflex (0x88)
+math \x2030 245678 #permille sign (0x89)
+noback math \x0089 245678 #permille sign (0x89)
+uplow \x0160\x0161 23478,2348 #LATIN CAPITAL LETTER S WITH CARON (0x8a)
+noback uplow \x008a\x009a 23478,2348 #LATIN LETTER S WITH CARON (0x8a)
+punctuation \x2039 456 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK (0x8b)
+noback punctuation \x008b 456 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK (0x8b)
+uplow \x0152\x0153 13578,1358 #LATIN CAPITAL LIGATURE OE (0x8c)
+noback uplow \x008c\x009c 13578,1358 #LATIN LIGATURE OE (0x8c)
+sign \x008d 3567 REVERSE LINE FEED (not defined in cp1252)
+letter \x008f 27 SINGLE SHIFT THREE (not defined in cp1252)
+letter \x0090 357 DEVICE CONTROL STRING (not defined in cp1252)
+punctuation \x2018 47 #LEFT SINGLE QUOTATION MARK (0x91)
+noback punctuation \x0091 47 #LEFT SINGLE QUOTATION MARK (0x91)
+punctuation \x2019 48 #RIGHT SINGLE QUOTATION MARK (0x92)
+noback punctuation \x0092 48 #RIGHT SINGLE QUOTATION MARK (0x92)
+punctuation \x201c 237 #LEFT DOUBLE QUOTATION MARK (0x93)
+noback punctuation \x0093 237 #LEFT DOUBLE QUOTATION MARK (0x93)
+punctuation \x201d 568 #RIGHT DOUBLE QUOTATION MARK (0x94)
+noback punctuation \x0094 568 #RIGHT DOUBLE QUOTATION MARK (0x94)
+sign \x2022 37 #Bullit (0x95)
+noback sign \x0095 37 #Bullit (0x95)
+sign \x02DC 46 #SMALL TILDE (0x98)
+noback sign \x0098 46 #SMALL TILDE (0x98)
+sign \x2122 234578 #TRADE MARK SIGN (0x99)
+noback sign \x0099 234578 #TRADE MARK SIGN (0x99)
+punctuation \x203A 4567 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (0x9b)
+noback punctuation \x009b 4567 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (0x9b)
+letter \x009d 2567 OPERATING SYSTEM COMMAND
+uplow \x0178\x00ff 2345678,234568 #LATIN LETTER Y WITH DIAERESIS (0x9f)
+noback uppercase \x009f 2345678 #LATIN LETTER Y WITH DIAERESIS (0x9f)
+punctuation \x00a0 23458 NO-BREAK SPACE (0xa0)
+punctuation \x00a2 2578 CENT SIGN (0xa2)
+punctuation \x00a3 1238 POUND SIGN (0xa3)
+punctuation \x00a5 67 YEN SIGN (0xa5)
+punctuation \x00a6 3478 BROKEN BAR (0xa6)
+punctuation \x00a7 578 SECTION SIGN (0xa7)
+punctuation \x00a9 134678 COPYRIGHT SIGN (0xa9)
+letter \x00aa 234678 FEMININE ORDINAL INDICATOR (0xaa)
+punctuation \x00ab 57 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (0xab)
+letter \x00ad 378 SOFT HYPHEN (0xad)
+punctuation \x00ae 123578 REGISTERED SIGN (0xae)
+punctuation \x00af 23567 MACRON (0xaf)
+math \x00b1 123458 PLUS-MINUS SIGN
+punctuation \x00b2 238 SUPERSCRIPT TWO
+punctuation \x00b3 258 SUPERSCRIPT THREE
+punctuation \x00b4 468 ACUTE ACCENT
+punctuation \x00b6 1234568 PILCROW SIGN
+punctuation \x00b7 38 MIDDLE DOT
+punctuation \x00b8 4678 CEDILLA
+punctuation \x00b9 28 SUPERSCRIPT ONE
+letter \x00ba 12345678 MASCULINE ORDINAL INDICATOR
+punctuation \x00bb 567 RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+punctuation \x00bc 13458 VULGAR FRACTION ONE QUARTER
+punctuation \x00bd 458 VULGAR FRACTION ONE HALF
+uplow \x00c1\x00e1 1235678,123568 LATIN LETTER A WITH ACUTE
+uplow \x00c2\x00e2 1678,168 LATIN LETTER A WITH CIRCUMFLEX
+uplow \x00c3\x00e3 14678,1468 LATIN LETTER A WITH TILDE
+uplow \x00c4\x00e4 34578,3458 LATIN LETTER A WITH DIAERESIS
+uplow \x00c5\x00e5 167,16 LATIN LETTER A WITH RING ABOVE
+uplow \x00c6\x00e6 3457,345 LATIN LETTER AE
+uplow \x00cc\x00ec 15678,1568 LATIN LETTER I WITH GRAVE
+uplow \x00cd\x00ed 12678,1268 LATIN LETTER I WITH ACUTE
+uplow \x00d0\x00f0 1345678,134568 LATIN LETTER ETH
+uplow \x00d1\x00f1 1245678,124568 LATIN LETTER N WITH TILDE
+uplow \x00d2\x00f2 124678,12468 LATIN LETTER O WITH GRAVE
+uplow \x00d3\x00f3 34678,3468 LATIN LETTER O WITH ACUTE
+uplow \x00d5\x00f5 145678,14568 LATIN LETTER O WITH TILDE
+uplow \x00d6\x00f6 24678,2468 LATIN LETTER O WITH DIAERESIS
+math \x00d7 13468 MULTIPLICATION SIGN
+uplow \x00d8\x00f8 2467,246 LATIN LETTER O WITH STROKE
+uplow \x00da\x00fa 125678,12568 LATIN LETTER U WITH ACUTE
+uplow \x00dd\x00fd 13478,1348 LATIN LETTER Y WITH ACUTE (infinite?)
+uplow \x00de\x00fe 1378,138 LATIN LETTER THORN
+lowercase \x00df 23468 LATIN SMALL LETTER SHARP S
+math \x00f7 2568 DIVISION SIGN
+
+# Character used for capslettersign
+# Resides in the "private use area", and shouldn't conflict with anything.
+sign \xf8ff f
+
+#Unicode Braille patterns
+include braille-patterns.cti
+
+# characters that have letsign as part of their definition
+# (to be removed when the alwaysletsign opcode has been implemented).
+punctuation * 6-35 ASTERISK
+uplow Qq 6-123457,6-12345 LATIN LETTER Q
+uplow Ww 6-24567,6-2456 LATIN LETTER W
+uplow Xx 6-13467,6-1346 LATIN LETTER X
+uplow Zz 6-13567,6-1356 LATIN LETTER Z
+punctuation \\ 6-347 REVERSE SLASH
+punctuation \x2026 6-3-3-3 #Elipsis (0x85)
+noback punctuation \x0085 6-3-3-3 #Elipsis (0x85)
+uplow \x017d\x017e 6-3467,6-346 #LATIN LETTER Z WITH CARON (0x8e)
+noback uplow \x008e\x009e 6-3467,6-346 #LATIN LETTER Z WITH CARON (0x8e)
+letter \x2013 6-36 #EN DASH (0x96)
+noback sign \x0096 6-36 #EN DASH (0x96)
+letter \x2014 6-367 #Em DASH (0x97)
+noback sign \x0097 6-367 #Em DASH (0x97)
+punctuation \x00a4 6-2367 CURRENCY SIGN (0xa4)
+punctuation \x00a8 6-56 DIAERESIS (0xa8)
+punctuation \x00ac 6-34567 NOT SIGN (0xac)
+sign \x00b0 4-356 DEGREE SIGN (0xb0)
+sign \x00b5 6-236 MICRO SIGN
+punctuation \x00be 6-3456 VULGAR FRACTION THREE QUARTERS
+punctuation \x00bf 6-34 INVERTED QUESTION MARK
+uplow \x00c0\x00e0 6-123567,6-12356 LATIN LETTER A WITH GRAVE
+uplow \x00c7\x00e7 6-123467,6-12346 LATIN LETTER C WITH CEDILLA
+uplow \x00c8\x00e8 6-23467,6-2346 LATIN LETTER E WITH GRAVE
+uplow \x00c9\x00e9 6-1234567,6-123456 LATIN LETTER E WITH ACUTE
+uplow \x00ca\x00ea 6-1267,6-126 LATIN LETTER E WITH CIRCUMFLEX
+uplow \x00cb\x00eb 6-12467,6-1246 LATIN LETTER E WITH DIAERESIS
+uplow \x00ce\x00ee 6-1467,6-146 LATIN LETTER I WITH CIRCUMFLEX
+uplow \x00cf\x00ef 6-124567,6-12456 LATIN LETTER I WITH DIAERESIS
+uplow \x00d4\x00f4 6-14567,6-1456 LATIN LETTER O WITH CIRCUMFLEX
+uplow \x00d9\x00f9 6-234567,6-23456 LATIN LETTER U WITH GRAVE
+uplow \x00db\x00fb 6-1567,6-156 LATIN LETTER U WITH CIRCUMFLEX
+uplow \x00dc\x00fc 6-12567,6-1256 LATIN LETTER U WITH DIAERESIS
+
+# Misc letters from other character sets prefixed with dot 5
+# to be implemented
+
+### misc opcodes ###
+
+# Emphasis opcodes
+emphclass italic
+emphclass underline
+emphclass bold
+
+begemphphrase italic 56
+endemphphrase italic after 56
+begemphword italic 56
+endemphword italic 56
+
+begemphphrase bold 56
+endemphphrase bold after 56
+begemphword bold 56
+endemphword bold 56
+
+begemphphrase underline 56
+endemphphrase underline after 56
+begemphword underline 56
+endemphword underline 56
+
+# special symbols
+decpoint , 2
+hyphen - 368
+letsign 6
+noletsign Ii
+noletsignbefore 1234567890
+
+capsletter f
+multind f-6 capsletter letsign
+multind 6-f letsign capsletter
+capsnocont
+
+# The Danish use of letsign differs somewhat from the LibLouis way.
+# In order to be sure that we are getting a letsign when we want one, we are sometimes getting an overlap.
+
+# Ensure that we have letsign between a digit and "st"
+# and nd after a digit is not contracted
+noback context _$d["st"]!$l @6-234-2345
+noback context _$d["st"]~ @6-234-2345
+noback context _$d["nd"]!$l @1345-145
+noback context _$d["nd"]~ @1345-145
+# Ensure that we get a letsign between a digit and a single letter.
+noback context $d[]$l!$l @6
+noback context $d[]$l~ @6
+
+#Special sequences, urls emails and file names.
+
+nocont $
+nocont \\ # line cannot end with a backslash
+nocont @
+nocont ://
+nocont www
+nocont .com
+nocont .dk
+nocont .eu
+nocont .edu
+nocont .gov
+nocont .mil
+nocont .net
+nocont .org
+nocont .uk
+nocont .doc
+nocont .exe
+nocont .htm
+nocont .tex
+nocont .txt
+nocont .gif
+nocont .jpg
+nocont .png
+nocont .wav
+nocont .tar
+nocont .zip
+
+# Word contractions with only 1 cell
+word at 1
+word bliver 12
+word den 12346
+word der 23456
+word det 2346
+word de 1456
+word du 145
+word efter 1356
+word eller 15
+word en 126
+word er 156
+word et 346
+word for 124
+word før 246
+word gennem 12456
+word gør 1245
+word han 13456
+word har 125
+word hun 136
+word hvad 2456
+word hvor 34
+word jeg 245
+word kan 13
+word lige 123
+word med 134
+word men 146
+word ned 1246
+word når 1345
+word og 14
+word op 135
+word over 1346
+word på 1234
+word ret 12356
+word rigtig 1235
+word skal 123456
+word som 234
+word så 16
+word te 1256
+word til 2345
+word under 12345
+word ved 1236
+word ve 3456
+word være 345
+
+### Exceptions ###
+
+# Ensure no single cell word contraction before or after a dash
+word -at 368-1-2345
+word at- 1-2345-368
+word -bliver 368-12-123-24-1236-15-1235
+word bliver- 12-123-24-1236-15-1235-368
+word -den 368-145-15-1345
+word den- 145-15-1345-368
+word -der 368-145-15-1235
+word der- 145-15-1235-368
+word -det 368-145-15-2345
+word det- 145-15-2345-368
+word -de 368-145-15
+word de- 145-15-368
+word -du 368-145-136
+word du- 145-136-368
+word -efter 368-15-124-2345-15-1235
+word efter- 15-124-2345-15-1235-368
+word -er 368-15-1235
+word er- 15-1235-368
+word -et 368-15-2345
+word et- 15-2345-368
+word -for 368-124-135-1235
+word for- 124-135-1235-368
+word -før 368-124-246-1235
+word før- 124-246-1235-368
+word -gennem 368-1245-15-1345-1345-15-134
+word gennem- 1245-15-1345-1345-15-134-368
+word -gør 368-1245-246-1235
+word gør- 1245-246-1235-368
+word -han 368-125-1-1345
+word han- 125-1-1345-368
+word -har 368-125-1-1235
+word har- 125-1-1235-368
+word -hun 368-125-136-1345
+word hun- 125-136-1345-368
+word -kan 368-13-1-1345
+word kan- 13-1-1345-368
+word -lige 368-123-24-12456
+word lige- 123-24-12456-368
+word -med 368-146-145
+word med- 146-145-368
+word -men 368-134-126
+word men- 134-126-368
+word -ned 368-1345-15-145
+word ned- 1345-15-145-368
+word -når 368-1345-16-1235
+word når- 1345-16-1235-368
+word -og 368-135-1245
+word og- 135-1245-368
+word -op 368-135-1234
+word op- 135-1234-368
+word -over 368-135-1236-15-1235
+word over- 135-1236-15-1235-368
+word -på 368-1234-16
+word på- 1234-16-368
+word -ret 368-1235-15-2345
+word ret- 1235-15-2345-368
+word -rigtig 368-1235-24-1245-2345-24-1245
+word rigtig- 1235-24-1245-2345-24-1245-368
+word -skal 368-234-13-1-123
+word skal- 234-13-1-123-368
+word -som 368-234-135-134
+word som- 234-135-134-368
+word -så 368-234-16
+word så- 234-16-368
+word -te 368-2345-15
+word te- 2345-15-368
+word -til 368-2345-24-123
+word til- 2345-24-123-368
+word -under 368-136-1345-145-15-1235
+word under- 136-1345-145-15-1235-368
+word -ved 368-1236-15-145
+word ved- 1236-15-145-368
+word -ve 368-1236-15
+word ve- 1236-15-368
+word -være 368-1236-345-1235-15
+word Være- 1236-345-1235-15-368
+
+### Patches ###
+# the following sections are to compensate for various behaviours and problems in liblouis.
+# They will be removed, as the issues are resolved.
+
+# Ensure correct back-translation of word contractions before various punctuation.
+
+nofor always a 6-1
+nofor always b 6-12
+nofor always c 6-14
+nofor always d 6-145
+nofor always e 6-15
+nofor always f 6-124
+nofor always g 6-1245
+nofor always h 6-125
+nofor always j 6-245
+nofor always k 6-13
+nofor always l 6-123
+nofor always m 6-134
+nofor always n 6-1345
+nofor always o 6-135
+nofor always p 6-1234
+nofor always q 6-12345
+nofor always r 6-1235
+nofor always s 6-234
+nofor always t 6-2345
+nofor always u 6-136
+nofor always v 6-1236
+nofor always w 6-2456
+nofor always x 6-1346
+nofor always y 6-13456
+nofor always z 6-1356
+nofor always æ 6-345
+nofor always ø 6-246
+nofor always å 6-16
+
+nofor always A 6-17
+nofor always B 6-127
+nofor always C 6-147
+nofor always D 6-1457
+nofor always E 6-157
+nofor always F 6-1247
+nofor always G 6-12457
+nofor always H 6-1257
+nofor always J 6-2457
+nofor always K 6-137
+nofor always L 6-1237
+nofor always M 6-1347
+nofor always N 6-13457
+nofor always O 6-1357
+nofor always P 6-12347
+nofor always Q 6-123457
+nofor always R 6-12357
+nofor always S 6-2347
+nofor always T 6-23457
+nofor always U 6-1367
+nofor always V 6-12367
+nofor always W 6-24567
+nofor always X 6-13467
+nofor always Y 6-134567
+nofor always Z 6-13567
+nofor always Æ 6-3457
+nofor always Ø 6-2467
+nofor always Å 6-167
+
+# if a word contraction is followed by a punctuation and another word immediately after,
+# The contracted word before the punctuation will back-translate as its components
+class wordlimit /,!.:’()?"'\x00ab_\x201d\x0094\x2019\x0092\x00bb
+
+nofor before wordlimit begword at 1
+nofor before wordlimit begword bliver 12
+nofor before wordlimit begword den 12346
+nofor before wordlimit begword der 23456
+nofor before wordlimit begword det 2346
+nofor before wordlimit begword de 1456
+nofor before wordlimit begword du 145
+nofor before wordlimit begword efter 1356
+nofor before wordlimit begword eller 15
+nofor before wordlimit begword en 126
+nofor before wordlimit begword er 156
+nofor before wordlimit begword et 346
+nofor before wordlimit begword for 124
+nofor before wordlimit begword før 246
+nofor before wordlimit begword gennem 12456
+nofor before wordlimit begword gør 1245
+nofor before wordlimit begword han 13456
+nofor before wordlimit begword har 125
+nofor before wordlimit begword hun 136
+nofor before wordlimit begword hvad 2456
+nofor before wordlimit begword hvor 34
+nofor before wordlimit begword jeg 245
+nofor before wordlimit begword kan 13
+nofor before wordlimit begword lige 123
+nofor before wordlimit begword med 134
+nofor before wordlimit begword men 146
+nofor before wordlimit begword ned 1246
+nofor before wordlimit begword når 1345
+nofor before wordlimit begword og 14
+nofor before wordlimit begword op 135
+nofor before wordlimit begword over 1346
+nofor before wordlimit begword på 1234
+nofor before wordlimit begword ret 12356
+nofor before wordlimit begword rigtig 1235
+nofor before wordlimit begword skal 123456
+nofor before wordlimit begword som 234
+nofor before wordlimit begword så 16
+nofor before wordlimit begword te 1256
+nofor before wordlimit begword til 2345
+nofor before wordlimit begword under 12345
+nofor before wordlimit begword ved 1236
+nofor before wordlimit begword være 345
+
+### Problems solved with pass 2 ###
+
+# Most of these lines are temporary.
+# They will be written with a few swap sets when the swapdd opcode has been fixed.
+
+
+# Generic forward convert of @f-... to @...7
+noback pass2 @f-235 @2357
+# Conversion with letsign.
+noback pass2 @f-6-235 @6-2357
+# Conversion with dot 5, which is used for accent marker in higher unicode pages.
+noback pass2 @f-5-235 @5-2357
+# Generic backward conversion.
+nofor pass2 @2357 @f-235
+# Conversion with dot 5 (letsign is handled below).
+nofor pass2 @5-2357 @f-5-235
+
+# Same for the following characters.
+
+noback pass2 @f-35 @357
+noback pass2 @f-6-35 @6-357
+noback pass2 @f-5-35 @5-357
+nofor pass2 @357 @f-35
+nofor pass2 @5-357 @f-5-35
+
+noback pass2 @f-1 @17
+noback pass2 @f-6-1 @6-17
+noback pass2 @f-5-1 @5-17
+nofor pass2 @17 @f-1
+nofor pass2 @5-17 @f-5-1
+
+noback pass2 @f-12 @127
+noback pass2 @f-6-12 @6-127
+noback pass2 @f-5-12 @5-127
+nofor pass2 @127 @f-12
+nofor pass2 @5-127 @f-5-12
+
+noback pass2 @f-14 @147
+noback pass2 @f-6-14 @6-147
+noback pass2 @f-5-14 @5-147
+nofor pass2 @147 @f-14
+nofor pass2 @5-147 @f-5-14
+
+noback pass2 @f-145 @1457
+noback pass2 @f-6-145 @6-1457
+noback pass2 @f-5-145 @5-1457
+nofor pass2 @1457 @f-145
+nofor pass2 @5-1457 @f-5-145
+
+noback pass2 @f-15 @157
+noback pass2 @f-6-15 @6-157
+noback pass2 @f-5-15 @5-157
+nofor pass2 @157 @f-15
+nofor pass2 @5-157 @f-5-15
+
+noback pass2 @f-124 @1247
+noback pass2 @f-6-124 @6-1247
+noback pass2 @f-5-124 @5-1247
+nofor pass2 @1247 @f-124
+nofor pass2 @5-1247 @f-5-124
+
+noback pass2 @f-1245 @12457
+noback pass2 @f-6-1245 @6-12457
+noback pass2 @f-5-1245 @5-12457
+nofor pass2 @12457 @f-1245
+nofor pass2 @5-12457 @f-5-1245
+
+noback pass2 @f-125 @1257
+noback pass2 @f-6-125 @6-1257
+noback pass2 @f-5-125 @5-1257
+nofor pass2 @1257 @f-125
+nofor pass2 @5-1257 @f-5-125
+
+noback pass2 @f-24 @247
+noback pass2 @f-6-24 @6-247
+noback pass2 @f-5-24 @5-247
+nofor pass2 @247 @f-24
+nofor pass2 @5-247 @f-5-24
+
+noback pass2 @f-245 @2457
+noback pass2 @f-6-245 @6-2457
+noback pass2 @f-5-245 @5-2457
+nofor pass2 @2457 @f-245
+nofor pass2 @5-2457 @f-5-245
+
+noback pass2 @f-13 @137
+noback pass2 @f-6-13 @6-137
+noback pass2 @f-5-13 @5-137
+nofor pass2 @137 @f-13
+nofor pass2 @5-137 @f-5-13
+
+noback pass2 @f-123 @1237
+noback pass2 @f-6-123 @6-1237
+noback pass2 @f-5-123 @5-1237
+nofor pass2 @1237 @f-123
+nofor pass2 @5-1237 @f-5-123
+
+noback pass2 @f-134 @1347
+noback pass2 @f-6-134 @6-1347
+noback pass2 @f-5-134 @5-1347
+nofor pass2 @1347 @f-134
+nofor pass2 @5-1347 @f-5-134
+
+noback pass2 @f-1345 @13457
+noback pass2 @f-6-1345 @6-13457
+noback pass2 @f-5-1345 @5-13457
+nofor pass2 @13457 @f-1345
+nofor pass2 @5-13457 @f-5-1345
+
+noback pass2 @f-135 @1357
+noback pass2 @f-6-135 @6-1357
+noback pass2 @f-5-135 @5-1357
+nofor pass2 @1357 @f-135
+nofor pass2 @5-1357 @f-5-135
+
+noback pass2 @f-1234 @12347
+noback pass2 @f-6-1234 @6-12347
+noback pass2 @f-5-1234 @5-12347
+nofor pass2 @12347 @f-1234
+nofor pass2 @5-12347 @f-5-1234
+
+noback pass2 @f-12345 @123457
+noback pass2 @f-6-12345 @6-123457
+noback pass2 @f-5-12345 @5-123457
+nofor pass2 @123457 @f-12345
+nofor pass2 @5-123457 @f-5-12345
+
+noback pass2 @f-1235 @12357
+noback pass2 @f-6-1235 @6-12357
+noback pass2 @f-5-1235 @5-12357
+nofor pass2 @12357 @f-1235
+nofor pass2 @5-12357 @f-5-1235
+
+noback pass2 @f-234 @2347
+noback pass2 @f-6-234 @6-2347
+noback pass2 @f-5-234 @5-2347
+nofor pass2 @2347 @f-234
+nofor pass2 @5-2347 @f-5-234
+
+noback pass2 @f-2345 @23457
+noback pass2 @f-6-2345 @6-23457
+noback pass2 @f-5-2345 @5-23457
+nofor pass2 @23457 @f-2345
+nofor pass2 @5-23457 @f-5-2345
+
+noback pass2 @f-136 @1367
+noback pass2 @f-6-136 @6-1367
+noback pass2 @f-5-136 @5-1367
+nofor pass2 @1367 @f-136
+nofor pass2 @5-1367 @f-5-136
+
+noback pass2 @f-1236 @12367
+noback pass2 @f-6-1236 @6-12367
+noback pass2 @f-5-1236 @5-12367
+nofor pass2 @12367 @f-1236
+nofor pass2 @5-12367 @f-5-1236
+
+noback pass2 @f-2456 @24567
+noback pass2 @f-6-2456 @6-24567
+noback pass2 @f-5-2456 @5-24567
+nofor pass2 @24567 @f-2456
+nofor pass2 @5-24567 @f-5-2456
+
+noback pass2 @f-1346 @13467
+noback pass2 @f-6-1346 @6-13467
+noback pass2 @f-5-1346 @5-13467
+nofor pass2 @13467 @f-1346
+nofor pass2 @5-13467 @f-5-1346
+
+noback pass2 @f-13456 @134567
+noback pass2 @f-6-13456 @6-134567
+noback pass2 @f-5-13456 @5-134567
+nofor pass2 @134567 @f-13456
+nofor pass2 @5-134567 @f-5-13456
+
+noback pass2 @f-1356 @13567
+noback pass2 @f-6-1356 @6-13567
+noback pass2 @f-5-1356 @5-13567
+nofor pass2 @13567 @f-1356
+nofor pass2 @5-13567 @f-5-1356
+
+noback pass2 @f-34 @347
+noback pass2 @f-6-34 @6-347
+noback pass2 @f-5-34 @5-347
+nofor pass2 @347 @f-34
+nofor pass2 @5-347 @f-5-34
+
+noback pass2 @f-346 @3467
+noback pass2 @f-6-346 @6-3467
+noback pass2 @f-5-346 @5-3467
+nofor pass2 @3467 @f-346
+nofor pass2 @5-3467 @f-5-346
+
+noback pass2 @f-2348 @23478
+noback pass2 @f-6-2348 @6-23478
+noback pass2 @f-5-2348 @5-23478
+nofor pass2 @23478 @f-2348
+nofor pass2 @5-23478 @f-5-2348
+
+noback pass2 @f-1358 @13578
+noback pass2 @f-6-1358 @6-13578
+noback pass2 @f-5-1358 @5-13578
+nofor pass2 @13578 @f-1358
+nofor pass2 @5-13578 @f-5-1358
+
+noback pass2 @f-234568 @2345678
+noback pass2 @f-6-234568 @6-2345678
+noback pass2 @f-5-234568 @5-2345678
+nofor pass2 @2345678 @f-234568
+nofor pass2 @5-2345678 @f-5-234568
+
+noback pass2 @f-236 @2367
+noback pass2 @f-6-236 @6-2367
+noback pass2 @f-5-236 @5-2367
+nofor pass2 @2367 @f-236
+nofor pass2 @5-2367 @f-5-236
+
+noback pass2 @f-256 @2567
+noback pass2 @f-6-256 @6-2567
+noback pass2 @f-5-256 @5-2567
+nofor pass2 @2567 @f-256
+nofor pass2 @5-2567 @f-5-256
+
+noback pass2 @f-356 @3567
+noback pass2 @f-6-356 @6-3567
+noback pass2 @f-5-356 @5-3567
+nofor pass2 @3567 @f-356
+nofor pass2 @5-3567 @f-5-356
+
+noback pass2 @f-3456 @34567
+noback pass2 @f-6-3456 @6-34567
+noback pass2 @f-5-3456 @5-34567
+nofor pass2 @34567 @f-3456
+nofor pass2 @5-34567 @f-5-3456
+
+noback pass2 @f-12356 @123567
+noback pass2 @f-6-12356 @6-123567
+noback pass2 @f-5-12356 @5-123567
+nofor pass2 @123567 @f-12356
+nofor pass2 @5-123567 @f-5-12356
+
+noback pass2 @f-123568 @1235678
+noback pass2 @f-6-123568 @6-1235678
+noback pass2 @f-5-123568 @5-1235678
+nofor pass2 @1235678 @f-123568
+nofor pass2 @5-1235678 @f-5-123568
+
+noback pass2 @f-168 @1678
+noback pass2 @f-6-168 @6-1678
+noback pass2 @f-5-168 @5-1678
+nofor pass2 @1678 @f-168
+nofor pass2 @5-1678 @f-5-168
+
+noback pass2 @f-1468 @14678
+noback pass2 @f-6-1468 @6-14678
+noback pass2 @f-5-1468 @5-14678
+nofor pass2 @14678 @f-1468
+nofor pass2 @5-14678 @f-5-1468
+
+noback pass2 @f-3458 @34578
+noback pass2 @f-6-3458 @6-34578
+noback pass2 @f-5-3458 @5-34578
+nofor pass2 @34578 @f-3458
+nofor pass2 @5-34578 @f-5-3458
+
+noback pass2 @f-16 @167
+noback pass2 @f-6-16 @6-167
+noback pass2 @f-5-16 @5-167
+nofor pass2 @167 @f-16
+nofor pass2 @5-167 @f-5-16
+
+noback pass2 @f-345 @3457
+noback pass2 @f-6-345 @6-3457
+noback pass2 @f-5-345 @5-3457
+nofor pass2 @3457 @f-345
+nofor pass2 @5-3457 @f-5-345
+
+noback pass2 @f-12346 @123467
+noback pass2 @f-6-12346 @6-123467
+noback pass2 @f-5-12346 @5-123467
+nofor pass2 @123467 @f-12346
+nofor pass2 @5-123467 @f-5-12346
+
+noback pass2 @f-2346 @23467
+noback pass2 @f-6-2346 @6-23467
+noback pass2 @f-5-2346 @5-23467
+nofor pass2 @23467 @f-2346
+nofor pass2 @5-23467 @f-5-2346
+
+noback pass2 @f-123456 @1234567
+noback pass2 @f-6-123456 @6-1234567
+noback pass2 @f-5-123456 @5-1234567
+nofor pass2 @1234567 @f-123456
+nofor pass2 @5-1234567 @f-5-123456
+
+noback pass2 @f-126 @1267
+noback pass2 @f-6-126 @6-1267
+noback pass2 @f-5-126 @5-1267
+nofor pass2 @1267 @f-126
+nofor pass2 @5-1267 @f-5-126
+
+noback pass2 @f-1246 @12467
+noback pass2 @f-6-1246 @6-12467
+noback pass2 @f-5-1246 @5-12467
+nofor pass2 @12467 @f-1246
+nofor pass2 @5-12467 @f-5-1246
+
+noback pass2 @f-1568 @15678
+noback pass2 @f-6-1568 @6-15678
+noback pass2 @f-5-1568 @5-15678
+nofor pass2 @15678 @f-1568
+nofor pass2 @5-15678 @f-5-1568
+
+noback pass2 @f-1268 @12678
+noback pass2 @f-6-1268 @6-12678
+noback pass2 @f-5-1268 @5-12678
+nofor pass2 @12678 @f-1268
+nofor pass2 @5-12678 @f-5-1268
+
+noback pass2 @f-146 @1467
+noback pass2 @f-6-146 @6-1467
+noback pass2 @f-5-146 @5-1467
+nofor pass2 @1467 @f-146
+nofor pass2 @5-1467 @f-5-146
+
+noback pass2 @f-12456 @124567
+noback pass2 @f-6-12456 @6-124567
+noback pass2 @f-5-12456 @5-124567
+nofor pass2 @124567 @f-12456
+nofor pass2 @5-124567 @f-5-12456
+
+noback pass2 @f-134568 @1345678
+noback pass2 @f-6-134568 @6-1345678
+noback pass2 @f-5-134568 @5-1345678
+nofor pass2 @1345678 @f-134568
+nofor pass2 @5-1345678 @f-5-134568
+
+noback pass2 @f-124568 @1245678
+noback pass2 @f-6-124568 @6-1245678
+noback pass2 @f-5-124568 @5-1245678
+nofor pass2 @1245678 @f-124568
+nofor pass2 @5-1245678 @f-5-124568
+
+noback pass2 @f-12468 @124678
+noback pass2 @f-6-12468 @6-124678
+noback pass2 @f-5-12468 @5-124678
+nofor pass2 @124678 @f-12468
+nofor pass2 @5-124678 @f-5-12468
+
+noback pass2 @f-3468 @34678
+noback pass2 @f-6-3468 @6-34678
+noback pass2 @f-5-3468 @5-34678
+nofor pass2 @34678 @f-3468
+nofor pass2 @5-34678 @f-5-3468
+
+noback pass2 @f-1456 @14567
+noback pass2 @f-6-1456 @6-14567
+noback pass2 @f-5-1456 @5-14567
+nofor pass2 @14567 @f-1456
+nofor pass2 @5-14567 @f-5-1456
+
+noback pass2 @f-14568 @145678
+noback pass2 @f-6-14568 @6-145678
+noback pass2 @f-5-14568 @5-145678
+nofor pass2 @145678 @f-14568
+nofor pass2 @5-145678 @f-5-14568
+
+noback pass2 @f-2468 @24678
+noback pass2 @f-6-2468 @6-24678
+noback pass2 @f-5-2468 @5-24678
+nofor pass2 @24678 @f-2468
+nofor pass2 @5-24678 @f-5-2468
+
+noback pass2 @f-246 @2467
+noback pass2 @f-6-246 @6-2467
+noback pass2 @f-5-246 @5-2467
+nofor pass2 @2467 @f-246
+nofor pass2 @5-2467 @f-5-246
+
+noback pass2 @f-23456 @234567
+noback pass2 @f-6-23456 @6-234567
+noback pass2 @f-5-23456 @5-234567
+nofor pass2 @234567 @f-23456
+nofor pass2 @5-234567 @f-5-23456
+
+noback pass2 @f-12568 @125678
+noback pass2 @f-6-12568 @6-125678
+noback pass2 @f-5-12568 @5-125678
+nofor pass2 @125678 @f-12568
+nofor pass2 @5-125678 @f-5-12568
+
+noback pass2 @f-156 @1567
+noback pass2 @f-6-156 @6-1567
+noback pass2 @f-5-156 @5-1567
+nofor pass2 @1567 @f-156
+nofor pass2 @5-1567 @f-5-156
+
+noback pass2 @f-1256 @12567
+noback pass2 @f-6-1256 @6-12567
+noback pass2 @f-5-1256 @5-12567
+nofor pass2 @12567 @f-1256
+nofor pass2 @5-12567 @f-5-1256
+
+noback pass2 @f-1348 @13478
+noback pass2 @f-6-1348 @6-13478
+noback pass2 @f-5-1348 @5-13478
+nofor pass2 @13478 @f-1348
+nofor pass2 @5-13478 @f-5-1348
+
+noback pass2 @f-138 @1378
+noback pass2 @f-6-138 @6-1378
+noback pass2 @f-5-138 @5-1378
+nofor pass2 @1378 @f-138
+nofor pass2 @5-1378 @f-5-138
+
+noback pass2 @f-234568 @2345678
+noback pass2 @f-6-234568 @6-2345678
+noback pass2 @f-5-234568 @5-2345678
+nofor pass2 @2345678 @f-234568
+nofor pass2 @5-2345678 @f-5-234568
+
+# Tweak to keep letsign for letters that should always have letsign.
+# Letsign will be removed by the multind opcode. So we insert an extra one.
+nofor pass2 @6-123457 @f-6-6-12345
+nofor pass2 @6-24567 @f-6-6-2456
+nofor pass2 @6-13467 @f-6-6-1346
+nofor pass2 @6-134567 @f-6-6-13456
+nofor pass2 @6-13567 @f-6-6-1356
+nofor pass2 @6-123567 @f-6-6-12356
+nofor pass2 @6-123467 @f-6-6-12346
+nofor pass2 @6-23467 @f-6-6-2346
+nofor pass2 @6-1234567 @f-6-6-123456
+nofor pass2 @6-1267 @f-6-6-126
+nofor pass2 @6-12467 @f-6-6-1246
+nofor pass2 @6-1467 @f-6-6-146
+nofor pass2 @6-124567 @f-6-6-12456
+nofor pass2 @6-14567 @f-6-6-1456
+nofor pass2 @6-234567 @f-6-6-23456
+nofor pass2 @6-1567 @f-6-6-156
+nofor pass2 @6-12567 @f-6-6-1256
+
+# Ensure that punctuation signs etc. are not "tolowered" when they have a letsign, but only when they act as a partword contraction.
+nofor pass2 @6-347 *
+nofor pass2 @6-2357 *
+nofor pass2 @6-3467 *
+nofor pass2 @6-2567 *
+nofor pass2 @6-2367 *
+nofor pass2 @6-34567 *
+
+# remove any superfluous capsletter marks.
+noback pass2 @f ?
+
+# Remove any superfluous letsigns and only keep one.
+noback pass3 @6-6 @6
diff --git a/tables/da-dk-octobraille.dis b/tables/da-dk-octobraille.dis
new file mode 100644
index 0000000..297b277
--- /dev/null
+++ b/tables/da-dk-octobraille.dis
@@ -0,0 +1,282 @@
+# Liblouis: Display table for Danish CP1252 Octo Braille
+#
+# Copyright (C) 2014-2017, Bue Vester-Andersen <bue@vester-andersen.dk>
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#------------
+#
+# This file contains display definitions for Danish 8 dot Braille.
+# It should be included in high level tables to ensure correct mapping of characters to dot patterns.
+#
+# Version: Bue Vester-Andersen 170604
+
+display \x0000 8 NULL
+display \x0001 178 START OF HEADING
+display \x0002 1278 START OF TEXT
+display \x0003 1478 END OF TEXT
+display \x0004 14578 END OF TRANSMISSION
+display \x0005 24568 ENQUIRY
+display \x0006 12478 ACKNOWLEDGE
+display \x0007 124578 BELL
+display \x0008 12578 BACKSPACE
+display \t 2478 CHARACTER TABULATION
+display \n 678 LINE FEED (LF)
+display \v 1368 LINE TABULATION
+display \f 12378 FORM FEED (FF)
+display \r 257 CARRIAGE RETURN (CR)
+display \x000e 134578 SHIFT OUT
+display \x000f 12358 SHIFT IN
+display \x0010 123478 DATA LINK ESCAPE
+display \x0011 1234578 DEVICE CONTROL ONE
+display \x0012 13568 DEVICE CONTROL TWO
+display \x0013 4578 DEVICE CONTROL THREE
+display \x0014 268 DEVICE CONTROL FOUR
+display \x0015 13678 NEGATIVE ACKNOWLEDGE
+display \x0016 278 SYNCHRONOUS IDLE
+display \x0017 3578 END OF TRANSMISSION BLOCK
+display \x0018 78 CANCEL
+display \x0019 68 END OF MEDIUM
+display \x001a 135678 SUBSTITUTE
+display \x001b 2678 ESCAPE
+display \x001c 45678 INFORMATION SEPARATOR FOUR
+display \x001d 12368 INFORMATION SEPARATOR THREE
+display \x001e 1234678 INFORMATION SEPARATOR TWO
+display \x001f 235678 INFORMATION SEPARATOR ONE
+display \s 0 SPACE
+display ! 235 EXCLAMATION MARK
+display " 2356 QUOTATION MARK
+display # 34568 NUMBER SIGN
+display $ 25678 DOLLAR SIGN
+display % 24578 PERCENT SIGN
+display & 123468 AMPERSAND
+display ' 4 APOSTROPHE
+display ( 2368 LEFT PARENTHESIS
+display ) 3568 RIGHT PARENTHESIS
+display * 35 ASTERISK
+display + 2358 PLUS SIGN
+display , 2 COMMA
+display - 368 HYPHEN-MINUS
+display . 3 FULL STOP
+display / 348 SLASH
+display 0 2458 #0
+display 1 18 #1
+display 2 128 #2
+display 3 148 #3
+display 4 1458 #4
+display 5 158 #5
+display 6 1248 #6
+display 7 12458 #7
+display 8 1258 #8
+display 9 248 #9
+display : 25 COLON
+display ; 23 SEMICOLON
+display < 358 LESS-THAN SIGN
+display = 23568 EQUALS SIGN
+display > 267 GREATER-THAN SIGN
+display ? 26 QUESTION MARK
+display @ 478 COMMERCIAL AT
+display A 17 LATIN CAPITAL LETTER A
+display B 127 LATIN CAPITAL LETTER B
+display C 147 LATIN CAPITAL LETTER C
+display D 1457 LATIN CAPITAL LETTER D
+display E 157 LATIN CAPITAL LETTER E
+display F 1247 LATIN CAPITAL LETTER F
+display G 12457 LATIN CAPITAL LETTER G
+display H 1257 LATIN CAPITAL LETTER H
+display I 247 LATIN CAPITAL LETTER I
+display J 2457 LATIN CAPITAL LETTER J
+display K 137 LATIN CAPITAL LETTER K
+display L 1237 LATIN CAPITAL LETTER L
+display M 1347 LATIN CAPITAL LETTER M
+display N 13457 LATIN CAPITAL LETTER N
+display O 1357 LATIN CAPITAL LETTER O
+display P 12347 LATIN CAPITAL LETTER P
+display Q 123457 LATIN CAPITAL LETTER Q
+display R 12357 LATIN CAPITAL LETTER R
+display S 2347 LATIN CAPITAL LETTER S
+display T 23457 LATIN CAPITAL LETTER T
+display U 1367 LATIN CAPITAL LETTER U
+display V 12367 LATIN CAPITAL LETTER V
+display W 24567 LATIN CAPITAL LETTER W
+display X 13467 LATIN CAPITAL LETTER X
+display Y 134567 LATIN CAPITAL LETTER Y
+display Z 13567 LATIN CAPITAL LETTER Z
+display [ 23678 LEFT SQUARE BRACKET
+display \\ 347 REVERSE SLASH
+display ] 35678 RIGHT SQUARE BRACKET
+display ^ 12348 CIRCUMFLEX ACCENT
+display _ 3678 LOW LINE
+display ` 5 GRAVE ACCENT
+display a 1 LATIN SMALL LETTER A
+display b 12 LATIN SMALL LETTER B
+display c 14 LATIN SMALL LETTER C
+display d 145 LATIN SMALL LETTER D
+display e 15 LATIN SMALL LETTER E
+display f 124 LATIN SMALL LETTER F
+display g 1245 LATIN SMALL LETTER G
+display h 125 LATIN SMALL LETTER H
+display i 24 LATIN SMALL LETTER I
+display j 245 LATIN SMALL LETTER J
+display k 13 LATIN SMALL LETTER K
+display l 123 LATIN SMALL LETTER L
+display m 134 LATIN SMALL LETTER M
+display n 1345 LATIN SMALL LETTER N
+display o 135 LATIN SMALL LETTER O
+display p 1234 LATIN SMALL LETTER P
+display q 12345 LATIN SMALL LETTER Q
+display r 1235 LATIN SMALL LETTER R
+display s 234 LATIN SMALL LETTER S
+display t 2345 LATIN SMALL LETTER T
+display u 136 LATIN SMALL LETTER U
+display v 1236 LATIN SMALL LETTER V
+display w 2456 LATIN SMALL LETTER W
+display x 1346 LATIN SMALL LETTER X
+display y 13456 LATIN SMALL LETTER Y
+display z 1356 LATIN SMALL LETTER Z
+display { 123678 LEFT CURLY BRACKET
+display | 4568 VERTICAL LINE
+display } 345678 RIGHT CURLY BRACKET
+display ~ 467 TILDE
+display \x007f 7 DELETE
+display \x0080 1578 #EURO SIGN (0x80)
+display \x0081 45 <control-0081> (not defined in cp1252)
+display \x0082 457 #Low single quote (0x82)
+display \x0083 58 #Flurihn (0x83)
+display \x0084 2378 #Low quote (0x84)
+display \x0085 6 #Elipsis (0x85)
+display \x0086 2357 #Dagger (0x86
+display \x0087 23578 #Double dagger (0x87
+display \x0088 5678 #Modifier letter circumflex (0x88)
+display \x0089 245678 #permille sign (0x89)
+display \x008a 23478 #LATIN CAPITAL LETTER S WITH CARON (0x8a)
+display \x008b 456 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK (0x8b)
+display \x008c 13578 #LATIN CAPITAL LIGATURE OE (0x8c)
+display \x008d 3567 REVERSE LINE FEED (not defined in cp1252)
+display \x008e 3467 #LATIN CAPITAL LETTER Z WITH CARON (0x8e)
+display \x008f 27 SINGLE SHIFT THREE (not defined in cp1252)
+display \x0090 357 DEVICE CONTROL STRING (not defined in cp1252)
+display \x0091 47 #LEFT SINGLE QUOTATION MARK (0x91)
+display \x0092 48 #RIGHT SINGLE QUOTATION MARK (0x92)
+display \x0093 237 #LEFT DOUBLE QUOTATION MARK (0x93)
+display \x0094 568 #RIGHT DOUBLE QUOTATION MARK (0x94)
+display \x0095 37 #Bullit (0x95)
+display \x0096 36 #EN DASH (0x96)
+display \x0097 367 #Em DASH (0x97)
+display \x0098 46 #SMALL TILDE (0x98)
+display \x0099 234578 #TRADE MARK SIGN (0x99)
+display \x009a 2348 #LATIN SMALL LETTER S WITH CARON (0x9a)
+display \x009b 4567 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (0x9b)
+display \x009c 1358 #LATIN SMALL LIGATURE OE (0x9c)
+display \x009d 2567 OPERATING SYSTEM COMMAND
+display \x009e 346 #LATIN SMALL LETTER Z WITH CARON (0x9e)
+display \x009f 2345678 #LATIN CAPITAL LETTER Y WITH DIAERESIS (0x9f)
+display \x00a1 256 INVERTED EXCLAMATION MARK )0xa1)
+display \x00a2 2578 CENT SIGN (0xa2)
+display \x00a3 1238 POUND SIGN (0xa3)
+display \x00a4 2367 CURRENCY SIGN (0xa4)
+display \x00a5 67 YEN SIGN (0xa5)
+display \x00a6 3478 BROKEN BAR (0xa6)
+display \x00a7 578 SECTION SIGN (0xa7)
+display \x00a8 56 DIAERESIS (0xa8)
+display \x00a9 134678 COPYRIGHT SIGN (0xa9)
+display \x00aa 234678 FEMININE ORDINAL INDICATOR (0xaa)
+display \x00ab 57 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK (0xab)
+display \x00ac 34567 NOT SIGN (0xac)
+display \x00ad 378 SOFT HYPHEN (0xad)
+display \x00ae 123578 REGISTERED SIGN (0xae)
+display \x00af 23567 MACRON (0xaf)
+display \x00b0 356 DEGREE SIGN (0xb0)
+display \x00b1 123458 PLUS-MINUS SIGN
+display \x00b2 238 SUPERSCRIPT TWO
+display \x00b3 258 SUPERSCRIPT THREE
+display \x00b4 468 ACUTE ACCENT
+display \x00b5 236 MICRO SIGN
+display \x00b6 1234568 PILCROW SIGN
+display \x00b7 38 MIDDLE DOT
+display \x00b8 4678 CEDILLA
+display \x00b9 28 SUPERSCRIPT ONE
+display \x00ba 12345678 MASCULINE ORDINAL INDICATOR
+display \x00bb 567 RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+display \x00bc 13458 VULGAR FRACTION ONE QUARTER
+display \x00bd 458 VULGAR FRACTION ONE HALF
+display \x00be 3456 VULGAR FRACTION THREE QUARTERS
+display \x00bf 34 INVERTED QUESTION MARK
+display \x00c0 123567 LATIN CAPITAL LETTER A WITH GRAVE
+display \x00c1 1235678 LATIN CAPITAL LETTER A WITH ACUTE
+display \x00c2 1678 LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+display \x00c3 14678 LATIN CAPITAL LETTER A WITH TILDE
+display \x00c4 34578 LATIN CAPITAL LETTER A WITH DIAERESIS
+display \x00c5 167 LATIN CAPITAL LETTER A WITH RING ABOVE
+display \x00c6 3457 LATIN CAPITAL LETTER AE
+display \x00c7 123467 LATIN CAPITAL LETTER C WITH CEDILLA
+display \x00c8 23467 LATIN CAPITAL LETTER E WITH GRAVE
+display \x00c9 1234567 LATIN CAPITAL LETTER E WITH ACUTE
+display \x00ca 1267 LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+display \x00cb 12467 LATIN CAPITAL LETTER E WITH DIAERESIS
+display \x00cc 15678 LATIN CAPITAL LETTER I WITH GRAVE
+display \x00cd 12678 LATIN CAPITAL LETTER I WITH ACUTE
+display \x00ce 1467 LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+display \x00cf 124567 LATIN CAPITAL LETTER I WITH DIAERESIS
+display \x00d0 1345678 LATIN CAPITAL LETTER ETH
+display \x00d1 1245678 LATIN CAPITAL LETTER N WITH TILDE
+display \x00d2 124678 LATIN CAPITAL LETTER O WITH GRAVE
+display \x00d3 34678 LATIN CAPITAL LETTER O WITH ACUTE
+display \x00d4 14567 LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+display \x00d5 145678 LATIN CAPITAL LETTER O WITH TILDE
+display \x00d6 24678 LATIN CAPITAL LETTER O WITH DIAERESIS
+display \x00d7 13468 MULTIPLICATION SIGN
+display \x00d8 2467 LATIN CAPITAL LETTER O WITH STROKE
+display \x00d9 234567 LATIN CAPITAL LETTER U WITH GRAVE
+display \x00da 125678 LATIN CAPITAL LETTER U WITH ACUTE
+display \x00db 1567 LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+display \x00dc 12567 LATIN CAPITAL LETTER U WITH DIAERESIS
+display \x00dd 13478 LATIN CAPITAL LETTER Y WITH ACUTE (infinite?)
+display \x00de 1378 LATIN CAPITAL LETTER THORN
+display \x00df 23468 LATIN SMALL LETTER SHARP S
+display \x00e0 12356 LATIN SMALL LETTER A WITH GRAVE
+display \x00e1 123568 LATIN SMALL LETTER A WITH ACUTE
+display \x00e2 168 LATIN SMALL LETTER A WITH CIRCUMFLEX
+display \x00e3 1468 LATIN SMALL LETTER A WITH TILDE
+display \x00e4 3458 LATIN SMALL LETTER A WITH DIAERESIS
+display \x00e5 16 LATIN SMALL LETTER A WITH RING ABOVE
+display \x00e6 345 LATIN SMALL LETTER AE
+display \x00e7 12346 LATIN SMALL LETTER C WITH CEDILLA
+display \x00e8 2346 LATIN SMALL LETTER E WITH GRAVE
+display \x00e9 123456 LATIN SMALL LETTER E WITH ACUTE
+display \x00ea 126 LATIN SMALL LETTER E WITH CIRCUMFLEX
+display \x00eb 1246 LATIN SMALL LETTER E WITH DIAERESIS
+display \x00ec 1568 LATIN SMALL LETTER I WITH GRAVE
+display \x00ed 1268 LATIN SMALL LETTER I WITH ACUTE
+display \x00ee 146 LATIN SMALL LETTER I WITH CIRCUMFLEX
+display \x00ef 12456 LATIN SMALL LETTER I WITH DIAERESIS
+display \x00f0 134568 LATIN SMALL LETTER ETH
+display \x00f1 124568 LATIN SMALL LETTER N WITH TILDE
+display \x00f2 12468 LATIN SMALL LETTER O WITH GRAVE
+display \x00f3 3468 LATIN SMALL LETTER O WITH ACUTE
+display \x00f4 1456 LATIN SMALL LETTER O WITH CIRCUMFLEX
+display \x00f5 14568 LATIN SMALL LETTER O WITH TILDE
+display \x00f6 2468 LATIN SMALL LETTER O WITH DIAERESIS
+display \x00f7 2568 DIVISION SIGN
+display \x00f8 246 LATIN SMALL LETTER O WITH STROKE
+display \x00f9 23456 LATIN SMALL LETTER U WITH GRAVE
+display \x00fa 12568 LATIN SMALL LETTER U WITH ACUTE
+display \x00fb 156 LATIN SMALL LETTER U WITH CIRCUMFLEX
+display \x00fc 1256 LATIN SMALL LETTER U WITH DIAERESIS
+display \x00fd 1348 LATIN SMALL LETTER Y WITH ACUTE
+display \x00fe 138 LATIN SMALL LETTER THORN
+display \x00ff 234568 LATIN SMALL LETTER Y WITH DIAERESIS
diff --git a/tables/da-dk.dis b/tables/da-dk.dis
new file mode 100644
index 0000000..21e2b2a
--- /dev/null
+++ b/tables/da-dk.dis
@@ -0,0 +1,280 @@
+# Danish 8-dot Computer Braille Table
+#
+# Copyright (C) 2004-2008 ViewPlus Technologies, Inc. www.viewplus.com
+# Copyright (C) 2004-2006 JJB Software, Inc. www.jjb-software.com
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# by Mike Sivill - <mike.sivill@viewplustechnologies.com>
+
+#**** Display Codes
+display \s 0
+display \x0000 8 # space marker
+display \x0001 178
+display \x0002 1278
+display \x0003 1478
+display \x0004 14578
+display \x0005 24568
+display \x0006 12478
+display \x0007 124578
+display \x0008 12578
+display \x0009 2478
+display \x000A 678
+display \x000B 1368
+display \x000C 12378
+display \x000D 257
+display \x000E 134578
+display \x000F 12358
+display \x0010 123478
+display \x0011 1234578
+display \x0012 13568
+display \x0013 4578
+display \x0014 268
+display \x0015 13678
+display \x0016 278
+display \x0017 3578
+display \x0018 78
+display \x0019 68
+display \x001A 135678
+display \x001B 2678
+display \x001C 45678
+display \x001D 12368
+display \x001E 1234678
+display \x001F 235678
+display \x0020 2356
+display \x0021 235 # !
+display \x0022 2356 # Quote marks
+display \x0023 34568 # Number hash mark
+display \x0024 25678 # $
+display \x0025 24578
+display \x0026 123468
+display \x0027 4 # Apostrophe
+display \x0028 2368 # left paren
+display \x0029 3568 # right paren
+display \x002A 35 # *
+display \x002B 2358 # +
+display \x002C 2 # ,
+display \x002D 368 # -
+display \x002E 3 # .
+display \x002F 348 # /
+display \x0030 2458 # zero
+display \x0031 18 # one
+display \x0032 128 # two
+display \x0033 148 # three
+display \x0034 1458 $ four
+display \x0035 168 $ five
+display \x0036 1248 # six
+display \x0037 12458 # seven
+display \x0038 125 # eight
+display \x0039 24 # nine
+display \x003A 25 # colon
+display \x003B 23 # semicolon
+display \x003C 358 # less than
+display \x003D 23568 # equals
+display \x003E 267 # greater than
+display \x003F 26 # question mark
+display \x0040 478 # at sign
+display \x0041 17 # A
+display \x0042 127 # B
+display \x0043 147 # C
+display \x0044 145 # D
+display \x0045 157 # E
+display \x0046 1247 # F
+display \x0047 12457 # G
+display \x0048 1257 # H
+display \x0049 247 # I
+display \x004A 2457 # J
+display \x004B 137 # K
+display \x004C 1237 # L
+display \x004D 1347 # M
+display \x004E 13457 # N
+display \x004F 1357 # O
+display \x0050 12347 # P
+display \x0051 123457 # Q
+display \x0052 12357 # R
+display \x0053 2347 # S
+display \x0054 23457 # T
+display \x0055 1367 # U
+display \x0056 12367 # V
+display \x0057 24567 # W
+display \x0058 13467 # X
+display \x0059 134567 # Y
+display \x005A 13567 # Z
+display \x005B 23678 # left bracket
+display \x005C 347 # backslash
+display \x005D 35678 # right bracket
+display \x005E 12348 # caret
+display \x005F 3678 # underline
+display \x0060 5 # grave accent
+display \x0061 1 # a
+display \x0062 12 # b
+display \x0063 14 # c
+display \x0064 145 # d
+display \x0065 15 # e
+display \x0066 124 # f
+display \x0067 1245 # g
+display \x0068 125 # h
+display \x0069 24 # i
+display \x006A 245 # j
+display \x006B 13 # k
+display \x006C 123 # l
+display \x006D 134 # m
+display \x006E 1345 # n
+display \x006F 135 # o
+display \x0070 1234 # p
+display \x0071 12345 # q
+display \x0072 1235 # r
+display \x0073 234 # s
+display \x0074 2345 # t
+display \x0075 136 # u
+display \x0076 1236 # v
+display \x0077 2456 # w
+display \x0078 1346 # x
+display \x0079 13456 # y
+display \x007A 1345 # z
+display \x007B 123678 # left brace
+display \x007C 4568 # vertical bar
+display \x007D 345678 # right brace
+display \x007E 467 # tilde
+display \x007F 7 # del
+display \x20AC 1578 # euros
+display \x201A 457 # unknown
+display \x0192 58 # florin
+display \x201E 2378 # unknown
+display \x2026 6 # elipsis
+display \x2020 2357 # single dagger
+display \x2021 23578 # double dagger
+display \x02C6 5678 # unknown
+display \x2030 245678 # unknown
+display \x0260 23478 # unknown
+display \x2039 456 # unknown
+display \x0152 13578 # OE
+display \x017D 3467 # unknown
+display \x2018 47 # unknown apostrophe?
+display \x2019 48 # unknown apostrophe?
+display \x201C 237 # open double quote
+display \x201D 568 # close double quote
+display \x2022 37 # bullet
+display \x2013 36 # en dash
+display \x2014 367 # em dash
+display \x20DC 46 # tilde?
+display \x2122 234578 # trademark
+display \x0161 2348 # unknown
+display \x203A 4567 # unknown
+display \x0153 1358 # oe
+display \x017E 346 # unknown
+display \x0178 2345678 # unknown
+display \x00A0 0 # space
+display \x00A1 256 # inverted exclaim
+display \x00A2 2578 # cent sign
+display \x00A3 1238 # pounds sterling
+display \x00A4 2367 # ham (ng)
+display \x00A5 67 # yen
+display \x00A6 3478 # broken bar
+display \x00A7 578 # section
+display \x00A8 56 # diamond bullet
+display \x00A9 134678 # copyright
+display \x00AA 234678 # superscript a
+display \x00AB 57 # left double angle bracket
+display \x00AC 34567 # optional hyphen
+display \x00AD 378 # unknown
+display \x00AE 123567 # registered
+display \x00AF 23567 # macron
+display \x00B0 356 # degrees
+display \x00B1 123458 # plus or minus
+display \x00B2 238 # superscript 2
+display \x00B3 258 # superscript 3
+display \x00B4 468 # unknown
+display \x00B5 236 # greek letter mu
+display \x00B6 1234568 # paragraph
+display \x00B7 38 # space marker
+display \x00B8 4678 # cedilla
+display \x00B9 28 # superscript 1
+display \x00bA 12345678 # degrees
+display \x00bB 567 # right double angle bracket
+display \x00bC 13458 # one-fourth
+display \x00bD 458 # one-half
+display \x00bE 3456 # three-fourths
+display \x00bF 34 # inverted question
+display \x00C0 123567 # a grave
+display \x00C1 1235678 # a acute
+display \x00C2 1678 # a circumflex
+display \x00C3 14678 # a tilde
+display \x00C4 34578 # a umlaut
+display \x00C5 167 # A
+display \x00C6 3457 # AE
+display \x00C7 123467 # c cedilla
+display \x00C8 23467 # e grave
+display \x00C9 1234567 # e acute
+display \x00CA 1267 # e circumflex
+display \x00CB 12467 # e umlaut
+display \x00CC 15678 # i grave
+display \x00CD 12678 # i acute
+display \x00CE 1467 # i circumflex
+display \x00CF 124567 # i umlaut
+display \x00D0 1345678 # eth
+display \x00D1 1245678 # any
+display \x00D2 124678 # o grave
+display \x00D3 34678 # o acute
+display \x00D4 14567 # o circumflex
+display \x00D5 145678 # o tilde
+display \x00D6 24678 # o umlaut
+display \x00D7 13468 # times
+display \x00D8 2467 # O
+display \x00D9 234567 # u grave
+display \x00DA 125678 # u acute
+display \x00DB 1567 # u circumflex
+display \x00DC 12567 # u umlaut
+display \x00DD 13478 # y acute
+display \x00DE 1378 # arrow bullet
+display \x00DF 23468 # s-zet
+display \x00E0 12356 # lc a grave
+display \x00E1 123568 # lc a acute
+display \x00E2 168 # lc a circumflex
+display \x00E3 1468 # lc a tilde
+display \x00E4 3458 # lc a umlaut
+display \x00E5 16 # lc a
+display \x00E6 345 # lc ae
+display \x00E7 12346 # lc c cedilla
+display \x00E8 2346 # lc e grave
+display \x00E9 123456 # lc e acute
+display \x00EA 126 # lc e circumflex
+display \x00EB 1246 # lc e umlaut
+display \x00EC 1568 # lc i grave
+display \x00ED 1268 # lc i acute
+display \x00EE 146 # lc i circumflex
+display \x00EF 12456 # lc i umlaut
+display \x00F0 134568 # lc eth
+display \x00F1 124568 # lc any
+display \x00F2 12468 # lc o grave
+display \x00F3 3468 # lc o acute
+display \x00F4 1456 # lc o circumflex
+display \x00F5 14568 # lc o tilde
+display \x00F6 2468 # lc o umlaut
+display \x00F7 2568 # divided by
+display \x00F8 246 # lc o
+display \x00F9 23456 # lc u grave
+display \x00FA 12568 # lc u acute
+display \x00FB 156 # lc u circumflex
+display \x00FC 1256 # lc u umlaut
+display \x00FD 1348 # y acute
+display \x00FE 138 # thorn
+display \x00FF 234568 # unknown
+display \x0081 45 # unknown
+display \x008D 3567 # unknown
+display \x008F 27 # Oplosningstegn
+display \x0090 357 # unknown
diff --git a/tables/da-lt.ctb b/tables/da-lt.ctb
new file mode 100644
index 0000000..db2e1cf
--- /dev/null
+++ b/tables/da-lt.ctb
@@ -0,0 +1,273 @@
+#
+# Copyright (C) 1995-2008 by The BRLTTY Developers.
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# BRLTTY Text Table - Danish LogText (iso-8859-1)
+
+# Danish LogText users are accustomed to the percent sign (%) and the
+# exclamation point (!) being mapped to patterns which differ from the new 1252
+# standard. LogText users will be more comfortable with this table.
+
+# generated by ttbtest
+letter \x0000 12345678 NULL
+letter \x0001 178 START OF HEADING
+letter \x0002 1278 START OF TEXT
+letter \x0003 1478 END OF TEXT
+letter \x0004 14578 END OF TRANSMISSION
+letter \x0005 1578 ENQUIRY
+letter \x0006 12478 ACKNOWLEDGE
+letter \x0007 124578 BELL
+letter \x0008 12578 BACKSPACE
+space \t 2478 CHARACTER TABULATION
+space \n 24578 LINE FEED (LF)
+space \v 1378 LINE TABULATION
+space \f 12378 FORM FEED (FF)
+space \r 13478 CARRIAGE RETURN (CR)
+letter \x000e 134578 SHIFT OUT
+letter \x000f 13578 SHIFT IN
+letter \x0010 123478 DATA LINK ESCAPE
+letter \x0011 1234578 DEVICE CONTROL ONE
+letter \x0012 123578 DEVICE CONTROL TWO
+letter \x0013 23478 DEVICE CONTROL THREE
+letter \x0014 234578 DEVICE CONTROL FOUR
+letter \x0015 13678 NEGATIVE ACKNOWLEDGE
+letter \x0016 123678 SYNCHRONOUS IDLE
+letter \x0017 245678 END OF TRANSMISSION BLOCK
+letter \x0018 134678 CANCEL
+letter \x0019 1345678 END OF MEDIUM
+letter \x001a 135678 SUBSTITUTE
+letter \x001b 34578 ESCAPE
+letter \x001c 45678 INFORMATION SEPARATOR FOUR
+letter \x001d 278 INFORMATION SEPARATOR THREE
+letter \x001e 1234678 INFORMATION SEPARATOR TWO
+letter \x001f 235678 INFORMATION SEPARATOR ONE
+space \s 0 SPACE
+punctuation ! 56 EXCLAMATION MARK
+punctuation " 2356 QUOTATION MARK
+punctuation # 34568 NUMBER SIGN
+punctuation $ 1568 DOLLAR SIGN
+punctuation % 3568 PERCENT SIGN
+punctuation & 123468 AMPERSAND
+punctuation ' 6 APOSTROPHE
+punctuation ( 1268 LEFT PARENTHESIS
+punctuation ) 3458 RIGHT PARENTHESIS
+punctuation * 13468 ASTERISK
+punctuation + 2358 PLUS SIGN
+punctuation , 2 COMMA
+punctuation - 368 HYPHEN-MINUS
+punctuation . 3 FULL STOP
+punctuation / 258 SOLIDUS
+include digits8Dots.uti
+punctuation : 25 COLON
+punctuation ; 23 SEMICOLON
+punctuation < 1348 LESS-THAN SIGN
+punctuation = 23568 EQUALS SIGN
+punctuation > 2348 GREATER-THAN SIGN
+punctuation ? 26 QUESTION MARK
+punctuation @ 478 COMMERCIAL AT
+uppercase A 17 LATIN CAPITAL LETTER A
+uppercase B 127 LATIN CAPITAL LETTER B
+uppercase C 147 LATIN CAPITAL LETTER C
+uppercase D 1457 LATIN CAPITAL LETTER D
+uppercase E 157 LATIN CAPITAL LETTER E
+uppercase F 1247 LATIN CAPITAL LETTER F
+uppercase G 12457 LATIN CAPITAL LETTER G
+uppercase H 1257 LATIN CAPITAL LETTER H
+uppercase I 247 LATIN CAPITAL LETTER I
+uppercase J 2457 LATIN CAPITAL LETTER J
+uppercase K 137 LATIN CAPITAL LETTER K
+uppercase L 1237 LATIN CAPITAL LETTER L
+uppercase M 1347 LATIN CAPITAL LETTER M
+uppercase N 13457 LATIN CAPITAL LETTER N
+uppercase O 1357 LATIN CAPITAL LETTER O
+uppercase P 12347 LATIN CAPITAL LETTER P
+uppercase Q 123457 LATIN CAPITAL LETTER Q
+uppercase R 12357 LATIN CAPITAL LETTER R
+uppercase S 2347 LATIN CAPITAL LETTER S
+uppercase T 23457 LATIN CAPITAL LETTER T
+uppercase U 1367 LATIN CAPITAL LETTER U
+uppercase V 12367 LATIN CAPITAL LETTER V
+uppercase W 24567 LATIN CAPITAL LETTER W
+uppercase X 13467 LATIN CAPITAL LETTER X
+uppercase Y 134567 LATIN CAPITAL LETTER Y
+uppercase Z 13567 LATIN CAPITAL LETTER Z
+punctuation [ 12368 LEFT SQUARE BRACKET
+punctuation \\ 168 REVERSE SOLIDUS
+punctuation ] 14568 RIGHT SQUARE BRACKET
+punctuation ^ 67 CIRCUMFLEX ACCENT
+punctuation _ 78 LOW LINE
+punctuation ` 23567 GRAVE ACCENT
+lowercase a 1 LATIN SMALL LETTER A
+lowercase b 12 LATIN SMALL LETTER B
+lowercase c 14 LATIN SMALL LETTER C
+lowercase d 145 LATIN SMALL LETTER D
+lowercase e 15 LATIN SMALL LETTER E
+lowercase f 124 LATIN SMALL LETTER F
+lowercase g 1245 LATIN SMALL LETTER G
+lowercase h 125 LATIN SMALL LETTER H
+lowercase i 24 LATIN SMALL LETTER I
+lowercase j 245 LATIN SMALL LETTER J
+lowercase k 13 LATIN SMALL LETTER K
+lowercase l 123 LATIN SMALL LETTER L
+lowercase m 134 LATIN SMALL LETTER M
+lowercase n 1345 LATIN SMALL LETTER N
+lowercase o 135 LATIN SMALL LETTER O
+lowercase p 1234 LATIN SMALL LETTER P
+lowercase q 12345 LATIN SMALL LETTER Q
+lowercase r 1235 LATIN SMALL LETTER R
+lowercase s 234 LATIN SMALL LETTER S
+lowercase t 2345 LATIN SMALL LETTER T
+lowercase u 136 LATIN SMALL LETTER U
+lowercase v 1236 LATIN SMALL LETTER V
+lowercase w 2456 LATIN SMALL LETTER W
+lowercase x 1346 LATIN SMALL LETTER X
+lowercase y 13456 LATIN SMALL LETTER Y
+lowercase z 1356 LATIN SMALL LETTER Z
+punctuation { 2468 LEFT CURLY BRACKET
+punctuation | 4568 VERTICAL LINE
+punctuation } 1358 RIGHT CURLY BRACKET
+punctuation ~ 68 TILDE
+letter \x007f 8 DELETE
+letter \x0080 4 <control-0080>
+letter \x0081 45 <control-0081>
+letter \x0082 457 BREAK PERMITTED HERE
+letter \x0083 5 NO BREAK HERE
+letter \x0084 2378 <control-0084>
+letter \x0085 235 NEXT LINE (NEL)
+letter \x0086 2357 START OF SELECTED AREA
+letter \x0087 23578 END OF SELECTED AREA
+letter \x0088 5678 CHARACTER TABULATION SET
+letter \x0089 678 CHARACTER TABULATION WITH JUSTIFICATION
+letter \x008a 2368 LINE TABULATION SET
+letter \x008b 456 PARTIAL LINE FORWARD
+letter \x008c 347 PARTIAL LINE BACKWARD
+letter \x008d 3567 REVERSE LINE FEED
+letter \x008e 3467 SINGLE SHIFT TWO
+letter \x008f 27 SINGLE SHIFT THREE
+letter \x0090 357 DEVICE CONTROL STRING
+letter \x0091 47 PRIVATE USE ONE
+letter \x0092 48 PRIVATE USE TWO
+letter \x0093 237 SET TRANSMIT STATE
+letter \x0094 568 CANCEL CHARACTER
+letter \x0095 37 MESSAGE WAITING
+letter \x0096 36 START OF GUARDED AREA
+letter \x0097 367 END OF GUARDED AREA
+letter \x0098 46 START OF STRING
+letter \x0099 257 <control-0099>
+letter \x009a 34 SINGLE CHARACTER INTRODUCER
+letter \x009b 4567 CONTROL SEQUENCE INTRODUCER
+letter \x009c 467 STRING TERMINATOR
+letter \x009d 23458 OPERATING SYSTEM COMMAND
+letter \x009e 346 PRIVACY MESSAGE
+letter \x009f 2345678 APPLICATION PROGRAM COMMAND
+punctuation \x00a0 0 NO-BREAK SPACE
+punctuation \x00a1 256 INVERTED EXCLAMATION MARK
+punctuation \x00a2 2578 CENT SIGN
+punctuation \x00a3 1238 POUND SIGN
+punctuation \x00a4 2367 CURRENCY SIGN
+punctuation \x00a5 25678 YEN SIGN
+punctuation \x00a6 3478 BROKEN BAR
+punctuation \x00a7 578 SECTION SIGN
+punctuation \x00a8 23678 DIAERESIS
+punctuation \x00a9 345678 COPYRIGHT SIGN
+letter \x00aa 234678 FEMININE ORDINAL INDICATOR
+punctuation \x00ab 57 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+punctuation \x00ac 34567 NOT SIGN
+punctuation \x00ad 378 SOFT HYPHEN
+punctuation \x00ae 4578 REGISTERED SIGN
+punctuation \x00af 267 MACRON
+punctuation \x00b0 356 DEGREE SIGN
+punctuation \x00b1 123458 PLUS-MINUS SIGN
+punctuation \x00b2 238 SUPERSCRIPT TWO
+punctuation \x00b3 12348 SUPERSCRIPT THREE
+punctuation \x00b4 468 ACUTE ACCENT
+lowercase \x00b5 236 MICRO SIGN
+punctuation \x00b6 1234568 PILCROW SIGN
+punctuation \x00b7 38 MIDDLE DOT
+punctuation \x00b8 4678 CEDILLA
+punctuation \x00b9 28 SUPERSCRIPT ONE
+letter \x00ba 7 MASCULINE ORDINAL INDICATOR
+punctuation \x00bb 567 RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+punctuation \x00bc 13458 VULGAR FRACTION ONE QUARTER
+punctuation \x00bd 458 VULGAR FRACTION ONE HALF
+punctuation \x00be 3456 VULGAR FRACTION THREE QUARTERS
+punctuation \x00bf 348 INVERTED QUESTION MARK
+uppercase \x00c0 123567 LATIN CAPITAL LETTER A WITH GRAVE
+uppercase \x00c1 1235678 LATIN CAPITAL LETTER A WITH ACUTE
+uppercase \x00c2 1678 LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+uppercase \x00c3 14678 LATIN CAPITAL LETTER A WITH TILDE
+uppercase \x00c4 358 LATIN CAPITAL LETTER A WITH DIAERESIS
+uppercase \x00c5 167 LATIN CAPITAL LETTER A WITH RING ABOVE
+uppercase \x00c6 3457 LATIN CAPITAL LETTER AE
+uppercase \x00c7 123467 LATIN CAPITAL LETTER C WITH CEDILLA
+uppercase \x00c8 23467 LATIN CAPITAL LETTER E WITH GRAVE
+uppercase \x00c9 1234567 LATIN CAPITAL LETTER E WITH ACUTE
+uppercase \x00ca 1267 LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+uppercase \x00cb 12467 LATIN CAPITAL LETTER E WITH DIAERESIS
+uppercase \x00cc 15678 LATIN CAPITAL LETTER I WITH GRAVE
+uppercase \x00cd 12678 LATIN CAPITAL LETTER I WITH ACUTE
+uppercase \x00ce 1467 LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+uppercase \x00cf 124567 LATIN CAPITAL LETTER I WITH DIAERESIS
+uppercase \x00d0 35678 LATIN CAPITAL LETTER ETH
+uppercase \x00d1 1245678 LATIN CAPITAL LETTER N WITH TILDE
+uppercase \x00d2 124678 LATIN CAPITAL LETTER O WITH GRAVE
+uppercase \x00d3 34678 LATIN CAPITAL LETTER O WITH ACUTE
+uppercase \x00d4 14567 LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+uppercase \x00d5 145678 LATIN CAPITAL LETTER O WITH TILDE
+uppercase \x00d6 24678 LATIN CAPITAL LETTER O WITH DIAERESIS
+punctuation \x00d7 13568 MULTIPLICATION SIGN
+uppercase \x00d8 2467 LATIN CAPITAL LETTER O WITH STROKE
+uppercase \x00d9 234567 LATIN CAPITAL LETTER U WITH GRAVE
+uppercase \x00da 125678 LATIN CAPITAL LETTER U WITH ACUTE
+uppercase \x00db 1567 LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+uppercase \x00dc 12567 LATIN CAPITAL LETTER U WITH DIAERESIS
+uppercase \x00dd 3578 LATIN CAPITAL LETTER Y WITH ACUTE
+uppercase \x00de 2678 LATIN CAPITAL LETTER THORN
+lowercase \x00df 23468 LATIN SMALL LETTER SHARP S
+lowercase \x00e0 12356 LATIN SMALL LETTER A WITH GRAVE
+lowercase \x00e1 123568 LATIN SMALL LETTER A WITH ACUTE
+lowercase \x00e2 268 LATIN SMALL LETTER A WITH CIRCUMFLEX
+lowercase \x00e3 1468 LATIN SMALL LETTER A WITH TILDE
+lowercase \x00e4 58 LATIN SMALL LETTER A WITH DIAERESIS
+lowercase \x00e5 16 LATIN SMALL LETTER A WITH RING ABOVE
+lowercase \x00e6 345 LATIN SMALL LETTER AE
+lowercase \x00e7 12346 LATIN SMALL LETTER C WITH CEDILLA
+lowercase \x00e8 2346 LATIN SMALL LETTER E WITH GRAVE
+lowercase \x00e9 123456 LATIN SMALL LETTER E WITH ACUTE
+lowercase \x00ea 126 LATIN SMALL LETTER E WITH CIRCUMFLEX
+lowercase \x00eb 1246 LATIN SMALL LETTER E WITH DIAERESIS
+lowercase \x00ec 3678 LATIN SMALL LETTER I WITH GRAVE
+lowercase \x00ed 1368 LATIN SMALL LETTER I WITH ACUTE
+lowercase \x00ee 146 LATIN SMALL LETTER I WITH CIRCUMFLEX
+lowercase \x00ef 12456 LATIN SMALL LETTER I WITH DIAERESIS
+lowercase \x00f0 134568 LATIN SMALL LETTER ETH
+lowercase \x00f1 124568 LATIN SMALL LETTER N WITH TILDE
+lowercase \x00f2 12468 LATIN SMALL LETTER O WITH GRAVE
+lowercase \x00f3 3468 LATIN SMALL LETTER O WITH ACUTE
+lowercase \x00f4 1456 LATIN SMALL LETTER O WITH CIRCUMFLEX
+lowercase \x00f5 12358 LATIN SMALL LETTER O WITH TILDE
+lowercase \x00f6 35 LATIN SMALL LETTER O WITH DIAERESIS
+punctuation \x00f7 2568 DIVISION SIGN
+lowercase \x00f8 246 LATIN SMALL LETTER O WITH STROKE
+lowercase \x00f9 23456 LATIN SMALL LETTER U WITH GRAVE
+lowercase \x00fa 12568 LATIN SMALL LETTER U WITH ACUTE
+lowercase \x00fb 156 LATIN SMALL LETTER U WITH CIRCUMFLEX
+lowercase \x00fc 1256 LATIN SMALL LETTER U WITH DIAERESIS
+lowercase \x00fd 24568 LATIN SMALL LETTER Y WITH ACUTE
+lowercase \x00fe 138 LATIN SMALL LETTER THORN
+lowercase \x00ff 234568 LATIN SMALL LETTER Y WITH DIAERESIS
diff --git a/tables/de-accents-detailed.cti b/tables/de-accents-detailed.cti
new file mode 100644
index 0000000..baa1418
--- /dev/null
+++ b/tables/de-accents-detailed.cti
@@ -0,0 +1,38 @@
+# liblouis: Letters with accents (without ä ö ü) - detailed representation of french and italian accents
+#
+# Copyright (C) 2018 SBS Schweizerische Bibliothek für Blinde, Seh- und Lesebehinderte
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#-------------------------------------------------------------------------------
+
+uplow \x00C0\x00E0 4-12356 Àà Àà LATIN LETTER A WITH GRAVE
+uplow \x00C2\x00E2 4-16 Ââ Ââ LATIN LETTER A WITH CIRCUMFLEX
+uplow \x00C7\x00E7 4-12346 Çç Çç LATIN LETTER C WITH CEDILLA
+uplow \x00C8\x00E8 4-2346 Èè Èè LATIN LETTER E WITH GRAVE
+uplow \x00C9\x00E9 4-123456 Éé Éé LATIN LETTER E WITH ACUTE
+uplow \x00CA\x00EA 4-126 Êê Êê LATIN LETTER E WITH CIRCUMFLEX
+uplow \x00CB\x00EB 4-1246 Ëë Ëë LATIN LETTER E WITH DIAERESIS
+uplow \x00CC\x00EC 4-34 Ìì Ìì LATIN LETTER I WITH GRAVE
+uplow \x00CE\x00EE 4-146 Îî Îî LATIN LETTER I WITH CIRCUMFLEX
+uplow \x00CF\x00EF 4-12456 Ïï Ïï LATIN LETTER I WITH DIAERESIS
+uplow \x00D2\x00F2 4-346 Òò Òò LATIN LETTER O WITH GRAVE
+uplow \x00D4\x00F4 4-1456 Ôô Ôô LATIN LETTER O WITH CIRCUMFLEX
+uplow \x00D9\x00F9 4-23456 Ùù Ùù LATIN LETTER U WITH GRAVE
+uplow \x00DB\x00FB 4-156 Ûû Ûû LATIN LETTER U WITH CIRCUMFLEX
+uplow \x0152\x0153 4-246 Œœ Œœ LATIN LIGATURE OE
+
diff --git a/tables/de-accents.cti b/tables/de-accents.cti
new file mode 100644
index 0000000..415d325
--- /dev/null
+++ b/tables/de-accents.cti
@@ -0,0 +1,117 @@
+# liblouis: Letters with accents (without ä ö ü)
+#
+# Copyright (C) 2018 SBS Schweizerische Bibliothek für Blinde, Seh- und Lesebehinderte
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#-------------------------------------------------------------------------------
+
+uplow \x00C0\x00E0 4-1 Àà Àà LATIN LETTER A WITH GRAVE
+uplow \x00C1\x00E1 4-1 Áá Áá LATIN LETTER A WITH ACUTE
+uplow \x00C2\x00E2 4-1 Ââ Ââ LATIN LETTER A WITH CIRCUMFLEX
+uplow \x00C3\x00E3 4-1 Ãã Ãã LATIN LETTER A WITH TILDE
+uplow \x00C5\x00E5 4-1 Åå Åå LATIN LETTER A WITH RING ABOVE
+uplow \x00C6\x00E6 1-15 Ææ Ææ LATIN LETTER AE
+uplow \x00C7\x00E7 4-14 Çç Çç LATIN LETTER C WITH CEDILLA
+uplow \x00C8\x00E8 4-15 Èè Èè LATIN LETTER E WITH GRAVE
+uplow \x00C9\x00E9 4-15 Éé Éé LATIN LETTER E WITH ACUTE
+uplow \x00CA\x00EA 4-15 Êê Êê LATIN LETTER E WITH CIRCUMFLEX
+uplow \x00CB\x00EB 4-15 Ëë Ëë LATIN LETTER E WITH DIAERESIS
+uplow \x00CC\x00EC 4-24 Ìì Ìì LATIN LETTER I WITH GRAVE
+uplow \x00CD\x00ED 4-24 Íí Íí LATIN LETTER I WITH ACUTE
+uplow \x00CE\x00EE 4-24 Îî Îî LATIN LETTER I WITH CIRCUMFLEX
+uplow \x00CF\x00EF 4-24 Ïï Ïï LATIN LETTER I WITH DIAERESIS
+uplow \x00D0\x00F0 4-145 Ðð Ðð LATIN LETTER ETH
+uplow \x00D1\x00F1 4-1345 Ññ Ññ LATIN LETTER N WITH TILDE
+uplow \x00D2\x00F2 4-135 Òò Òò LATIN LETTER O WITH GRAVE
+uplow \x00D3\x00F3 4-135 Óó Óó LATIN LETTER O WITH ACUTE
+uplow \x00D4\x00F4 4-135 Ôô Ôô LATIN LETTER O WITH CIRCUMFLEX
+uplow \x00D5\x00F5 4-135 Õõ Õõ LATIN LETTER O WITH TILDE
+uplow \x00D8\x00F8 4-135 Øø Øø LATIN LETTER O WITH STROKE
+uplow \x00D9\x00F9 4-136 Ùù Ùù LATIN LETTER U WITH GRAVE
+uplow \x00DA\x00FA 4-136 Úú Úú LATIN LETTER U WITH ACUTE
+uplow \x00DB\x00FB 4-136 Ûû Ûû LATIN LETTER U WITH CIRCUMFLEX
+uplow \x00DD\x00FD 4-13456 Ýý Ýý LATIN LETTER Y WITH ACUTE
+uplow \x00DE\x00FE 4-2345 Þþ Þþ LATIN LETTER THORN
+uplow \x0178\x00FF 4-13456 Ÿÿ ÿŸ LATIN LETTER Y WITH DIAERESIS
+uplow \x0152\x0153 135-15 Œœ Œœ LATIN LIGATURE OE
+
+uplow \x0100\x0101 4-1 Āā Āā LATIN LETTER A WITH MACRON
+uplow \x0102\x0103 4-1 Ăă Ăă LATIN LETTER A WITH BREVE
+uplow \x0104\x0105 4-1 Ąą Ąą LATIN LETTER A WITH OGONEK
+uplow \x0106\x0107 4-14 Ćć Ćć LATIN LETTER C WITH ACUTE
+uplow \x0108\x0109 4-14 Ĉĉ Ĉĉ LATIN LETTER C WITH CIRCUMFLEX
+uplow \x010A\x010B 4-14 Ċċ Ċċ LATIN LETTER C WITH DOT ABOVE
+uplow \x010C\x010D 4-14 Čč Čč LATIN LETTER C WITH CARON
+uplow \x010E\x010F 4-145 Ďď Ďď LATIN LETTER D WITH CARON
+uplow \x0110\x0111 4-145 Đđ Đđ LATIN LETTER D WITH STROKE
+uplow \x0112\x0113 4-15 Ēē Ēē LATIN LETTER E WITH MACRON
+uplow \x0116\x0117 4-15 Ėė Ėė LATIN LETTER E WITH DOT ABOVE
+uplow \x0118\x0119 4-15 Ęę Ęę LATIN LETTER E WITH OGONEK
+uplow \x011A\x011B 4-15 Ěě Ěě LATIN LETTER E WITH CARON
+uplow \x011E\x011F 4-1245 Ğğ Ğğ LATIN LETTER G WITH BREVE
+uplow \x0122\x0123 4-1245 Ģģ Ģģ LATIN LETTER G WITH CEDILLA
+uplow \x0124\x0125 4-125 Ĥĥ Ĥĥ LATIN LETTER H WITH CIRCUMFLEX
+uplow \x0126\x0127 4-125 Ħħ Ħħ LATIN LETTER H WITH STROKE
+uplow \x0128\x0129 4-24 Ĩĩ Ĩĩ LATIN LETTER I WITH TILDE
+uplow \x012A\x012B 4-24 Īī Īī LATIN LETTER I WITH MACRON
+uplow \x012E\x012F 4-24 Įį Įį LATIN LETTER I WITH OGONEK
+uplow \x0130\x0131 4-24 İı İı LATIN CAPITAL LETTER I WITH DOT ABOVE - LATIN SMALL LETTER DOTLESS I
+uplow \x0132\x0133 4-245 IJij IJij LATIN LIGATURE IJ
+uplow \x0134\x0135 4-245 Ĵĵ Ĵĵ LATIN LETTER J WITH CIRCUMFLEX
+uplow \x0136\x0137 4-13 Ķķ Ķķ LATIN LETTER K WITH CEDILLA
+uplow \x0139\x013A 4-123 Ĺĺ Ĺĺ LATIN LETTER L WITH ACUTE
+uplow \x013B\x013C 4-123 Ļļ Ļļ LATIN LETTER L WITH CEDILLA
+uplow \x013D\x013E 4-123 Ľľ Ľľ LATIN LETTER L WITH CARON
+uplow \x013F\x0140 4-123 Ŀŀ Ŀŀ LATIN LETTER L WITH MIDDLE DOT
+uplow \x0141\x0142 4-123 Łł Łł LATIN LETTER L WITH STROKE
+uplow \x0143\x0144 4-1345 Ńń Ńń LATIN LETTER N WITH ACUTE
+uplow \x0145\x0146 4-1345 Ņņ Ņņ LATIN LETTER N WITH CEDILLA
+uplow \x0147\x0148 4-1345 Ňň Ňň LATIN LETTER N WITH CARON
+uplow \x014A\x014B 4-1345 Ŋŋ Ŋŋ LATIN LETTER ENG
+uplow \x014C\x014D 4-135 Ōō Ōō LATIN LETTER O WITH MACRON
+uplow \x014E\x014F 4-135 Ŏŏ Ŏŏ LATIN LETTER O WITH BREVE
+uplow \x0150\x0151 4-135 Őő Őő LATIN LETTER O WITH DOUBLE ACUTE
+uplow \x0154\x0155 4-1235 Ŕŕ Ŕŕ LATIN LETTER R WITH ACUTE
+uplow \x0156\x0157 4-1235 Ŗŗ Ŗŗ LATIN LETTER R WITH CEDILLA
+uplow \x0158\x0159 4-1235 Řř Řř LATIN LETTER R WITH CARON
+uplow \x015A\x015B 4-234 Śś Śś LATIN LETTER S WITH ACUTE
+uplow \x015C\x015D 4-234 Ŝŝ Ŝŝ LATIN LETTER S WITH CIRCUMFLEX
+uplow \x015E\x015F 4-234 Şş Şş LATIN LETTER S WITH CEDILLA
+uplow \x0160\x0161 4-234 Šš Šš LATIN LETTER S WITH CARON
+uplow \x0218\x0219 4-234 Șș LATIN LETTER S WITH COMMA BELOW
+uplow \x0162\x0163 4-2345 Ţţ Ţţ LATIN LETTER T WITH CEDILLA
+uplow \x0164\x0165 4-2345 Ťť Ťť LATIN LETTER T WITH CARON
+uplow \x0166\x0167 4-2345 Ŧŧ Ŧŧ LATIN LETTER T WITH STROKE
+uplow \x021A\x021B 4-2345 Țț LATIN LETTER T WITH COMMA BELOW
+uplow \x0168\x0169 4-136 Ũũ Ũũ LATIN LETTER U WITH TILDE
+uplow \x016A\x016B 4-136 Ūū Ūū LATIN LETTER U WITH MACRON
+uplow \x016C\x016D 4-136 Ŭŭ Ŭŭ LATIN LETTER U WITH BREVE
+uplow \x016E\x016F 4-136 Ůů Ůů LATIN LETTER U WITH RING ABOVE
+uplow \x0170\x0171 4-136 Űű Űű LATIN LETTER U WITH DOUBLE ACUTE
+uplow \x0172\x0173 4-136 Ųų Ųų LATIN LETTER U WITH OGONEK
+uplow \x0174\x0175 4-2456 Ŵŵ Ŵŵ LATIN LETTER W WITH CIRCUMFLEX
+uplow \x0176\x0177 4-13456 Ŷŷ Ŷŷ LATIN LETTER Y WITH CIRCUMFLEX
+uplow \x0179\x017A 4-1356 Źź Źź LATIN LETTER Z WITH ACUTE
+uplow \x017B\x017C 4-1356 Żż Żż LATIN LETTER Z WITH DOT ABOVE
+uplow \x017D\x017E 4-1356 Žž Žž LATIN LETTER Z WITH CARON
+uplow \x01CD\x01CE 4-1 Ǎǎ Ǎǎ LATIN LETTER A WITH CARON
+uplow \x1E80\x1E81 4-2456 Ẁẁ Ẁẁ LATIN LETTER W WITH GRAVE
+uplow \x1E82\x1E83 4-2456 Ẃẃ Ẃẃ LATIN LETTER W WITH ACUTE
+uplow \x1E84\x1E85 4-2456 Ẅẅ Ẅẅ LATIN LETTER W WITH DIAERESIS
+uplow \x1EF2\x1EF3 4-13456 Ỳỳ Ỳỳ LATIN LETTER Y WITH GRAVE
+
diff --git a/tables/de-chardefs6.cti b/tables/de-chardefs6.cti
new file mode 100644
index 0000000..a688322
--- /dev/null
+++ b/tables/de-chardefs6.cti
@@ -0,0 +1,279 @@
+# liblouis: Character definitions for german tables
+#
+# Copyright (C) 2018 SBS Schweizerische Bibliothek für Blinde, Seh- und Lesebehinderte
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#-------------------------------------------------------------------------------
+
+space \x00a0 a
+include spaces.uti
+
+# ===== BASIC LATIN - 0000-007F ================================================
+
+punctuation \x0021 5 #33 ! EXCLAMATION MARK
+punctuation \x0022 4 #34 " QUOTATION MARK
+sign \x0023 3456 #35 # NUMBER SIGN
+sign \x0024 46 #36 $ DOLLAR SIGN
+sign \x0025 123456 #37 % PERCENT SIGN
+sign \x0026 12346 #38 & AMPERSAND
+punctuation \x0027 6 #39 ' APOSTROPHE APOSTROPHE-QUOTE
+lowercase \x0027 6 #39 ' APOSTROPHE APOSTROPHE-QUOTE # doesn't work with letter!
+punctuation \x0028 236 #40 ( LEFT PARENTHESIS
+punctuation \x0029 356 #41 ) RIGHT PARENTHESIS
+punctuation \x002A 35 #42 * ASTERISK
+math \x002B 235 #43 + PLUS SIGN
+punctuation \x002C 2 #44 , COMMA
+punctuation \x002D 36 #45 - HYPHEN-MINUS
+punctuation \x002E 3 #46 . FULL STOP PERIOD
+punctuation \x002F 256 #47 / SOLIDUS SLASH
+
+include digits6DotsPlusDot6.uti
+
+punctuation \x003A 25 #58 : COLON
+punctuation \x003B 23 #59 ; SEMICOLON
+math \x003C 56 #60 < LESS-THAN SIGN
+math \x003D 2356 #61 = EQUALS SIGN
+math \x003E 45 #62 > GREATER-THAN SIGN
+punctuation \x003F 26 #63 ? QUESTION MARK
+
+include latinLetterDef6Dots.uti
+
+sign \x0060 345 #96 ` GRAVE ACCENT
+punctuation \x007B 12356 #123 { LEFT CURLY BRACKET
+sign \x007C 34 #124 | VERTICAL LINE
+punctuation \x007D 23456 #125 } RIGHT CURLY BRACKET
+sign \x007E 2346 #126 ~ TILDE
+sign \x007F 456 #127 [DELETE]
+
+sign \x0040 4-345 #64 @ COMMERCIAL AT
+punctuation \x005B 6-2356 #91 [ LEFT SQUARE BRACKET
+sign \x005C 4-34 #92 \ REVERSE SOLIDUS
+punctuation \x005D 6-2356 #93 ] RIGHT SQUARE BRACKET
+sign \x005E 4-2346 #94 ^ CIRCUMFLEX ACCENT
+sign \x005F 4-456 #95 _ LOW LINE
+
+# ===== LATIN-1 SUPPLEMENT: 0080-00FF ==========================================
+
+punctuation \x00A1 6-235 #161 ¡ INVERTED EXCLAMATION MARK
+sign \x00A2 4-14 #162 ¢ CENT SIGN
+sign \x00A3 4-123 #163 £ POUND SIGN
+sign \x00A4 0 #164 ¤ CURRENCY SIGN
+sign \x00A5 4-13456 #165 ¥ YEN SIGN
+sign \x00A6 5-36 #166 ¦ BROKEN BAR
+sign \x00A7 346 #167 § SECTION SIGN
+sign \x00A8 0 #168 ¨ DIAERESIS
+sign \x00A9 2356-45-14-2356 #169 © COPYRIGHT SIGN
+lowercase \x00AA 1 #170 ª FEMININE ORDINAL INDICATOR
+punctuation \x00AB 236 #171 « LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+sign \x00AC 0 #172 ¬ NOT SIGN
+sign \x00AD 0 #173 SOFT HYPHEN
+sign \x00AE 6-2356-45-1235-2356 #174 ® REGISTERED SIGN
+sign \x00AF 0 #175 ¯ MACRON
+sign \x00B0 4-356 #176 ° DEGREE SIGN
+math \x00B1 235-36 #177 ± PLUS-MINUS SIGN
+sign \x00B2 34-23 #178 ² SUPERSCRIPT TWO
+sign \x00B3 34-25 #179 ³ SUPERSCRIPT THREE
+sign \x00B4 0 #180 ´ ACUTE ACCENT
+sign \x00B5 56-134 #181 µ MICRO SIGN
+sign \x00B6 0 #182 ¶ PILCROW SIGN
+sign \x00B7 0 #183 · MIDDLE DOT
+sign \x00B8 0 #184 ¸ CEDILLA
+sign \x00B9 0 #185 ¹ SUPERSCRIPT ONE
+lowercase \x00BA 135 #186 º MASCULINE ORDINAL INDICATOR
+punctuation \x00BB 356 #187 » RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+math \x00BC 3456-1-256 #188 ¼ VULGAR FRACTION ONE QUARTER
+math \x00BD 3456-1-23 #189 ½ VULGAR FRACTION ONE HALF
+math \x00BE 3456-14-256 #190 ¾ VULGAR FRACTION THREE QUARTERS
+punctuation \x00BF 6-26 #191 ¿ INVERTED QUESTION MARK
+uplow \x00C4\x00E4 345 #196 #228 Ää LATIN CAPITAL LETTER A WITH DIAERESIS
+uplow \x00D6\x00F6 246 #214 #246 Öö LATIN CAPITAL LETTER O WITH DIAERESIS
+math \x00D7 236 #215 × MULTIPLICATION SIGN
+uplow \x00DC\x00FC 1256 #220 #252 Üü LATIN CAPITAL LETTER U WITH DIAERESIS
+uplow \x1e9e\x00DF 2346 #223 ß LATIN SMALL LETTER SHARP S
+math \x00F7 0 #247 ÷ DIVISION SIGN
+
+# ===== GENERAL PUNCTUATION: 2000-206F =========================================
+
+punctuation \x2013 6-36 #8211 EN DASH
+punctuation \x2014 6-36 #8212 EM DASH
+punctuation \x2018 6-236 #8216 LEFT SINGLE QUOTATION MARK
+punctuation \x2019 6-356 #8217 RIGHT SINGLE QUOTATION MARK
+punctuation \x201A 6-236 #8218 SINGLE LOW-9 QUOTATION MARK
+punctuation \x201B 6-356 #8219 SINGLE HIGH-REVERSED-9 QUOTATION MARK
+punctuation \x201C 236 #8220 LEFT DOUBLE QUOTATION MARK
+punctuation \x201D 356 #8221 RIGHT DOUBLE QUOTATION MARK
+punctuation \x201E 236 #8222 DOUBLE LOW-9 QUOTATION MARK
+punctuation \x201F 356 #8223 DOUBLE HIGH-REVERSED-9 QUOTATION MARK
+sign \x2020 4-235 #8224 DAGGER
+sign \x2030 3456-245-356-356 #8240 PER MILLE SIGN
+sign \x2031 3456-245-356-356-356 #8241 PER TEN THOUSAND SIGN
+sign \x2032 4-35 #8242 PRIME
+sign \x2033 4-35-35 #8243 DOUBLE PRIME
+punctuation \x2039 6-236 SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+punctuation \x203a 6-356 SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+
+# ===== CURRENCY SYMBOLS: 20A0-20CF ============================================
+
+sign \x20A0 4-15 #8352 EURO-CURRENCY SIGN
+sign \x20AC 4-15 #8364 EURO SIGN
+
+# ===== LETTERLIKE SYMBOLS 2100-214F ===========================================
+
+sign \x2122 6-2356-45-2345-134-2356 #8482 TRADE MARK SIGN
+
+# ===== NUMBER FORMS: 2150-218F ================================================
+
+math \x2153 3456-1-25 VULGAR FRACTION ONE THIRD
+math \x2154 3456-12-25 VULGAR FRACTION TWO THIRDS
+math \x2155 3456-1-26 VULGAR FRACTION ONE FIFTH
+math \x2156 3456-12-26 VULGAR FRACTION TWO FIFTHS
+math \x2157 3456-14-26 VULGAR FRACTION THREE FIFTHS
+math \x2158 3456-145-26 VULGAR FRACTION FOUR FIFTHS
+math \x2159 3456-1-235 VULGAR FRACTION ONE SIXTH
+math \x215a 3456-15-235 VULGAR FRACTION FIVE SIXTHS
+math \x215b 3456-1-236 VULGAR FRACTION ONE EIGHTH
+math \x215c 3456-14-236 VULGAR FRACTION THREE EIGHTHS
+math \x215d 3456-15-236 VULGAR FRACTION FIVE EIGHTHS
+math \x215e 3456-1245-236 VULGAR FRACTION SEVEN EIGHTHS
+
+# ===== ARROWS: 2190-21FF ======================================================
+
+sign \x2190 0-246-25-25-0 LEFTWARDS ARROW
+sign \x2192 0-25-25-135-0 RIGHTWARDS ARROW
+sign \x2194 0-246-25-25-135-0 LEFT RIGHT ARROW
+
+# ===== MATHEMATICAL OPERATORS: 2200-22FF ======================================
+
+math \x2212 36a #8722 MINUS SIGN
+math \x2215 25 #8725 DIVISION SLASH
+math \x2217 35 #8727 ASTERISK OPERATOR
+math \x223C 25-25 #8764 TILDE OPERATOR
+math \x2245 26-26 #8773 APPROXIMATELY EQUAL TO
+math \x2259 26 #8793 ESTIMATES
+math \x2260 35-2356 #8800 NOT EQUAL TO
+math \x2261 2356-2356 #8801 IDENTICAL TO
+math \x2264 246-2356 #8804 LESS-THAN OR EQUAL TO
+math \x2265 135-2356 #8805 GREATER-THAN OR EQUAL TO
+math \x2266 246-2356 #8806 LESS-THAN OVER EQUAL TO
+math \x2267 135-2356 #8807 GREATER-THAN OVER EQUAL TO
+math \x22c5 3 #8901 DOT OPERATOR
+math \x22c6 3 #8902 STAR OPERATOR
+
+# ===== MISCELLANEOUS TECHNICAL: 2300-23FF =====================================
+
+punctuation \x2329 5-2356 #9001 LEFT-POINTING ANGLE BRACKET
+punctuation \x232a 5-2356 #9002 RIGHT-POINTING ANGLE BRACKET
+
+# ===== MISCELLANEOUS SYMBOLS: 2600-26FF =======================================
+
+sign \x2639 6-46-25-36-236 #9785 WHITE FROWNING FACE
+sign \x263a 6-46-25-36-356 #9786 WHITE SMILING FACE
+
+# ===== SPECIAL PURPOSE CHARACTERS (from BOX DRAWING: 2500-257F) ===============
+
+# KUERZUNGSVERBOT und "DUMMY"-TEXT:
+lowercase \x250A abcdef #9482 BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL
+# "DUMMY"-ZAHL:
+digit \x250B b #9483 BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL
+# GROSSBUCHSTABE (virtual use only):
+sign \x2565 46a #9573 BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+# GROSSBUCHSTABENFOLGE (virtual use only):
+sign \x2567 45a #9575 BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+# ENDE GROSSBUCHSTABENFOLGE (virtual use only):
+sign \x2568 45b #9576 BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+# AUFHEBUNGSPUNKT bei Wort-Zahl-Ausdruecken (grade 2):
+sign \x256C ab #9580 BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+# DOPPELPUNKT bei Zeitangaben:
+sign \x2573 6-25 #9587 BOX DRAWINGS LIGHT DIAGONAL CROSS
+# MARKIERUNG FÜR ZAHL-BUCHSTABE-VERBINDUNG (zum Eliminieren überflüssiger Letter-Signs):
+digit \x2504 ac #9476 BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL
+# APOSTROPH VOR ZAHL (z.B. Im Jahr '97):
+digit \x2500 69 #9472 BOX DRAWINGS LIGHT HORIZONTAL
+# PUNKT VOR ZAHL (z.B. Kaliber .45):
+digit \x2501 39 #9473 BOX DRAWINGS HEAVY HORIZONTAL
+# Strich und Punkt vor Zahl (Fr. --.45):
+digit \x2510 36a-36a-3 #9488 BOX DRAWINGS LIGHT DOWN AND LEFT
+# Strich und Komma vor Zahl (EUR --,45):
+digit \x2511 36a-36a-2 #9489 BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY
+
+# ===== BRAILLE PATTERNS: 2800-28FF ============================================
+
+space \x2800 0 #10240 BRAILLE PATTERN BLANK
+sign \x2801 1 #10241 BRAILLE PATTERN DOTS-1
+sign \x2802 2 #10242 BRAILLE PATTERN DOTS-2
+sign \x2803 12 #10243 BRAILLE PATTERN DOTS-12
+sign \x2804 3 #10244 BRAILLE PATTERN DOTS-3
+sign \x2805 13 #10245 BRAILLE PATTERN DOTS-13
+sign \x2806 23 #10246 BRAILLE PATTERN DOTS-23
+sign \x2807 123 #10247 BRAILLE PATTERN DOTS-123
+sign \x2808 4 #10248 BRAILLE PATTERN DOTS-4
+sign \x2809 14 #10249 BRAILLE PATTERN DOTS-14
+sign \x280a 24 #10250 BRAILLE PATTERN DOTS-24
+sign \x280b 124 #10251 BRAILLE PATTERN DOTS-124
+sign \x280c 34 #10252 BRAILLE PATTERN DOTS-34
+sign \x280d 134 #10253 BRAILLE PATTERN DOTS-134
+sign \x280e 234 #10254 BRAILLE PATTERN DOTS-234
+sign \x280f 1234 #10255 BRAILLE PATTERN DOTS-1234
+sign \x2810 5 #10256 BRAILLE PATTERN DOTS-5
+sign \x2811 15 #10257 BRAILLE PATTERN DOTS-15
+sign \x2812 25 #10258 BRAILLE PATTERN DOTS-25
+sign \x2813 125 #10259 BRAILLE PATTERN DOTS-125
+sign \x2814 35 #10260 BRAILLE PATTERN DOTS-35
+sign \x2815 135 #10261 BRAILLE PATTERN DOTS-135
+sign \x2816 235 #10262 BRAILLE PATTERN DOTS-235
+sign \x2817 1235 #10263 BRAILLE PATTERN DOTS-1235
+sign \x2818 45 #10264 BRAILLE PATTERN DOTS-45
+sign \x2819 145 #10265 BRAILLE PATTERN DOTS-145
+sign \x281a 245 #10266 BRAILLE PATTERN DOTS-245
+sign \x281b 1245 #10267 BRAILLE PATTERN DOTS-1245
+sign \x281c 345 #10268 BRAILLE PATTERN DOTS-345
+sign \x281d 1345 #10269 BRAILLE PATTERN DOTS-1345
+sign \x281e 2345 #10270 BRAILLE PATTERN DOTS-2345
+sign \x281f 12345 #10271 BRAILLE PATTERN DOTS-12345
+sign \x2820 6 #10272 BRAILLE PATTERN DOTS-6
+sign \x2821 16 #10273 BRAILLE PATTERN DOTS-16
+sign \x2822 26 #10274 BRAILLE PATTERN DOTS-26
+sign \x2823 126 #10275 BRAILLE PATTERN DOTS-126
+sign \x2824 36 #10276 BRAILLE PATTERN DOTS-36
+sign \x2825 136 #10277 BRAILLE PATTERN DOTS-136
+sign \x2826 236 #10278 BRAILLE PATTERN DOTS-236
+sign \x2827 1236 #10279 BRAILLE PATTERN DOTS-1236
+sign \x2828 46 #10280 BRAILLE PATTERN DOTS-46
+sign \x2829 146 #10281 BRAILLE PATTERN DOTS-146
+sign \x282a 246 #10282 BRAILLE PATTERN DOTS-246
+sign \x282b 1246 #10283 BRAILLE PATTERN DOTS-1246
+sign \x282c 346 #10284 BRAILLE PATTERN DOTS-346
+sign \x282d 1346 #10285 BRAILLE PATTERN DOTS-1346
+sign \x282e 2346 #10286 BRAILLE PATTERN DOTS-2346
+sign \x282f 12346 #10287 BRAILLE PATTERN DOTS-12346
+sign \x2830 56 #10288 BRAILLE PATTERN DOTS-56
+sign \x2831 156 #10289 BRAILLE PATTERN DOTS-156
+sign \x2832 256 #10290 BRAILLE PATTERN DOTS-256
+sign \x2833 1256 #10291 BRAILLE PATTERN DOTS-1256
+sign \x2834 356 #10292 BRAILLE PATTERN DOTS-356
+sign \x2835 1356 #10293 BRAILLE PATTERN DOTS-1356
+sign \x2836 2356 #10294 BRAILLE PATTERN DOTS-2356
+sign \x2837 12356 #10295 BRAILLE PATTERN DOTS-12356
+sign \x2838 456 #10296 BRAILLE PATTERN DOTS-456
+sign \x2839 1456 #10297 BRAILLE PATTERN DOTS-1456
+sign \x283a 2456 #10298 BRAILLE PATTERN DOTS-2456
+sign \x283b 12456 #10299 BRAILLE PATTERN DOTS-12456
+sign \x283c 3456 #10300 BRAILLE PATTERN DOTS-3456
+sign \x283d 13456 #10301 BRAILLE PATTERN DOTS-13456
+sign \x283e 23456 #10302 BRAILLE PATTERN DOTS-23456
+sign \x283f 123456 #10303 BRAILLE PATTERN DOTS-123456
diff --git a/tables/de-chardefs8.cti b/tables/de-chardefs8.cti
new file mode 100644
index 0000000..2c3a92a
--- /dev/null
+++ b/tables/de-chardefs8.cti
@@ -0,0 +1,278 @@
+# liblouis: Character definitions for german tables
+#
+# Copyright (C) 2009 SBS Schweizerische Bibliothek für Blinde und Sehbehinderte
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#-------------------------------------------------------------------------------
+#
+# EUROBRAILLE
+# This computer braille table is widely
+# being used in german speaking parts of europe
+#
+# Version 2009-11-19
+# christian.waldvogel@sbszh.ch
+#
+#-------------------------------------------------------------------------------
+
+# 34578 \x0000 � <control> [NULL]
+# 178 \x0001  <control> [START OF HEADING]
+# 1278 \x0002  <control> [START OF TEXT]
+# 1478 \x0003  <control> [END OF TEXT]
+# 14578 \x0004  <control> [END OF TRANSMISSION]
+# 1578 \x0005  <control> [ENQUIRY]
+# 12478 \x0006  <control> [ACKNOWLEDGE]
+# 124578 \x0007  <control> [BELL]
+# 12578 \x0008  <control> [BACKSPACE]
+# 2478 \x0009 	 <control> [CHARACTER TABULATION]
+# 24578 \x000A <control> [LINE FEED (LF)]
+# 1378 \x000B  <control> [LINE TABULATION]
+# 12378 \x000C  <control> [FORM FEED (FF)]
+# 13478 \x000D <control> [CARRIAGE RETURN (CR)]
+# 134578 \x000E  <control> [SHIFT OUT]
+# 13578 \x000F  <control> [SHIFT IN]
+# 123478 \x0010  <control> [DATA LINK ESCAPE]
+# 1234578 \x0011  <control> [DEVICE CONTROL ONE]
+# 123578 \x0012  <control> [DEVICE CONTROL TWO]
+# 23478 \x0013  <control> [DEVICE CONTROL THREE]
+# 234578 \x0014  <control> [DEVICE CONTROL FOUR]
+# 13678 \x0015  <control> [NEGATIVE ACKNOWLEDGE]
+# 123678 \x0016  <control> [SYNCHRONOUS IDLE]
+# 245678 \x0017  <control> [END OF TRANSMISSION BLOCK]
+# 134678 \x0018  <control> [CANCEL]
+# 1345678 \x0019  <control> [END OF MEDIUM]
+# 135678 \x001A  <control> [SUBSTITUTE]
+# 1235678 \x001B  <control> [ESCAPE]
+# 3478 \x001C  <control> [INFORMATION SEPARATOR FOUR]
+# 2345678 \x001D  <control> [INFORMATION SEPARATOR THREE]
+# 234678 \x001E  <control> [INFORMATION SEPARATOR TWO]
+# 45678 \x001F  <control> [INFORMATION SEPARATOR ONE]
+space \s 0 \x0020   SPACE
+punctuation ! 5 \x0021 ! EXCLAMATION MARK
+punctuation " 4 \x0022 " QUOTATION MARK
+sign # 3456 \x0023 # NUMBER SIGN
+sign $ 46 \x0024 $ DOLLAR SIGN
+sign % 123456 \x0025 % PERCENT SIGN
+sign & 12346 \x0026 & AMPERSAND
+punctuation ' 6 \x0027 ' APOSTROPHE APOSTROPHE-QUOTE
+punctuation ( 236 \x0028 ( LEFT PARENTHESIS
+punctuation ) 356 \x0029 ) RIGHT PARENTHESIS
+sign * 35 \x002A * ASTERISK
+math + 235 \x002B + PLUS SIGN
+punctuation , 2 \x002C , COMMA
+punctuation - 36 \x002D - HYPHEN-MINUS
+punctuation . 3 \x002E . FULL STOP PERIOD
+punctuation / 256 \x002F / SOLIDUS SLASH
+include digits6DotsPlusDot6.uti
+punctuation : 25 \x003A : COLON
+punctuation ; 23 \x003B ; SEMICOLON
+math < 56 \x003C < LESS-THAN SIGN
+math = 2356 \x003D = EQUALS SIGN
+math > 45 \x003E > GREATER-THAN SIGN
+punctuation ? 26 \x003F ? QUESTION MARK
+sign @ 3457 \x0040 @ COMMERCIAL AT
+uppercase A 17 \x0041 A LATIN CAPITAL LETTER A
+uppercase B 127 \x0042 B LATIN CAPITAL LETTER B
+uppercase C 147 \x0043 C LATIN CAPITAL LETTER C
+uppercase D 1457 \x0044 D LATIN CAPITAL LETTER D
+uppercase E 157 \x0045 E LATIN CAPITAL LETTER E
+uppercase F 1247 \x0046 F LATIN CAPITAL LETTER F
+uppercase G 12457 \x0047 G LATIN CAPITAL LETTER G
+uppercase H 1257 \x0048 H LATIN CAPITAL LETTER H
+uppercase I 247 \x0049 I LATIN CAPITAL LETTER I
+uppercase J 2457 \x004A J LATIN CAPITAL LETTER J
+uppercase K 137 \x004B K LATIN CAPITAL LETTER K
+uppercase L 1237 \x004C L LATIN CAPITAL LETTER L
+uppercase M 1347 \x004D M LATIN CAPITAL LETTER M
+uppercase N 13457 \x004E N LATIN CAPITAL LETTER N
+uppercase O 1357 \x004F O LATIN CAPITAL LETTER O
+uppercase P 12347 \x0050 P LATIN CAPITAL LETTER P
+uppercase Q 123457 \x0051 Q LATIN CAPITAL LETTER Q
+uppercase R 12357 \x0052 R LATIN CAPITAL LETTER R
+uppercase S 2347 \x0053 S LATIN CAPITAL LETTER S
+uppercase T 23457 \x0054 T LATIN CAPITAL LETTER T
+uppercase U 1367 \x0055 U LATIN CAPITAL LETTER U
+uppercase V 12367 \x0056 V LATIN CAPITAL LETTER V
+uppercase W 24567 \x0057 W LATIN CAPITAL LETTER W
+uppercase X 13467 \x0058 X LATIN CAPITAL LETTER X
+uppercase Y 134567 \x0059 Y LATIN CAPITAL LETTER Y
+uppercase Z 13567 \x005A Z LATIN CAPITAL LETTER Z
+punctuation [ 123567 \x005B [ LEFT SQUARE BRACKET
+sign \\ 347 \x005C \ REVERSE SOLIDUS
+punctuation ] 234567 \x005D ] RIGHT SQUARE BRACKET
+sign ^ 23467 \x005E ^ CIRCUMFLEX ACCENT
+sign _ 4567 \x005F _ LOW LINE
+sign ` 345 \x0060 ` GRAVE ACCENT
+lowercase a 1 \x0061 a LATIN SMALL LETTER A
+lowercase b 12 \x0062 a LATIN SMALL LETTER B
+lowercase c 14 \x0063 a LATIN SMALL LETTER C
+lowercase d 145 \x0064 a LATIN SMALL LETTER D
+lowercase e 15 \x0065 a LATIN SMALL LETTER E
+lowercase f 124 \x0066 a LATIN SMALL LETTER F
+lowercase g 1245 \x0067 a LATIN SMALL LETTER G
+lowercase h 125 \x0068 a LATIN SMALL LETTER H
+lowercase i 24 \x0069 a LATIN SMALL LETTER I
+lowercase j 245 \x006A a LATIN SMALL LETTER J
+lowercase k 13 \x006B a LATIN SMALL LETTER K
+lowercase l 123 \x006C a LATIN SMALL LETTER L
+lowercase m 134 \x006D a LATIN SMALL LETTER M
+lowercase n 1345 \x006E a LATIN SMALL LETTER N
+lowercase o 135 \x006F o LATIN SMALL LETTER O
+lowercase p 1234 \x0070 p LATIN SMALL LETTER P
+lowercase q 12345 \x0071 q LATIN SMALL LETTER Q
+lowercase r 1235 \x0072 r LATIN SMALL LETTER R
+lowercase s 234 \x0073 s LATIN SMALL LETTER S
+lowercase t 2345 \x0074 t LATIN SMALL LETTER T
+lowercase u 136 \x0075 u LATIN SMALL LETTER U
+lowercase v 1236 \x0076 v LATIN SMALL LETTER V
+lowercase w 2456 \x0077 w LATIN SMALL LETTER W
+lowercase x 1346 \x0078 x LATIN SMALL LETTER X
+lowercase y 13456 \x0079 y LATIN SMALL LETTER Y
+lowercase z 1356 \x007A z LATIN SMALL LETTER Z
+punctuation { 12356 \x007B { LEFT CURLY BRACKET
+sign | 34 \x007C | VERTICAL LINE
+punctuation } 23456 \x007D } RIGHT CURLY BRACKET
+sign ~ 2346 \x007E ~ TILDE
+sign \x007F 456 \x007F  [DELETE]
+# 457 \x0080 € <control>
+# 8 \x0081  <control>
+# 3678 \x0082 ‚ <control> [BREAK PERMITTED HERE]
+# 78 \x0083 ƒ <control> [NO BREAK HERE]
+# 1268 \x0084 „ <control>
+# 238 \x0085 … <control> [NEXT LINE (NEL)]
+# 1248 \x0086 † <control> [START OF SELECTED AREA]
+# 12458 \x0087 ‡ <control> [END OF SELECTED AREA]
+# 378 \x0088 ˆ <control> [CHARACTER TABULATION SET]
+# 248 \x0089 ‰ <control> [CHARACTER TABULATION WITH JUSTIFICATION]
+# 678 \x008A Š <control> [LINE TABULATION SET]
+# 27 \x008B ‹ <control> [PARTIAL LINE FORWARD]
+# 237 \x008C Œ <control> [PARTIAL LINE BACKWARD]
+# 257 \x008D  <control> [REVERSE LINE FEED]
+# 12567 \x008E Ž <control> [SINGLE SHIFT TWO]
+# 12467 \x008F  <control> [SINGLE SHIFT THREE]
+# 124678 \x0090  <control> [DEVICE CONTROL STRING]
+# 23567 \x0091 ‘ <control> [PRIVATE USE ONE]
+# 2367 \x0092 ’ <control> [PRIVATE USE TWO]
+# 138 \x0093 “ <control> [SET TRANSMIT STATE]
+# 1238 \x0094 ” <control> [CANCEL CHARACTER]
+# 278 \x0095 • <control> [MESSAGE WAITING]
+# 2378 \x0096 – <control> [START OF GUARDED AREA]
+# 13568 \x0097 — <control> [END OF GUARDED AREA]
+# 2578 \x0098 ˜ <control> [START OF STRING]
+# 1245678 \x0099 ™ <control>
+# 2678 \x009A š <control> [SINGLE CHARACTER INTRODUCER]
+# 123458 \x009B › <control> [CONTROL SEQUENCE INTRODUCER]
+# 67 \x009C œ <control> [STRING TERMINATOR]
+# 124567 \x009D  <control> [OPERATING SYSTEM COMMAND]
+# 235678 \x009E ž <control> [PRIVACY MESSAGE]
+# 12345678 \x009F Ÿ <control> [APPLICATION PROGRAM COMMAND]
+space \x00a0 7 \x00A0   NO-BREAK SPACE
+punctuation ¡ 367 \x00A1 ¡ INVERTED EXCLAMATION MARK
+sign ¢ 58 \x00A2 ¢ CENT SIGN
+sign £ 467 \x00A3 £ POUND SIGN
+sign ¤ 4678 \x00A4 ¤ CURRENCY SIGN
+sign ¥ 468 \x00A5 ¥ YEN SIGN
+sign ¦ 158 \x00A6 ¦ BROKEN BAR
+sign § 357 \x00A7 § SECTION SIGN
+sign ¨ 48 \x00A8 ¨ DIAERESIS
+sign © 123468 \x00A9 © COPYRIGHT SIGN
+sign ª 1258 \x00AA ª FEMININE ORDINAL INDICATOR
+punctuation « 5678 \x00AB « LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+sign ¬ 25678 \x00AC ¬ NOT SIGN
+sign 368 \x00AD ­ SOFT HYPHEN
+sign ® 12358 \x00AE ® REGISTERED SIGN
+sign ¯ 458 \x00AF ¯ MACRON
+sign ° 4568 \x00B0 ° DEGREE SIGN
+math ± 23578 \x00B1 ± PLUS-MINUS SIGN
+sign ² 128 \x00B2 ² SUPERSCRIPT TWO
+sign ³ 148 \x00B3 ³ SUPERSCRIPT THREE
+sign ´ 568 \x00B4 ´ ACUTE ACCENT
+sign µ 1348 \x00B5 µ MICRO SIGN
+sign ¶ 1458 \x00B6 ¶ PILCROW SIGN
+sign · 37 \x00B7 · MIDDLE DOT
+sign ¸ 68 \x00B8 ¸ CEDILLA
+sign ¹ 18 \x00B9 ¹ SUPERSCRIPT ONE
+sign º 2458 \x00BA º MASCULINE ORDINAL INDICATOR
+punctuation » 4578 \x00BB » RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+math ¼ 1368 \x00BC ¼ VULGAR FRACTION ONE QUARTER
+math ½ 12368 \x00BD ½ VULGAR FRACTION ONE HALF
+math ¾ 13468 \x00BE ¾ VULGAR FRACTION THREE QUARTERS
+punctuation ¿ 38 \x00BF ¿ INVERTED QUESTION MARK
+uppercase À 23678 \x00C0 À LATIN CAPITAL LETTER A WITH GRAVE
+uppercase Á 28 \x00C1 Á LATIN CAPITAL LETTER A WITH ACUTE
+uppercase  167 \x00C2  LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+uppercase à 3467 \x00C3 à LATIN CAPITAL LETTER A WITH TILDE
+uppercase Ä 567 \x00C4 Ä LATIN CAPITAL LETTER A WITH DIAERESIS
+uppercase Å 34567 \x00C5 Å LATIN CAPITAL LETTER A WITH RING ABOVE
+uppercase Æ 47 \x00C6 Æ LATIN CAPITAL LETTER AE
+uppercase Ç 123467 \x00C7 Ç LATIN CAPITAL LETTER C WITH CEDILLA
+uppercase È 3578 \x00C8 È LATIN CAPITAL LETTER E WITH GRAVE
+uppercase É 1234567 \x00C9 É LATIN CAPITAL LETTER E WITH ACUTE
+uppercase Ê 1267 \x00CA Ê LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+uppercase Ë 2358 \x00CB Ë LATIN CAPITAL LETTER E WITH DIAERESIS
+uppercase Ì 57 \x00CC Ì LATIN CAPITAL LETTER I WITH GRAVE
+uppercase Í 258 \x00CD Í LATIN CAPITAL LETTER I WITH ACUTE
+uppercase Î 1467 \x00CE Î LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+uppercase Ï 23568 \x00CF Ï LATIN CAPITAL LETTER I WITH DIAERESIS
+uppercase Ð 3567 \x00D0 Ð LATIN CAPITAL LETTER ETH
+uppercase Ñ 2567 \x00D1 Ñ LATIN CAPITAL LETTER N WITH TILDE
+uppercase Ò 578 \x00D2 Ò LATIN CAPITAL LETTER O WITH GRAVE
+uppercase Ó 2568 \x00D3 Ó LATIN CAPITAL LETTER O WITH ACUTE
+uppercase Ô 14567 \x00D4 Ô LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+uppercase Õ 267 \x00D5 Õ LATIN CAPITAL LETTER O WITH TILDE
+uppercase Ö 358 \x00D6 Ö LATIN CAPITAL LETTER O WITH DIAERESIS
+math × 2348 \x00D7 × MULTIPLICATION SIGN
+uppercase Ø 2467 \x00D8 Ø LATIN CAPITAL LETTER O WITH STROKE
+uppercase Ù 35678 \x00D9 Ù LATIN CAPITAL LETTER U WITH GRAVE
+uppercase Ú 268 \x00DA Ú LATIN CAPITAL LETTER U WITH ACUTE
+uppercase Û 1567 \x00DB Û LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+uppercase Ü 2368 \x00DC Ü LATIN CAPITAL LETTER U WITH DIAERESIS
+uppercase Ý 3568 \x00DD Ý LATIN CAPITAL LETTER Y WITH ACUTE
+uppercase Þ 2357 \x00DE Þ LATIN CAPITAL LETTER THORN
+lowercase ß 34568 \x00DF ß LATIN SMALL LETTER SHARP S
+lowercase à 123568 \x00E0 à LATIN SMALL LETTER A WITH GRAVE
+lowercase á 168 \x00E1 á LATIN SMALL LETTER A WITH ACUTE
+lowercase â 1678 \x00E2 â LATIN SMALL LETTER A WITH CIRCUMFLEX
+lowercase ã 34678 \x00E3 ã LATIN SMALL LETTER A WITH TILDE
+lowercase ä 3458 \x00E4 ä LATIN SMALL LETTER A WITH DIAERESIS
+lowercase å 345678 \x00E5 å LATIN SMALL LETTER A WITH RING ABOVE
+lowercase æ 478 \x00E6 æ LATIN SMALL LETTER AE
+lowercase ç 1234678 \x00E7 ç LATIN SMALL LETTER C WITH CEDILLA
+lowercase è 23468 \x00E8 è LATIN SMALL LETTER E WITH GRAVE
+lowercase é 1234568 \x00E9 é LATIN SMALL LETTER E WITH ACUTE
+lowercase ê 12678 \x00EA ê LATIN SMALL LETTER E WITH CIRCUMFLEX
+lowercase ë 12468 \x00EB ë LATIN SMALL LETTER E WITH DIAERESIS
+lowercase ì 348 \x00EC ì LATIN SMALL LETTER I WITH GRAVE
+lowercase í 1468 \x00ED í LATIN SMALL LETTER I WITH ACUTE
+lowercase î 14678 \x00EE î LATIN SMALL LETTER I WITH CIRCUMFLEX
+lowercase ï 124568 \x00EF ï LATIN SMALL LETTER I WITH DIAERESIS
+lowercase ð 23458 \x00F0 ð LATIN SMALL LETTER ETH
+lowercase ñ 13458 \x00F1 ñ LATIN SMALL LETTER N WITH TILDE
+lowercase ò 3468 \x00F2 ò LATIN SMALL LETTER O WITH GRAVE
+lowercase ó 14568 \x00F3 ó LATIN SMALL LETTER O WITH ACUTE
+lowercase ô 145678 \x00F4 ô LATIN SMALL LETTER O WITH CIRCUMFLEX
+lowercase õ 1358 \x00F5 õ LATIN SMALL LETTER O WITH TILDE
+lowercase ö 2468 \x00F6 ö LATIN SMALL LETTER O WITH DIAERESIS
+math ÷ 125678 \x00F7 ÷ DIVISION SIGN
+lowercase ø 24678 \x00F8 ø LATIN SMALL LETTER O WITH STROKE
+lowercase ù 234568 \x00F9 ù LATIN SMALL LETTER U WITH GRAVE
+lowercase ú 1568 \x00FA ú LATIN SMALL LETTER U WITH ACUTE
+lowercase û 15678 \x00FB û LATIN SMALL LETTER U WITH CIRCUMFLEX
+lowercase ü 12568 \x00FC ü LATIN SMALL LETTER U WITH DIAERESIS
+lowercase ý 24568 \x00FD ý LATIN SMALL LETTER Y WITH ACUTE
+lowercase þ 12348 \x00FE þ LATIN SMALL LETTER THORN
+lowercase ÿ 134568 \x00FF ÿ LATIN SMALL LETTER Y WITH DIAERESIS
diff --git a/tables/de-chess.ctb b/tables/de-chess.ctb
new file mode 100644
index 0000000..97880a5
--- /dev/null
+++ b/tables/de-chess.ctb
@@ -0,0 +1,37 @@
+#
+# Copyright (C) 1995-2008 by The BRLTTY Developers.
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# This text subtable defines braille representations for the chess figures in
+# terms of the letters that are used for them in the German language.
+
+# See: http://en.wikipedia.org/wiki/Chess_symbols_in_Unicode
+
+# generated by ttbtest
+punctuation \x2654 137 WHITE CHESS KING
+punctuation \x2655 1457 WHITE CHESS QUEEN
+punctuation \x2656 23457 WHITE CHESS ROOK
+punctuation \x2657 1237 WHITE CHESS BISHOP
+punctuation \x2658 2347 WHITE CHESS KNIGHT
+punctuation \x2659 127 WHITE CHESS PAWN
+punctuation \x265a 13 BLACK CHESS KING
+punctuation \x265b 145 BLACK CHESS QUEEN
+punctuation \x265c 2345 BLACK CHESS ROOK
+punctuation \x265d 123 BLACK CHESS BISHOP
+punctuation \x265e 234 BLACK CHESS KNIGHT
+punctuation \x265f 12 BLACK CHESS PAWN
diff --git a/tables/de-de-comp8.ctb b/tables/de-de-comp8.ctb
new file mode 100644
index 0000000..b16fc95
--- /dev/null
+++ b/tables/de-de-comp8.ctb
@@ -0,0 +1,493 @@
+
+# Copyright (C) 2004-2008 ViewPlus Technologies, Inc. www.viewplus.com
+# Copyright (C) 2004-2006 JJB Software, Inc. www.jjb-software.com
+# Copyright (C) 2012 Ali-Riza Ciftcioglu aliminator83@gmail.com
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# A part of these mappings do not correspond to a standard as not all of German 8-dot
+# braille is properly standardized
+
+# -----------
+#-name: Eurobraille
+#-index-name: German, computer
+#-display-name: German computer braille
+#
+#+locale: de
+#+type: computer
+#+contraction: no
+#+grade: 0
+#+direction: both
+# ------------
+
+include braille-patterns.cti
+
+sign \x0020 0
+sign \x0000 0
+sign \x0001 178
+sign \x0002 1278
+sign \x0003 1478
+sign \x0004 14578
+sign \x0005 1578
+sign \x0006 12478
+sign \x0007 124578
+sign \x0008 12578
+sign \x0009 2478
+sign \x000a 24578
+sign \x000b 1378
+sign \x000c 12378
+sign \x000d 13478
+sign \x000e 134578
+sign \x000f 13578
+sign \x0010 123478
+sign \x0011 1234578
+sign \x0012 123578
+sign \x0013 23478
+sign \x0014 234578
+sign \x0015 13678
+sign \x0016 123678
+sign \x0017 245678
+sign \x0018 134678
+sign \x0019 1345678
+sign \x001a 135678
+sign \x001b 1235678
+sign \x001c 3478
+sign \x001d 2345678
+sign \x001e 234678
+sign \x001f 45678
+sign \x0021 5
+sign \x0022 4
+sign \x0023 3456
+sign \x0024 46
+sign \x0025 123456
+sign \x0026 12346
+sign \x0027 6
+sign \x0028 236
+sign \x0029 356
+sign \x002a 35
+sign \x002b 235
+sign \x002c 2
+sign \x002d 36
+sign \x002e 3
+sign \x002f 256
+sign \x0030 346
+sign \x0031 16
+sign \x0032 126
+sign \x0033 146
+sign \x0034 1456
+sign \x0035 156
+sign \x0036 1246
+sign \x0037 12456
+sign \x0038 1256
+sign \x0039 246
+sign \x003a 25
+sign \x003b 23
+sign \x003c 56
+sign \x003d 2356
+sign \x003e 45
+sign \x003f 26
+sign \x0040 3457
+sign \x0041 17
+sign \x0042 127
+sign \x0043 147
+sign \x0044 1457
+sign \x0045 157
+sign \x0046 1247
+sign \x0047 12457
+sign \x0048 1257
+sign \x0049 247
+sign \x004a 2457
+sign \x004b 137
+sign \x004c 1237
+sign \x004d 1347
+sign \x004e 13457
+sign \x004f 1357
+sign \x0050 12347
+sign \x0051 123457
+sign \x0052 12357
+sign \x0053 2347
+sign \x0054 23457
+sign \x0055 1367
+sign \x0056 12367
+sign \x0057 24567
+sign \x0058 13467
+sign \x0059 134567
+sign \x005a 13567
+sign \x005b 123567
+sign \x005c 347
+sign \x005d 234567
+sign \x005e 23467
+sign \x005f 4567
+sign \x0060 345
+sign \x0061 1
+sign \x0062 12
+sign \x0063 14
+sign \x0064 145
+sign \x0065 15
+sign \x0066 124
+sign \x0067 1245
+sign \x0068 125
+sign \x0069 24
+sign \x006a 245
+sign \x006b 13
+sign \x006c 123
+sign \x006d 134
+sign \x006e 1345
+sign \x006f 135
+sign \x0070 1234
+sign \x0071 12345
+sign \x0072 1235
+sign \x0073 234
+sign \x0074 2345
+sign \x0075 136
+sign \x0076 1236
+sign \x0077 2456
+sign \x0078 1346
+sign \x0079 13456
+sign \x007a 1356
+sign \x007b 12356
+sign \x007c 34
+sign \x007d 23456
+sign \x007e 2346
+sign \x007f 456
+sign \x0080 457
+sign \x0081 8
+sign \x0082 3678
+sign \x0083 78
+sign \x0084 1268
+sign \x0085 238
+sign \x0086 1248
+sign \x0087 12458
+sign \x0088 378
+sign \x0089 248
+sign \x008a 678
+sign \x008b 27
+sign \x008c 237
+sign \x008d 257
+sign \x008e 12567
+sign \x008f 12467
+sign \x0090 124678
+sign \x0091 23567
+sign \x0092 2367
+sign \x0093 138
+sign \x0094 1238
+sign \x0095 278
+sign \x0096 2378
+sign \x0097 13568
+sign \x0098 2578
+sign \x0099 1245678
+sign \x009a 2678
+sign \x009b 123458
+sign \x009c 67
+sign \x009d 124567
+sign \x009e 235678
+sign \x009f 12345678
+sign \x00a0 7
+sign \x00a1 367
+sign \x00a2 58
+sign \x00a3 467
+sign \x00a4 4678
+sign \x00a5 468
+sign \x00a6 158
+sign \x00a7 357
+sign \x00a8 48
+sign \x00a9 123468
+sign \x00aa 1258
+sign \x00ab 5678
+sign \x00ac 25678
+sign \x00ad 368
+sign \x00ae 12358
+sign \x00af 458
+sign \x00b0 4568
+sign \x00b1 23578
+sign \x00b2 128
+sign \x00b3 148
+sign \x00b4 568
+sign \x00b5 1348
+sign \x00b6 1458
+sign \x00b7 37
+sign \x00b8 68
+sign \x00b9 18
+sign \x00ba 2458
+sign \x00bb 4578
+sign \x00bc 1368
+sign \x00bd 12368
+sign \x00be 13468
+sign \x00bf 38
+sign \x00c0 23678
+sign \x00c1 28
+sign \x00c2 167
+sign \x00c3 3467
+sign \x00c4 567
+sign \x00c5 34567
+sign \x00c6 47
+sign \x00c7 123467
+sign \x00c8 3578
+sign \x00c9 1234567
+sign \x00ca 1267
+sign \x00cb 2358
+sign \x00cc 57
+sign \x00cd 258
+sign \x00ce 1467
+sign \x00cf 23568
+sign \x00d0 3567
+sign \x00d1 2567
+sign \x00d2 578
+sign \x00d3 2568
+sign \x00d4 14567
+sign \x00d5 267
+sign \x00d6 358
+sign \x00d7 2348
+sign \x00d8 2467
+sign \x00d9 35678
+sign \x00da 268
+sign \x00db 1567
+sign \x00dc 2368
+sign \x00dd 3568
+sign \x00de 2357
+sign \x00df 34568
+sign \x00e0 123568
+sign \x00e1 168
+sign \x00e2 1678
+sign \x00e3 34678
+sign \x00e4 3458
+sign \x00e5 345678
+sign \x00e6 478
+sign \x00e7 1234678
+sign \x00e8 23468
+sign \x00e9 1234568
+sign \x00ea 12678
+sign \x00eb 12468
+sign \x00ec 348
+sign \x00ed 1468
+sign \x00ee 14678
+sign \x00ef 124568
+sign \x00f0 23458
+sign \x00f1 13458
+sign \x00f2 3468
+sign \x00f3 14568
+sign \x00f4 145678
+sign \x00f5 1358
+sign \x00f6 2468
+sign \x00f7 125678
+sign \x00f8 24678
+sign \x00f9 234568
+sign \x00fa 1568
+sign \x00fb 15678
+sign \x00fc 12568
+sign \x00fd 24568
+sign \x00fe 12348
+sign \x00ff 134568
+sign \x25e6 67 # white bullet
+sign \x25fe 3678 # black square
+sign \x2022 35 # •
+sign \x2014 36 # —
+sign \x2013 36 # –
+sign \x2019 6 # '
+sign \x201e 1268 # „
+sign \x201c 138 # “
+sign \x201a 3678 # ‚
+sign \x2018 2367 # ‘
+noback sign \x202F 7 NARROW NO-BREAK SPACE
+noback sign \x25CF 35 # 9679 black circle
+
+# those symbols should be ignored because there is no one character mapping in the actual braille table
+sign \x2192 0 # →
+sign \x2190 0 # ←
+sign \x25bc 0 # ▼
+
+# The following mappings are not standards compliant as there is no standard for these.
+
+sign \x0100 1678
+sign \x0101 168
+sign \x0102 1235678
+sign \x0103 123568
+sign \x0104 134568
+sign \x0105 168
+sign \x0106 14678
+sign \x0107 1468
+sign \x0108 14678
+sign \x0109 1468
+sign \x010C 14678
+sign \x010D 1468
+sign \x0110 145678
+sign \x0111 14568
+sign \x0112 15678
+sign \x0113 1568
+sign \x0118 12678
+sign \x0119 1268
+sign \x011B 126
+sign \x011c 1245678
+sign \x011d 124568
+sign \x011e 124567
+sign \x011f 12456
+sign \x0122 1245678
+sign \x0123 124568
+sign \x0124 125678
+sign \x0125 12568
+sign \x012B 2468
+sign \x0130 3478
+sign \x0131 348
+sign \x0134 245678
+sign \x0135 24568
+sign \x0136 13678
+sign \x0137 1368
+sign \x013B 123678
+sign \x013C 12368
+sign \x0141 134568
+sign \x0142 1568
+sign \x0143 145678
+sign \x0144 14568
+sign \x0145 1345678
+sign \x0146 134568
+sign \x0150 1245678
+sign \x0151 124568
+sign \x0152 237
+sign \x0153 467
+sign \x0156 1235678
+sign \x0157 123568
+sign \x0159 2456
+sign \x015C 234678
+sign \x015D 23468
+sign \x015F 123468
+sign \x015a 134568
+sign \x015b 134568
+sign \x015e 134568
+sign \x0160 678
+sign \x0161 1568
+sign \x0162 24678
+sign \x0163 23458
+sign \x0164 125678
+sign \x0165 1256
+sign \x016B 3468
+sign \x016C 34678
+sign \x016D 3468
+sign \x016a 34678
+sign \x016f 23456
+sign \x0170 2345678
+sign \x0171 234568
+sign \x0178 12345678
+sign \x0179 134568
+sign \x017C 123468
+sign \x017D 12567
+sign \x017a 134568
+sign \x017b 134568
+sign \x017e 2346
+sign \x0192 78
+sign \x01a0 12367
+sign \x01a1 1236
+sign \x025C 13567
+sign \x02C6 378
+sign \x02DC 2578
+sign \x02c7 134568
+sign \x02d8 134568
+sign \x02d9 5
+sign \x02db 134568
+sign \x2003 0
+sign \x2011 36
+sign \x2013 368
+sign \x2014 36
+sign \x2015 36
+sign \x2017 36
+sign \x2018 2367
+sign \x2019 47
+sign \x201A 3678
+sign \x201C 138
+sign \x201D 1238
+sign \x201E 1268
+sign \x2020 1248
+sign \x2021 12458
+sign \x2022 35
+sign \x2026 238
+sign \x2029 1458
+sign \x2030 248
+sign \x2039 27
+sign \x203a 123458
+sign \x207F 13467
+sign \x20AC 457
+sign \x20AF 145678
+sign \x2116 3456
+sign \x2122 1245678
+sign \x2219 48
+sign \x221A 1467
+sign \x221E 234678
+sign \x2229 578
+sign \x2248 3578
+sign \x2261 23568
+sign \x2264 568
+sign \x2265 458
+sign \x2310 14567
+sign \x2320 347
+sign \x2321 1567
+sign \x2500 67
+sign \x2502 237
+sign \x250C 257
+sign \x2510 278
+sign \x2514 378
+sign \x2518 678
+sign \x251C 2367
+sign \x2524 13568
+sign \x252C 138
+sign \x2534 27
+sign \x2550 2578
+sign \x2551 1234568
+sign \x2552 123468
+sign \x2553 1358
+sign \x2554 23567
+sign \x2555 148
+sign \x2556 368
+sign \x2557 12458
+sign \x2558 248
+sign \x2559 1238
+sign \x255A 2378
+sign \x255B 34678
+sign \x255C 4678
+sign \x255D 2678
+sign \x255E 68
+sign \x255F 257
+sign \x2560 1248
+sign \x2561 268
+sign \x2562 24568
+sign \x2563 123567
+sign \x2564 3467
+sign \x2565 28
+sign \x2566 123458
+sign \x2567 167
+sign \x2568 57
+sign \x2569 8
+sign \x256A 3567
+sign \x256B 12358
+sign \x256C 5678
+sign \x2580 234567
+sign \x2584 1267
+sign \x2588 12345678
+sign \x258C 23678
+sign \x2590 35678
+sign \x2591 78
+sign \x2592 3678
+sign \x2593 235678
+sign \x25A0 1234567
+sign \x25cf 35
+sign \x2610 124578 # not active
+sign \x2612 12345678 # active
+sign \x8722 36
+
+# musical unicode characters
+
+sign \x266d 12 # ♭
+sign \x266e 2356 # ♮
+sign \x266f 3456 # ♯
diff --git a/tables/de-de.dis b/tables/de-de.dis
new file mode 100644
index 0000000..0ded774
--- /dev/null
+++ b/tables/de-de.dis
@@ -0,0 +1,331 @@
+# This file is obsolete. Do not use!
+
+# liblouis: de-de.dis
+#
+# Copyright (C) 1995-2004 by The BRLTTY Team. All rights reserved.
+# Copyright (C) 2004 ViewPlus Technologies, inc., www.viewplustech.com
+# Copyright (C) 2004 Computers to Help People, Inc., www.chpi.org
+
+# This file is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This file is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this file; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Maintained by John J. Boyer, director@chpi.org, www.chpi.org
+
+# This is to be used with German translation tables.
+
+
+ #Hex Dots Dec Char Description
+display \x0020 0 #32 space
+display \x0021 5 #33 ! exclamation mark
+display \x0022 4 #34 " quotation mark
+display \x0023 3456 #35 # number sign
+display \x0024 46 #36 $ dollar sign
+display \x0025 123456 #37 % percent sign
+display \x0026 12346 #38 & ampersand
+display \x0027 6 #39 ' apostrophe
+display \x0028 236 #40 ( left parenthesis
+display \x0029 356 #41 ) right parenthesis
+display \x002A 35 #42 * asterisk
+display \x002B 235 #43 + plus sign
+display \x002C 2 #44 , comma
+display \x002D 36 #45 - hyphen-minus
+display \x002E 3 #46 . full stop
+display \x002F 256 #47 / solidus
+
+display \x0030 346 #480 digit zero
+display \x0031 16 #491 digit one
+display \x0032 126 #502 digit two
+display \x0033 146 #513 digit three
+display \x0034 1456 #524 digit four
+display \x0035 156 #535 digit five
+display \x0036 1246 #546 digit six
+display \x0037 12456 #557 digit seven
+display \x0038 1256 #568 digit eight
+display \x0039 246 #579 digit nine
+display \x003A 25 #58 : colon
+display \x003B 23 #59 ; semicolon
+display \x003C 56 #60 < less-than sign
+# display \x003D 156 #61 = equals sign
+display \x003D 2356 #61 = equals sign
+display \x003E 45 #62 > greater-than sign
+display \x003F 26 #63 ? question mark
+display \x0040 345 #64 @ commercial at
+
+ #Hex Dots Dec Char Description
+display \x0041 17 #65 A Latin capital letter a
+display \x0042 127 #66 B Latin capital letter b
+display \x0043 147 #67 C Latin capital letter c
+display \x0044 1457 #68 D Latin capital letter d
+display \x0045 157 #69 E Latin capital letter e
+display \x0046 1247 #70 F Latin capital letter f
+display \x0047 12457 #71 G Latin capital letter g
+display \x0048 1257 #72 H Latin capital letter h
+display \x0049 247 #73 I Latin capital letter i
+display \x004A 2457 #74 J Latin capital letter j
+display \x004B 137 #75 K Latin capital letter k
+display \x004C 1237 #76 L Latin capital letter l
+display \x004D 1347 #77 M Latin capital letter m
+display \x004E 13457 #78 N Latin capital letter n
+display \x004F 1357 #79 O Latin capital letter o
+display \x0050 12347 #80 P Latin capital letter p
+display \x0051 123457 #81 Q Latin capital letter q
+display \x0052 12357 #82 R Latin capital letter r
+display \x0053 2347 #83 S Latin capital letter s
+display \x0054 23457 #84 T Latin capital letter t
+display \x0055 1367 #85 U Latin capital letter u
+display \x0056 12367 #86 V Latin capital letter v
+display \x0057 24567 #87 W Latin capital letter w
+display \x0058 13467 #88 X Latin capital letter x
+display \x0059 134567 #89 Y Latin capital letter y
+display \x005A 13567 #90 Z Latin capital letter z
+
+display \x005B 12356 # 91 [ left square bracket
+display \x005C 347 # 92 \ reverse solidus
+display \x005D 23456 # 93 ] right square bracket
+display \x005E 2346 # 94 ^ circumflex accent
+display \x005F 456 # 95 _ low line
+display \x0060 345 # 96 ` grave accent
+
+display \x0061 1 #97 a Latin small letter a
+display \x0062 12 #98 b Latin small letter b
+display \x0063 14 #99 c Latin small letter c
+display \x0064 145 #100 d Latin small letter d
+display \x0065 15 #101 e Latin small letter e
+display \x0066 124 #102 f Latin small letter f
+display \x0067 1245 #103 g Latin small letter g
+display \x0068 125 #104 h Latin small letter h
+display \x0069 24 #105 i Latin small letter i
+display \x006A 245 #106 j Latin small letter j
+display \x006B 13 #107 k Latin small letter k
+display \x006C 123 #108 l Latin small letter l
+display \x006D 134 #109 m Latin small letter m
+display \x006E 1345 #110 n Latin small letter n
+display \x006F 135 #111 o Latin small letter o
+display \x0070 1234 #112 p Latin small letter p
+display \x0071 12345 #113 q Latin small letter q
+display \x0072 1235 #114 r Latin small letter r
+display \x0073 234 #115 s Latin small letter s
+display \x0074 2345 #116 t Latin small letter t
+display \x0075 136 #117 u Latin small letter u
+display \x0076 1236 #118 v Latin small letter v
+display \x0077 2456 #119 w Latin small letter w
+display \x0078 1346 #120 x Latin small letter x
+display \x0079 13456 #121 y Latin small letter y
+display \x007A 1356 #122 z Latin small letter z
+
+display \x007B 12356 # 123 { left curly bracket
+display \x007C 34 # 124 | vertical line
+display \x007D 23456 # 125 } right curly bracket
+display \x007E 2356 # 126 ~ tilde
+display \x007F 4568 # 127 ^ ?delete
+
+#Hex Dots Dec Char Description
+display \x0080 48 # 128~@<control>
+display \x0081 18 # 129~A<control>
+display \x0082 128 # 130~Bbreak permitted here
+display \x0083 148 # 131~Cno break here
+display \x0084 1458 # 132~D<control>
+display \x0085 158 # 133~Enext line
+display \x0086 1248 # 134~Fstart of selected area
+display \x0087 12458 # 135~Gend of selected area
+display \x0088 1258 # 136~Hcharacter tabulation set
+display \x0089 248 # 137~Icharacter tabulation with justification
+display \x008A 2458 # 138~Jline tabulation set
+display \x008B 138 # 139~Kpartial line down
+display \x008C 1238 # 140~Lpartial line up
+display \x008D 1348 # 141~Mreverse line feed
+display \x008E 13458 # 142~Nsingle shift two
+display \x008F 1358 # 143~Osingle shift three
+display \x0090 12348 # 144~Pdevice control string
+display \x0091 123458 # 145~Qprivate use one
+display \x0092 12358 # 146~Rprivate use two
+display \x0093 2348 # 147~Sset transmit state
+display \x0094 23458 # 148~Tcancel character
+display \x0095 1368 # 149~Umessage waiting
+display \x0096 12368 # 150~Vstart of guarded area
+display \x0097 24568 # 151~Wend of guarded area
+display \x0098 13468 # 152~Xstart of string
+display \x0099 134568 # 153~Y<control>
+display \x009A 13568 # 154~Zsingle character introducer
+display \x009B 2468 # 155~[control sequence introducer
+display \x009C 12568 # 156~\string terminator
+display \x009D 124568 # 157~]operating system command
+display \x009E 458 # 158~^privacy message
+display \x009F 4568 # 159 ~_application program command
+display \x00A0 0 #160 no-break space
+
+#Hex Dots Dec Char Description
+display \x0000 478 #0^@null
+display \x0001 178 #1^Astart of heading
+display \x0002 1278 #2^Bstart of text
+display \x0003 1478 #3^Cend of text
+display \x0004 14578 #4^Dend of transmission
+display \x0005 1578 #5^Eenquiry
+display \x0006 12478 #6^Facknowledge
+display \x0007 124578 #7^Gbell
+display \x0008 12578 #8^Hbackspace
+display \x0009 2478 #9^Ihorizontal tabulation
+display \x000A 24578 #10^Jline feed
+display \x000B 1378 #11^Kvertical tabulation
+display \x000C 12378 #12^Lform feed
+display \x000D 13478 #13^Mcarriage return
+display \x000E 134578 #14^Nshift out
+display \x000F 13578 #15^Oshift in
+display \x0010 123478 #16^Pdata link escape
+display \x0011 1234578 #17^Qdevice control one
+display \x0012 123578 #18^Rdevice control two
+display \x0013 23478 #19^Sdevice control three
+display \x0014 234578 #20^Tdevice control four
+display \x0015 13678 #21^Unegative acknowledge
+display \x0016 123678 #22^Vsynchronous idle
+display \x0017 245678 #23^Wend of transmission block
+display \x0018 134678 #24^Xcancel
+display \x0019 1345678 #25^Yend of medium
+display \x001A 135678 #26^Zsubstitute
+display \x001B 24678 #27^[escape
+display \x001C 125678 #28^\file separator
+display \x001D 1245678 #29^]group separator
+display \x001E 4578 #30^^record separator
+display \x001F 45678 #31^_unit separator
+
+ #Hex Dots Dec Char Description
+display \x00A1 23467 # 161 ¡ inverted exclamation mark
+display \x00A2 58 #162 ¢ cent sign
+display \x00A3 34567 # 163 £ pound sign
+display \x00A4 1467 # 164 ¤ currency sign
+display \x00A5 123467 # 165 ¥ yen sign
+display \x00A6 1567 # 166 ¦ broken bar
+display \x00A7 357 # 167 § section sign
+display \x00A8 57 # 168 ¨ diaeresis
+display \x00A9 23567 # 169 © copyright sign
+display \x00AA 8 # 170 ª feminine ordinal indicator
+display \x00AB 1267 # 171 « left-pointing double angle quotation mark
+display \x00AC 2567 # 172 ¬ not sign
+display \x00AD 367 # 173 soft hyphen
+display \x00AE 2367 # 174 ® registered sign
+display \x00AF 267 # 175 ¯ macron
+display \x00B0 3567 # 176 ° degree sign
+
+display \x00C0 23578 # 192 À Latin capital letter a with grave
+display \x00C1 1678 # 193 Á Latin capital letter a with acute
+display \x00C2 16 # 194 Â Latin capital letter a with circumflex
+display \x00C3 578 # 195Ã Latin capital letter a with tilde
+display \x00C4 1234678 # 196Ä Latin capital letter a with diaeresis
+display \x00C5 34578 # 197Å Latin capital letter a with ring above
+display \x00C6 378 # 198Æ Latin capital letter ae
+display \x00C7 34678 # 199Ç Latin capital letter c with cedilla
+display \x00C8 23567 # 200 È Latin capital letter e with grave
+display \x00C9 12678 # 201É Latin capital letter e with acute
+display \x00CA 2378 # 202 Ê Latin capital letter e with circumflex
+display \x00CB 12345678 # 203Ë Latin capital letter e with diaeresis
+display \x00CC 23678 # 204Ì Latin capital letter i with grave
+display \x00CD 14678 # 205Í Latin capital letter i with acute
+display \x00CE 2578 # 206 Î Latin capital letter i with circumflex
+display \x00CF 1235678 # 207Ï Latin capital letter i with diaeresis
+display \x00D0 678 # 208Ð Latin capital letter eth
+display \x00D1 4678 # 209Ñ Latin capital letter n with tilde
+display \x00D2 3578 # 210Ò Latin capital letter o with grave
+display \x00D3 145678 # 211Ó Latin capital letter o with acute
+display \x00D4 25678 # 212 Ô Latin capital letter o with circumflex
+display \x00D5 5678 # 213Õ Latin capital letter o with tilde
+display \x00D6 234678 # 214Ö Latin capital letter o with diaeresis
+display \x00D7 167 # 215×multiplication sign
+display \x00D8 3478 # 216Ø Latin capital letter o with stroke
+display \x00D9 35678 # 217Ù Latin capital letter u with grave
+display \x00DA 15678 # 218Ú Latin capital letter u with acute
+display \x00DB 2678 # 219 Û Latin capital letter u with circumflex
+display \x00DC 2345678 # 220Ü Latin capital letter u with diaeresis
+display \x00DD 124678 # 221Ý Latin capital letter y with acute
+display \x00DE 3678 # 222Þ Latin capital letter thorn
+display \x00DF 345678 # 223ß Latin small letter sharp s
+display \x00E0 2358 # 224à Latin small letter a with grave
+display \x00E1 168 # 225á Latin small letter a with acute
+display \x00E2 16 # 226 â Latin small letter a with circumflex
+display \x00E3 58 # 227ã Latin small letter a with tilde
+display \x00E4 123468 # 228ä Latin small letter a with diaeresis
+display \x00E5 3458 # 229å Latin small letter a with ring above
+display \x00E6 38 # 230æ Latin small letter ae
+display \x00E7 3468 # 231ç Latin small letter c with cedilla
+display \x00E8 23568 # 232è Latin small letter e with grave
+display \x00E9 1268 # 233é Latin small letter e with acute
+display \x00EA 238 # 234 ê Latin small letter e with circumflex
+display \x00EB 1234568 # 235ë Latin small letter e with diaeresis
+display \x00EC 2368 # 236ì Latin small letter i with grave
+display \x00ED 1468 # 237í Latin small letter i with acute
+display \x00EE 258 # 238 î Latin small letter i with circumflex
+display \x00EF 123568 # 239ï Latin small letter i with diaeresis
+display \x00F0 68 # 240ð Latin small letter eth
+display \x00F1 468 # 241ñ Latin small letter n with tilde
+display \x00F2 358 # 242ò Latin small letter o with grave
+display \x00F3 14568 # 243ó Latin small letter o with acute
+display \x00F4 2568 # 244 ô Latin small letter o with circumflex
+display \x00F5 568 # 245õ Latin small letter o with tilde
+display \x00F6 23468 # 246ö Latin small letter o with diaeresis
+display \x00F7 347 # 247÷division sign
+display \x00F8 348 # 248ø Latin small letter o with stroke
+display \x00F9 3568 # 249ù Latin small letter u with grave
+display \x00FA 1568 # 250ú Latin small letter u with acute
+display \x00FB 268 # 251 û Latin small letter u with circumflex
+display \x00FC 234568 # 252ü Latin small letter u with diaeresis
+display \x00FD 12468 # 253ý Latin small letter y with acute
+display \x00FE 368 # 254þ Latin small letter thorn
+display \x00FF 34568 # 255ÿ Latin small letter y with diaeresis
+
+
+display \x00BB 3457 # 187»right-pointing double angle quotation mark
+display \x00B9 27 # 185¹superscript one
+display \x00B2 237 # 178²superscript two
+display \x00B3 257 # 179³superscript three
+display \x00B1 3467 # 177±plus-minus sign
+display \x00D7 167 # 215×multiplication sign
+
+display \x00B7 467 # 183·middle dot
+
+display \x00BF 14567 # 191¿inverted question mark
+
+
+display \x00B6 2357 # 182¶pilcrow sign
+
+
+#Hex Dots Dec Char Description
+display \x00BC 123567 # 188¼vulgar fraction one quarter
+display \x00BD 1234567 # 189½vulgar fraction one half
+display \x00BE 234567 # 190¾vulgar fraction three quarters
+
+# Each of the three extended accent characters is the same as its conventional
+# compose character but with dot7 added:
+
+#Hex Dots Dec Char Description
+display \x00B4 37 # 180´acute accent
+display \x00B8 67 # 184¸cedilla
+
+
+# The two gender symbols are:
+
+#Hex Dots Dec Char Description
+display \x00BA 7 # 186ºmasculine ordinal indicator
+
+
+# The three remaining characters are:
+
+#Hex Dots Dec Char Description
+
+display \x00B5 567 # 181µmicro sign
+
+
+# The nonbreaking space is dots 7 and 8 because this presents a sequence of
+# nonbreaking spaces as a smooth low line segment.
+
+#Hex Dots Dec Char Description
+
diff --git a/tables/de-eurobrl6.dis b/tables/de-eurobrl6.dis
new file mode 100644
index 0000000..932a4eb
--- /dev/null
+++ b/tables/de-eurobrl6.dis
@@ -0,0 +1,98 @@
+# liblouis: German Eurobraille Display Table
+#
+# Copyright (C) 2009 SBS Schweizerische Bibliothek für Blinde und Sehbehinderte
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#-------------------------------------------------------------------------------
+#
+# EUROBRAILLE DISPLAY TABLE
+#
+# This character mapping of 6-dot braille is widely being
+# used in german speaking parts of europe.
+#
+# Version 2009-11-19
+# christian.waldvogel@sbszh.ch
+#
+#-------------------------------------------------------------------------------
+
+display \s 0
+display a 1
+display b 12
+display c 14
+display d 145
+display e 15
+display f 124
+display g 1245
+display h 125
+display i 24
+display j 245
+display k 13
+display l 123
+display m 134
+display n 1345
+display o 135
+display p 1234
+display q 12345
+display r 1235
+display s 234
+display t 2345
+display u 136
+display v 1236
+display x 1346
+display y 13456
+display z 1356
+display & 12346
+display % 123456
+display { 12356
+display ~ 2346
+display } 23456
+display 1 16
+display 2 126
+display 3 146
+display 4 1456
+display 5 156
+display 6 1246
+display 7 12456
+display 8 1256
+display 9 246
+display w 2456
+display , 2
+display ; 23
+display : 25
+display / 256
+display ? 26
+display + 235
+display = 2356
+display ( 236
+display * 35
+display ) 356
+display . 3
+display - 36
+display | 34
+display 0 346
+display ` 345
+display # 3456
+display " 4
+display ! 5
+display > 45
+display $ 46
+# according to the standard it should be \x007F but _ seems more convenient and used more widely
+# display \x007F 456
+display _ 456
+display < 56
+display ' 6
diff --git a/tables/de-eurobrl6u.dis b/tables/de-eurobrl6u.dis
new file mode 100644
index 0000000..3e87eac
--- /dev/null
+++ b/tables/de-eurobrl6u.dis
@@ -0,0 +1,96 @@
+# liblouis: "Upshifted" German Eurobraille Display Table
+#
+# Copyright (C) 2009 SBS Schweizerische Bibliothek für Blinde und Sehbehinderte
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#-------------------------------------------------------------------------------
+#
+# "Upshifted" Version of EUROBRAILLE
+#
+# This "upshifted" version of de-eurobrl6.dis
+# is (sometimes) being used in Switzerland.
+#
+# Version 2009-11-19
+# christian.waldvogel@sbszh.ch
+#
+#-------------------------------------------------------------------------------
+
+display \s 0
+display A 1
+display B 12
+display C 14
+display D 145
+display E 15
+display F 124
+display G 1245
+display H 125
+display I 24
+display J 245
+display K 13
+display L 123
+display M 134
+display N 1345
+display O 135
+display P 1234
+display Q 12345
+display R 1235
+display S 234
+display T 2345
+display U 136
+display V 1236
+display X 1346
+display Y 13456
+display Z 1356
+display & 12346
+display % 123456
+display [ 12356
+display ^ 2346
+display ] 23456
+display 1 16
+display 2 126
+display 3 146
+display 4 1456
+display 5 156
+display 6 1246
+display 7 12456
+display 8 1256
+display 9 246
+display W 2456
+display , 2
+display ; 23
+display : 25
+display / 256
+display ? 26
+display + 235
+display = 2356
+display ( 236
+display * 35
+display ) 356
+display . 3
+display - 36
+display \\ 34
+display 0 346
+display @ 345
+display # 3456
+display " 4
+display ! 5
+display > 45
+display $ 46
+display _ 456
+display < 56
+display ' 6
diff --git a/tables/de-g0-core.uti b/tables/de-g0-core.uti
new file mode 100644
index 0000000..0803da1
--- /dev/null
+++ b/tables/de-g0-core.uti
@@ -0,0 +1,669 @@
+# liblouis: German grade 0 braille
+#
+# Copyright (C) 2018 SBS Schweizerische Bibliothek für Blinde, Seh- und Lesebehinderte
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#-------------------------------------------------------------------------------
+
+
+# --- Corrects -----------------------------------------------------------------
+
+# --- Korrektur der Bindestrich-Probleme
+
+# Bindestrich nach Leerschlag vor Zahl ist Minuszeichen.
+noback correct $s["-"]$d "\x2212"
+# Bindestrich nach öffnender Klammer vor Zahl ist Minuszeichen.
+noback correct ["(-"]$d "(\x2212"
+noback correct ["[-"]$d "[\x2212"
+# begword nach Wortersatzstrich verhindern
+noback correct $s["-"] "-\x250A"
+# begword Wortersatzstrich nach Schrägstrich verhindern
+noback correct ["/-"]$l "/\x2013\x250A"
+# endword vor Wortersatzstrich verhindern
+noback correct "-\s" "\x250A-\s"
+# endword vor Wortersatzstrich und Komma verhindern
+noback correct "-,\s" "\x250A-,\s"
+
+# --- Satzzeichen im Wort: Keine Wortgrenze
+
+noback correct $l["("]$l "\x250A(\x250A"
+noback correct $l[")"]$l "\x250A)\x250A"
+noback correct $l["["]$l "\x250A[\x250A"
+noback correct $l["]"]$l "\x250A]\x250A"
+noback correct $l["»"]$l "\x250A»\x250A"
+noback correct $l["«"]$l "\x250A«\x250A"
+noback correct $l["\x2039"]$l "\x250A\x2039\x250A"
+noback correct $l["\x203a"]$l "\x250A\x203a\x250A"
+
+# --- Apostroph, Punkt, Komma, Strich vor Zahl
+
+noback correct $d["'"]$d "."
+noback correct ["'"]$d "\x2500"
+noback correct $dl["."]$d "."
+noback correct ["."]$d "\x2501"
+noback correct ["--."]$d "\x2510"
+noback correct ["\x2013."]$d "\x2510"
+noback correct ["\x2014."]$d "\x2510"
+noback correct ["--,"]$d "\x2511"
+noback correct ["\x2013,"]$d "\x2511"
+noback correct ["\x2014,"]$d "\x2511"
+
+# --- Dagger ("gestorben")
+
+noback correct ["\x2020"] "gest."
+
+# --- Satzzeichen nach zahlenähnlichen Zeichen
+
+class puncAfterOrdinal ;:?!()[]\x00AB\x00BB
+# Prozent
+noback correct ["%"]%puncAfterOrdinal "%\x250B"
+noback correct ["%,"] "%\x256C,"
+# Promille
+noback correct ["\x2030"]%puncAfterOrdinal "\x2030\x250B"
+noback correct ["\x2030,"] "\x2030\x256C,"
+# Grad
+noback correct ["\x00B0"]%puncAfterOrdinal "\x00B0\x250B"
+noback correct ["\x00B0,"] "\x00B0\x256C,"
+# Superscript 2
+noback correct ["\x00B2"]%puncAfterOrdinal "\x00B2\x250B"
+noback correct ["\x00B2,"] "\x00B2\x256C,"
+# Superscript 3
+noback correct ["\x00B3"]%puncAfterOrdinal "\x00B3\x250B"
+noback correct ["\x00B3,"] "\x00B3\x256C,"
+noback correct "\x00BC"[]%puncAfterOrdinal "\x250B"
+noback correct "\x00BD"[]%puncAfterOrdinal "\x250B"
+noback correct "\x00BE"[]%puncAfterOrdinal "\x250B"
+noback correct "\x2153"[]%puncAfterOrdinal "\x250B"
+noback correct "\x2154"[]%puncAfterOrdinal "\x250B"
+noback correct "\x2155"[]%puncAfterOrdinal "\x250B"
+noback correct "\x2156"[]%puncAfterOrdinal "\x250B"
+noback correct "\x2157"[]%puncAfterOrdinal "\x250B"
+noback correct "\x2158"[]%puncAfterOrdinal "\x250B"
+noback correct "\x2159"[]%puncAfterOrdinal "\x250B"
+noback correct "\x215a"[]%puncAfterOrdinal "\x250B"
+noback correct "\x215b"[]%puncAfterOrdinal "\x250B"
+noback correct "\x215c"[]%puncAfterOrdinal "\x250B"
+noback correct "\x215d"[]%puncAfterOrdinal "\x250B"
+noback correct "\x215e"[]%puncAfterOrdinal "\x250B"
+
+# --- Brüche vor Komma
+
+noback correct "\x00BC"[]"," "\x256C"
+noback correct "\x00BD"[]"," "\x256C"
+noback correct "\x00BE"[]"," "\x256C"
+noback correct "\x2153"[]"," "\x256C"
+noback correct "\x2154"[]"," "\x256C"
+noback correct "\x2155"[]"," "\x256C"
+noback correct "\x2156"[]"," "\x256C"
+noback correct "\x2157"[]"," "\x256C"
+noback correct "\x2158"[]"," "\x256C"
+noback correct "\x2159"[]"," "\x256C"
+noback correct "\x215a"[]"," "\x256C"
+noback correct "\x215b"[]"," "\x256C"
+noback correct "\x215c"[]"," "\x256C"
+noback correct "\x215d"[]"," "\x256C"
+noback correct "\x215e"[]"," "\x256C"
+
+# --- Markieren von Zahl-Buchstabenverbindung für Kurzschrift
+
+noback correct $d["bis"]!$l "b\x250Ais"
+noback correct $d[]$l "\x2504"
+
+# --- Braille indicator opcodes ------------------------------------------------
+
+# "Fake"-use of capitalization (removed by pass2)
+capsletter 46a
+begcapsword 45a
+endcapsword 45b
+begcaps 45a
+endcaps 45b
+
+numsign 3456
+
+# --- Emphasis opcodes ---------------------------------------------------------
+
+emphclass italic
+emphclass underline
+emphclass bold
+
+begemphphrase italic 456-456
+endemphphrase italic after 6-3
+lenemphphrase italic 2
+begemphword italic 456
+
+begemphphrase bold 456-456
+endemphphrase bold after 6-3
+lenemphphrase bold 2
+begemphword bold 456
+
+begemphphrase underline 456-456
+endemphphrase underline after 6-3
+lenemphphrase underline 2
+begemphword underline 456
+
+begcomp 6-46
+# endcomp 6-3 # Omitted here (only to be used when longer than one word)
+
+# --- Special Symbol Opcodes ---------------------------------------------------
+
+hyphen - 36
+
+# --- Translation opcodes ------------------------------------------------------
+
+include litdigits6Dots.uti
+
+midnum , 2
+endnum ; 6-23
+
+endnum ? 6-26
+midword ? 6-26
+always \s? 0-6-26
+always (? 2356-6-26
+
+endnum ! 6-235
+midword ! 6-235
+always \s! 0-6-235
+noback always ! 235
+
+midword : 6-25
+
+midword ( 6-2356
+midnum ( 6-2356-3456
+endnum ( 6-2356
+noback always ( 2356
+
+midword ) 6-2356
+midnum ) 6-2356-3456
+endnum ) 6-2356
+noback always ) 2356
+
+midword [ 6-6-2356
+midnum [ 6-6-2356-3456
+endnum [ 6-6-2356
+midword ] 6-6-2356
+midnum ] 6-6-2356-3456
+endnum ] 6-6-2356
+
+always { 5-12356
+always } 5-12356
+
+prepunc " 236
+prepunc « 236
+prepunc » 236
+prepunc \x201f 236
+
+endnum " 6-356
+postpunc " 356
+endnum » 6-356
+postpunc » 356
+endnum « 6-356
+postpunc « 356
+endnum \x201f 6-356
+postpunc \x201f 356
+
+midword » 6-236
+midword « 6-356
+midword \x2039 6-6-356
+midword \x203a 6-6-236
+
+midnum . 3
+always .\s.\s. 3-3-3
+
+always # 4-3456
+
+always ** 6-35-35
+always *** 6-35-35-35
+
+prepunc \x2039 6-236
+prepunc \x203a 6-236
+prepunc \x201b 6-236
+postpunc \x2039 6-356
+postpunc \x203a 6-356
+postpunc \x201b 6-356
+
+always \x2192 25-25-135
+always \x2190 246-25-25
+always \x2194 246-25-25-135
+
+always & 5-136
+
+always % 3456-245-356
+always \s% 3456-245-356
+always \s\x2030 3456-245-356-356
+always \s\x2031 3456-245-356-356-356
+
+always \s° 4-356
+always \s\x2032 4-35
+always \s\x2033 4-35-35
+
+joinnum § 346
+joinnum §§ 346-346
+word § 4-346
+word §§ 4-346-346
+
+endnum .-- 3-36a-36a
+endnum .\x2013 3-36a-36a
+endnum ,-- 2-36a-36a
+endnum ,\x2013 2-36a-36a
+
+always \s-\s 6-36a-0
+always \s-- 6-36a
+always -- 6-36a
+always \s\x2013 6-36a
+always \x2013 6-36a
+always \s\x2014 6-36a
+always \x2014 6-36a
+
+always / 5-2
+always | 5-36
+
+joinnum £ 4-123
+joinnum $ 4-234
+always $ 4-234
+joinnum ¢ 4-14
+joinnum ¥ 4-13456
+joinnum \x20A0 4-15
+joinnum \x20AC 4-15
+
+begnum +\s 4-235
+midnum \s+\s 0-4-235-3456
+midnum \s+ 0-4-235-3456
+midnum + 0-4-235-3456
+always + 4-235
+
+begnum \s- 0-4-36a-3456
+always \s- 0-6-36a
+begnum \x2212\s 4-36a
+midnum \s\x2212\s 0-4-36a-3456
+midnum \s\x2212 0-4-36a-3456
+midnum \x2212 0-4-36a-3456
+always \x2212 4-36a
+
+midnum \s±\s 0-4-235-36a-3456
+midnum \s± 0-4-235-36a-3456
+midnum ± 0-4-235-36a-3456
+always ± 4-235-36a
+
+begnum =\s 4-2356
+midnum \s=\s 0-4-2356-3456
+midnum \s= 0-4-2356-3456
+midnum = 0-4-2356-3456
+always = 4-2356
+
+midnum \s\x2260\s 0-4-35-2356-3456
+midnum \s\x2260 0-4-35-2356-3456
+midnum \x2260 0-4-35-2356-3456
+always \x2260 4-35-2356
+
+midnum \s\x2261\s 0-4-2356-2356-3456
+midnum \s\x2261 0-4-2356-2356-3456
+midnum \x2261 0-4-2356-2356-3456
+always \x2261 4-2356-2356
+
+midnum \s\x2259\s 0-4-26-3456
+midnum \s\x2259 0-4-26-3456
+midnum \x2259 0-4-26-3456
+always \x2259 4-26
+
+midnum \s~\s 0-4-26-26-3456
+midnum \s~ 0-4-26-26-3456
+midnum ~ 0-4-26-26-3456
+always ~ 0-4-26-26
+midnum \s\x223C\s 0-4-26-26-3456
+midnum \s\x223C 0-4-26-26-3456
+midnum \x223C 0-4-26-26-3456
+always \x223C 4-26-26
+midnum \s\x2245\s 0-4-26-26-3456
+midnum \s\x2245 0-4-26-26-3456
+midnum \x2245 0-4-26-26-3456
+always \x2245 4-26-26
+
+begnum \x00D7\s 4-236
+midnum \s\x00D7\s 0-4-236-3456
+midnum \s\x00D7 0-4-236-3456
+midnum \x00D7 0-4-236-3456
+always \x00D7 4-236
+midnum \s\x2217\s 3-3456
+midnum \s\x2217 3-3456
+midnum \x2217 3-3456
+midnum \s*\s 3-3456
+midnum \s* 3-3456
+midnum * 3-3456
+always * 6-35 (Anmerkungsstern)
+midnum \s\x22c5\s 3-3456
+midnum \s\x22c5 3-3456
+midnum \x22c5 3-3456
+midnum \s\x22c6\s 3-3456
+midnum \s\x22c6 3-3456
+midnum \x22c6 3-3456
+
+midnum \s:\s 4-25-3456
+midnum \s: 4-25-3456
+midnum : 4-25-3456
+endnum : 6-25
+begnum ÷\s 4-25
+midnum \s÷\s 0-4-25-3456
+midnum \s÷ 0-4-25-3456
+midnum ÷ 0-4-25-3456
+always ÷ 4-25
+midnum \s\x2215\s 0-4-25-3456
+midnum \s\x2215 0-4-25-3456
+midnum \x2215 0-4-25-3456
+always \x2215 4-25
+
+midnum \s<\s 0-4-246-3-3456
+midnum \s< 0-4-246-3-3456
+midnum < 0-4-246-3-3456
+always < 4-246-3
+
+midnum \s\x2264\s 0-4-246-2356-3456
+midnum \s\x2264 0-4-246-2356-3456
+midnum \x2264 0-4-246-2356-3456
+always \x2264 4-246-2356
+midnum \s\x2266\s 0-4-246-2356-3456
+midnum \s\x2266 0-4-246-2356-3456
+midnum \x2266 0-4-246-2356-3456
+always \x2266 4-246-2356
+
+midnum \s>\s 0-4-135-2-3456
+midnum \s> 0-4-135-2-3456
+midnum > 0-4-135-2-3456
+always > 4-135-2
+
+midnum \s\x2265\s 0-4-135-2356-3456
+midnum \s\x2265 0-4-135-2356-3456
+midnum \x2265 0-4-135-2356-3456
+always \x2265 4-135-2356
+midnum \s\x2267\s 0-4-135-2356-3456
+midnum \s\x2267 0-4-135-2356-3456
+midnum \x2267 0-4-135-2356-3456
+always \x2267 4-135-2356
+
+# --- 6-Dot Computer Braille ---------------------------------------------------
+
+include countries.cti
+compbrl :// URLs
+compbrl www.
+compbrl @ Mail-address
+compbrl .com
+compbrl .edu
+compbrl .gov
+compbrl .mil
+compbrl .net
+compbrl .org
+compbrl .doc
+compbrl .htm
+compbrl .html
+compbrl .tex
+compbrl .txt
+compbrl .gif
+compbrl .jpg
+compbrl .png
+compbrl .wav
+compbrl .tar
+compbrl .zip
+
+#comp6 \x0020 0   SPACE
+comp6 \x0021 5 ! EXCLAMATION MARK
+comp6 \x0022 4-4 " QUOTATION MARK
+comp6 \x0023 3456 # NUMBER SIGN
+comp6 \x0024 46-46 $ DOLLAR SIGN
+comp6 \x0025 123456 % PERCENT SIGN
+comp6 \x0026 12346 & AMPERSAND
+comp6 \x0027 6-6 ' APOSTROPHE APOSTROPHE-QUOTE
+comp6 \x0028 236 ( LEFT PARENTHESIS
+comp6 \x0029 356 ) RIGHT PARENTHESIS
+comp6 \x002A 35 * ASTERISK
+comp6 \x002B 235 + PLUS SIGN
+comp6 \x002C 2 , COMMA
+comp6 \x002D 36 - HYPHEN-MINUS
+comp6 \x002E 3 . FULL STOP PERIOD
+comp6 \x002F 256 / SOLIDUS SLASH
+comp6 \x0030 346 0 DIGIT ZERO
+comp6 \x0031 16 1 DIGIT ONE
+comp6 \x0032 126 2 DIGIT TWO
+comp6 \x0033 146 3 DIGIT THREE
+comp6 \x0034 1456 4 DIGIT FOUR
+comp6 \x0035 156 5 DIGIT FIVE
+comp6 \x0036 1246 6 DIGIT SIX
+comp6 \x0037 12456 7 DIGIT SEVEN
+comp6 \x0038 1256 8 DIGIT EIGHT
+comp6 \x0039 246 9 DIGIT NINE
+comp6 \x003A 25 : COLON
+comp6 \x003B 23 ; SEMICOLON
+comp6 \x003C 56 < LESS-THAN SIGN
+comp6 \x003D 2356 = EQUALS SIGN
+comp6 \x003E 45 > GREATER-THAN SIGN
+comp6 \x003F 26 ? QUESTION MARK
+comp6 \x0040 4-345 @ COMMERCIAL AT
+comp6 \x0041 4-1 A LATIN CAPITAL LETTER A
+comp6 \x0042 4-12 B LATIN CAPITAL LETTER B
+comp6 \x0043 4-14 C LATIN CAPITAL LETTER C
+comp6 \x0044 4-145 D LATIN CAPITAL LETTER D
+comp6 \x0045 4-15 E LATIN CAPITAL LETTER E
+comp6 \x0046 4-124 F LATIN CAPITAL LETTER F
+comp6 \x0047 4-1245 G LATIN CAPITAL LETTER G
+comp6 \x0048 4-125 H LATIN CAPITAL LETTER H
+comp6 \x0049 4-24 I LATIN CAPITAL LETTER I
+comp6 \x004A 4-245 J LATIN CAPITAL LETTER J
+comp6 \x004B 4-13 K LATIN CAPITAL LETTER K
+comp6 \x004C 4-123 L LATIN CAPITAL LETTER L
+comp6 \x004D 4-134 M LATIN CAPITAL LETTER M
+comp6 \x004E 4-1345 N LATIN CAPITAL LETTER N
+comp6 \x004F 4-135 O LATIN CAPITAL LETTER O
+comp6 \x0050 4-1234 P LATIN CAPITAL LETTER P
+comp6 \x0051 4-12345 Q LATIN CAPITAL LETTER Q
+comp6 \x0052 4-1235 R LATIN CAPITAL LETTER R
+comp6 \x0053 4-234 S LATIN CAPITAL LETTER S
+comp6 \x0054 4-2345 T LATIN CAPITAL LETTER T
+comp6 \x0055 4-136 U LATIN CAPITAL LETTER U
+comp6 \x0056 4-1236 V LATIN CAPITAL LETTER V
+comp6 \x0057 4-2456 W LATIN CAPITAL LETTER W
+comp6 \x0058 4-1346 X LATIN CAPITAL LETTER X
+comp6 \x0059 4-13456 Y LATIN CAPITAL LETTER Y
+comp6 \x005A 4-1356 Z LATIN CAPITAL LETTER Z
+comp6 \x005B 4-12356 [ LEFT SQUARE BRACKET
+comp6 \x005C 4-34 \ REVERSE SOLIDUS
+comp6 \x005D 4-23456 ] RIGHT SQUARE BRACKET
+comp6 \x005E 4-2346 ^ CIRCUMFLEX ACCENT
+comp6 \x005F 4-456 _ LOW LINE
+comp6 \x0060 345 ` GRAVE ACCENT
+comp6 \x0061 1 a LATIN SMALL LETTER A
+comp6 \x0062 12 a LATIN SMALL LETTER B
+comp6 \x0063 14 a LATIN SMALL LETTER C
+comp6 \x0064 145 a LATIN SMALL LETTER D
+comp6 \x0065 15 a LATIN SMALL LETTER E
+comp6 \x0066 124 a LATIN SMALL LETTER F
+comp6 \x0067 1245 a LATIN SMALL LETTER G
+comp6 \x0068 125 a LATIN SMALL LETTER H
+comp6 \x0069 24 a LATIN SMALL LETTER I
+comp6 \x006A 245 a LATIN SMALL LETTER J
+comp6 \x006B 13 a LATIN SMALL LETTER K
+comp6 \x006C 123 a LATIN SMALL LETTER L
+comp6 \x006D 134 a LATIN SMALL LETTER M
+comp6 \x006E 1345 a LATIN SMALL LETTER N
+comp6 \x006F 135 o LATIN SMALL LETTER O
+comp6 \x0070 1234 p LATIN SMALL LETTER P
+comp6 \x0071 12345 q LATIN SMALL LETTER Q
+comp6 \x0072 1235 r LATIN SMALL LETTER R
+comp6 \x0073 234 s LATIN SMALL LETTER S
+comp6 \x0074 2345 t LATIN SMALL LETTER T
+comp6 \x0075 136 u LATIN SMALL LETTER U
+comp6 \x0076 1236 v LATIN SMALL LETTER V
+comp6 \x0077 2456 w LATIN SMALL LETTER W
+comp6 \x0078 1346 x LATIN SMALL LETTER X
+comp6 \x0079 13456 y LATIN SMALL LETTER Y
+comp6 \x007A 1356 z LATIN SMALL LETTER Z
+comp6 \x007B 12356 { LEFT CURLY BRACKET
+comp6 \x007C 34 | VERTICAL LINE
+comp6 \x007D 23456 } RIGHT CURLY BRACKET
+comp6 \x007E 2346 ~ TILDE
+comp6 \x00A1 4-36 ¡ INVERTED EXCLAMATION MARK
+comp6 \x00A2 6-5 ¢ CENT SIGN
+comp6 \x00A3 4-46 £ POUND SIGN
+comp6 \x00A4 46-46 ¤ CURRENCY SIGN
+comp6 \x00A5 6-46 ¥ YEN SIGN
+comp6 \x00A6 6-15 ¦ BROKEN BAR
+comp6 \x00A7 4-35 § SECTION SIGN
+comp6 \x00A8 6-4 ¨ DIAERESIS
+comp6 \x00A9 6-12346 © COPYRIGHT SIGN
+comp6 \x00AA 6-125 ª FEMININE ORDINAL INDICATOR
+comp6 \x00AB 46-56 « LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+comp6 \x00AC 46-256 ¬ NOT SIGN
+comp6 \x00AD 6-36 ­ SOFT HYPHEN
+comp6 \x00AE 6-1235 ® REGISTERED SIGN
+comp6 \x00AF 6-45 ¯ MACRON
+comp6 \x00B0 6-456 ° DEGREE SIGN
+comp6 \x00B1 46-235 ± PLUS-MINUS SIGN
+comp6 \x00B2 6-12 ² SUPERSCRIPT TWO
+comp6 \x00B3 6-14 ³ SUPERSCRIPT THREE
+comp6 \x00B4 6-56 ´ ACUTE ACCENT
+comp6 \x00B5 6-134 µ MICRO SIGN
+comp6 \x00B6 6-145 ¶ PILCROW SIGN
+comp6 \x00B7 4-3 · MIDDLE DOT
+comp6 \x00B8 6-6 ¸ CEDILLA
+comp6 \x00B9 6-1 ¹ SUPERSCRIPT ONE
+comp6 \x00BA 6-245 º MASCULINE ORDINAL INDICATOR
+comp6 \x00BB 46-45 » RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+comp6 \x00BC 6-136 ¼ VULGAR FRACTION ONE QUARTER
+comp6 \x00BD 6-1236 ½ VULGAR FRACTION ONE HALF
+comp6 \x00BE 6-1346 ¾ VULGAR FRACTION THREE QUARTERS
+comp6 \x00BF 6-3 ¿ INVERTED QUESTION MARK
+comp6 \x00C0 46-236 À LATIN CAPITAL LETTER A WITH GRAVE
+comp6 \x00C1 6-2 Á LATIN CAPITAL LETTER A WITH ACUTE
+comp6 \x00C2 4-16 Â LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+comp6 \x00C3 4-346 Ã LATIN CAPITAL LETTER A WITH TILDE
+comp6 \x00C4 4-56 Ä LATIN CAPITAL LETTER A WITH DIAERESIS
+comp6 \x00C5 4-3456 Å LATIN CAPITAL LETTER A WITH RING ABOVE
+comp6 \x00C6 4-4 Æ LATIN CAPITAL LETTER AE
+comp6 \x00C7 4-12346 Ç LATIN CAPITAL LETTER C WITH CEDILLA
+comp6 \x00C8 46-35 È LATIN CAPITAL LETTER E WITH GRAVE
+comp6 \x00C9 4-123456 É LATIN CAPITAL LETTER E WITH ACUTE
+comp6 \x00CA 4-126 Ê LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+comp6 \x00CB 6-235 Ë LATIN CAPITAL LETTER E WITH DIAERESIS
+comp6 \x00CC 4-5 Ì LATIN CAPITAL LETTER I WITH GRAVE
+comp6 \x00CD 6-25 Í LATIN CAPITAL LETTER I WITH ACUTE
+comp6 \x00CE 4-146 Î LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+comp6 \x00CF 6-2356 Ï LATIN CAPITAL LETTER I WITH DIAERESIS
+comp6 \x00D0 4-356 Ð LATIN CAPITAL LETTER ETH
+comp6 \x00D1 4-256 Ñ LATIN CAPITAL LETTER N WITH TILDE
+comp6 \x00D2 46-5 Ò LATIN CAPITAL LETTER O WITH GRAVE
+comp6 \x00D3 6-256 Ó LATIN CAPITAL LETTER O WITH ACUTE
+comp6 \x00D4 4-1456 Ô LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+comp6 \x00D5 4-26 Õ LATIN CAPITAL LETTER O WITH TILDE
+comp6 \x00D6 6-35 Ö LATIN CAPITAL LETTER O WITH DIAERESIS
+comp6 \x00D7 6-234 × MULTIPLICATION SIGN
+comp6 \x00D8 4-246 Ø LATIN CAPITAL LETTER O WITH STROKE
+comp6 \x00D9 46-356 Ù LATIN CAPITAL LETTER U WITH GRAVE
+comp6 \x00DA 6-26 Ú LATIN CAPITAL LETTER U WITH ACUTE
+comp6 \x00DB 4-156 Û LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+comp6 \x00DC 6-236 Ü LATIN CAPITAL LETTER U WITH DIAERESIS
+comp6 \x00DD 6-356 Ý LATIN CAPITAL LETTER Y WITH ACUTE
+comp6 \x00DE 4-235 Þ LATIN CAPITAL LETTER THORN
+comp6 \x00DF 6-3456 ß LATIN SMALL LETTER SHARP S
+comp6 \x00E0 6-12356 à LATIN SMALL LETTER A WITH GRAVE
+comp6 \x00E1 6-16 á LATIN SMALL LETTER A WITH ACUTE
+comp6 \x00E2 46-16 â LATIN SMALL LETTER A WITH CIRCUMFLEX
+comp6 \x00E3 46-346 ã LATIN SMALL LETTER A WITH TILDE
+comp6 \x00E4 6-345 ä LATIN SMALL LETTER A WITH DIAERESIS
+comp6 \x00E5 46-3456 å LATIN SMALL LETTER A WITH RING ABOVE
+comp6 \x00E6 46-4 æ LATIN SMALL LETTER AE
+comp6 \x00E7 46-12346 ç LATIN SMALL LETTER C WITH CEDILLA
+comp6 \x00E8 6-2346 è LATIN SMALL LETTER E WITH GRAVE
+comp6 \x00E9 6-123456 é LATIN SMALL LETTER E WITH ACUTE
+comp6 \x00EA 46-126 ê LATIN SMALL LETTER E WITH CIRCUMFLEX
+comp6 \x00EB 6-1246 ë LATIN SMALL LETTER E WITH DIAERESIS
+comp6 \x00EC 6-34 ì LATIN SMALL LETTER I WITH GRAVE
+comp6 \x00ED 6-146 í LATIN SMALL LETTER I WITH ACUTE
+comp6 \x00EE 46-146 î LATIN SMALL LETTER I WITH CIRCUMFLEX
+comp6 \x00EF 6-12456 ï LATIN SMALL LETTER I WITH DIAERESIS
+comp6 \x00F0 6-2345 ð LATIN SMALL LETTER ETH
+comp6 \x00F1 6-1345 ñ LATIN SMALL LETTER N WITH TILDE
+comp6 \x00F2 6-346 ò LATIN SMALL LETTER O WITH GRAVE
+comp6 \x00F3 6-1456 ó LATIN SMALL LETTER O WITH ACUTE
+comp6 \x00F4 46-1456 ô LATIN SMALL LETTER O WITH CIRCUMFLEX
+comp6 \x00F5 6-135 õ LATIN SMALL LETTER O WITH TILDE
+comp6 \x00F6 6-246 ö LATIN SMALL LETTER O WITH DIAERESIS
+comp6 \x00F7 46-1256 ÷ DIVISION SIGN
+comp6 \x00F8 46-246 ø LATIN SMALL LETTER O WITH STROKE
+comp6 \x00F9 6-23456 ù LATIN SMALL LETTER U WITH GRAVE
+comp6 \x00FA 6-156 ú LATIN SMALL LETTER U WITH ACUTE
+comp6 \x00FB 46-156 û LATIN SMALL LETTER U WITH CIRCUMFLEX
+comp6 \x00FC 6-1256 ü LATIN SMALL LETTER U WITH DIAERESIS
+comp6 \x00FD 6-2456 ý LATIN SMALL LETTER Y WITH ACUTE
+comp6 \x00FE 6-1234 þ LATIN SMALL LETTER THORN
+comp6 \x00FF 6-13456 ÿ LATIN SMALL LETTER Y WITH DIAERESIS
+
+
+# --- Handling of virtual dots -------------------------------------------------
+
+# Kürzungsverbot entfernen
+noback pass2 @abcdef ?
+# Grosschreibungsmarken entfernen
+noback pass2 @46a ? # capsletter
+noback pass2 @45a ? # begcaps, begcapsword
+noback pass2 @45b ? # endcaps, endcapsword
+# Apostroph vor Zahl ('98)
+noback pass2 @3456-69 @3456-6
+# Punkt vor Zahl (.45)
+noback pass2 @3456-39 @3456-3
+# Dummy-Zahl entfernen
+noback pass2 @3456-b ?
+
+# Aufhebungspunkt vor Komma nach tiefgestellten Zahlen
+noback pass2 @ab @6
+
+# Fehlende Lettersigns bei Zahl-Buchstaben-Verbindung in Kurzschrift bei
+# Buchstaben a-j ergänzen
+noback pass2 @ac-1 @6-1
+noback pass2 @ac-12 @6-12
+noback pass2 @ac-14 @6-14
+noback pass2 @ac-145 @6-145
+noback pass2 @ac-15 @6-15
+noback pass2 @ac-124 @6-124
+noback pass2 @ac-1245 @6-1245
+noback pass2 @ac-125 @6-125
+noback pass2 @ac-24 @6-24
+noback pass2 @ac-245 @6-245
+# Lettersigns bei Zahl-Buchstaben-Verbindung in Kurzschrift erhalten
+noback pass2 @ac-6-1 @6-1
+noback pass2 @ac-6-12 @6-12
+noback pass2 @ac-6-14 @6-14
+noback pass2 @ac-6-145 @6-145
+noback pass2 @ac-6-15 @6-15
+noback pass2 @ac-6-124 @6-124
+noback pass2 @ac-6-1245 @6-1245
+noback pass2 @ac-6-125 @6-125
+noback pass2 @ac-6-24 @6-24
+noback pass2 @ac-6-245 @6-245
+# Restliche Lettersigns bei Zahl-Buchstaben-Verbindung in Kurzschrift entfernen
+noback pass2 @ac-6 ?
+# Markierung für Zahl-Buchstaben-Verbindung in Vollschrift entfernen
+noback pass2 @ac ?
+
+# Korrektur: Kürzung "des" zwischen Bindestrichen auflösen
+noback pass3 @36-3-36 @36-145-123456-36
+# Korrektur: Kürzung "im" vor Bindestrich oder zwischen Bindestrichen auflösen
+noback pass3 @36-36a-36 @36-24-134-36
+noback pass3 @36a-36 @24-134-36
+# Korrektur: Als Bindestrich geschriebens Minuszeichen vor Zahl
+noback pass3 @0-6-36a-6-3456 @0-4-36-3456
+# Korrektur: Kürzung "ver" nach Bindestrich auflösen
+noback pass3 @36[@36a] @1236-12456
+# Bei allen weiteren P36 virtuellen Punkt a entfernen
+noback pass3 @36a @36
diff --git a/tables/de-g0.utb b/tables/de-g0.utb
new file mode 100644
index 0000000..0df2598
--- /dev/null
+++ b/tables/de-g0.utb
@@ -0,0 +1,48 @@
+# liblouis: German Grade 0 Braille
+#
+# Das System der deutschen Blindenschrift (2015/2018)
+# http://www.bskdl.org/textschrift.html
+#
+# Bemerkung:
+# - Gross-/Kleinschreibung wird nicht berücksichtigt (d.h. für
+# Abkürzungen u.ä. braucht es Vorprogramm)
+# - Akzente: Hinweis auf die beiden Tabellen (bis jetzt nur als
+# Kommentar in de-g0.utb)
+#
+# -----------
+#-name: Deutsche Basisschrift
+#-index-name: German, uncontracted
+#-display-name: German uncontracted braille
+#
+#+locale:de
+#+type:literary
+#+contraction:no
+#+grade:0
+#+direction:forward
+# ------------
+#
+# Copyright (C) 2018 SBS Schweizerische Bibliothek für Blinde, Seh- und Lesebehinderte
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#-------------------------------------------------------------------------------
+
+include de-chardefs6.cti
+# for a detailed representation of french and italian accents un-comment the next line
+#include de-accents-detailed.cti
+include de-accents.cti
+include de-g0-core.uti
diff --git a/tables/de-g1-core-patterns.dic b/tables/de-g1-core-patterns.dic
new file mode 100644
index 0000000..1374b9d
--- /dev/null
+++ b/tables/de-g1-core-patterns.dic
@@ -0,0 +1,4863 @@
+UTF-8
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% auto-generated file, don't edit! %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+.aa1
+.aci1
+.ade1
+.adi1
+.ae1
+.age1
+.aids1
+.ai1
+.akkadi1
+.al1e1ut
+.alti1
+.amma1
+.anes1
+.ani1
+.apuli1
+.ari1
+.arzi1
+.assi1
+.asti1
+.athe1
+.audi1
+.aus1che
+.aus1ta
+.aus1t1eil
+.aus1tes
+.aus1th
+.aus1to
+.avers1
+.axi1
+.azi1
+.bedi2
+.belgi1
+.biss1
+.bis1tu
+.boe1
+.brus1c
+.cerisi1
+.ces1c
+.chi1en
+.chi1er
+.cobi1
+.couri1
+.cue1
+.d1e1i.
+.de1ind
+.de1inst
+.derni1
+.destri1
+.didi1
+.divi1
+.dizi1
+.dys1c
+.dys1ton
+.dys1tr
+.dzi1
+.echs1
+.ehe1
+.einge1
+.eises1
+.1eis
+.eis1ta
+.eis1tr
+.eis1tü
+.elis1che
+.els1c
+.emma1
+.enns1
+.1enn
+.1enti1
+.erzbis1t
+.1erzb
+.es1cha
+.ess1
+.essens1
+.es1th
+.fee1
+.fels1ti
+.fels1tu
+.fels1tü
+.feri1
+.fi1era
+.fres1c
+.gerli1
+.germani1
+.gri2
+.guri1
+.happi1
+.hari1
+.hi1erar
+.hilli1
+.hunde1
+.husse1
+.i1
+.ile1
+.imi1
+.ini1
+.intra1
+.ioni1
+.is1chä
+.isis1
+.istri1
+.izi1
+.joi1
+.jugi1
+.kassi1e.
+.kass1
+.ki1erb
+.kies1
+.kiss1
+.kolli1
+.kordi1
+.kuss1
+.lachs1te
+.lage1
+.lagni1
+.lanti1
+.leids1
+.lese1
+.li2en
+.ligni1
+.lili1
+.lori1
+.los1tr
+.lute1
+.läus1
+.mali1
+.mana1
+.mass1
+.medi1
+.meni1
+.meri1
+.mess1
+.meti1
+.mi1edo
+.mi1el.
+.mi1erz
+.moos1
+.mori1
+.morti1
+.muli1
+.muss1
+.nass1
+.ne1ii
+.ni2enb
+.ni1en
+.ni2end
+.nuss1
+.oe1
+.ogi1
+.oi1
+.olds1
+.orgi1
+.ori1
+.orki1
+.osteri1
+.pelli1
+.pelti1
+.perri1
+.pes1che.
+.pi1ed
+.pi1em
+.pi1era
+.pi1erd
+.pi1erf
+.pi1ern
+.pi1err
+.pi1ev
+.piss1
+.podi1
+.porti1er.
+.porti1ere.
+.porti1eren.
+.pri2en
+.pris1c
+.puni1
+.rabi1
+.raini1
+.rai1
+.rani1
+.re1inkon
+.re1insz
+.reis1che
+.r1eis
+.reli1
+.re1un
+.ri1esk
+.ringi1
+.rivi1
+.robi1er
+.rodi1
+.rogi1
+.roni1
+.rossi1
+.russ1
+.rös1chen.
+.safi1
+.sali1
+.sari1
+.sauri1
+.s1chiap
+.s1chool
+.see1
+.selli1
+.s1enti1
+.seri1e.
+.sevi1
+.sieges1
+.si1en
+.si1err
+.si1est
+.si1et
+.ski1er
+.sorbi1
+.s1t.
+.s1ta.
+.s2tag
+.studi1e.
+.tages1
+.tarsi1
+.tele1
+.telli1
+.teni1
+.tes1trä
+.thani1
+.ti1en.
+.ti1ev
+.tri1est
+.ugri1
+.uri1
+.urä1
+.vari1
+.veni1
+.vers1chen.
+.väs1c
+.weiss1
+.w1eis
+.wies1c
+.xi1
+.zebra1
+.zins1
+.zvi1
+.éti1
+'arvi1
+'bri1
+'oe1
+'offici1
+'ori1
+aadi1
+aani1
+aare1
+aas1ta
+aats1t
+abali1
+abetes1
+abre1u
+abäus1
+acchi1
+achs1tig
+achs1tum
+aci1er.
+aci1ers
+adde1
+adi1en.
+adi1ent
+adies1
+adoni1
+adungs1
+adä1
+a1e1i.
+aene1
+aere1u
+a1e1ub
+ae1um
+a1e1us
+affi1el
+afi1en.
+afi1ens
+afts1tem
+afts1trä
+afungs1
+age1id
+agi1ern
+agi1erzi
+agi1ez.
+agni1et
+agore1
+ags1tab
+ags1tal
+ags1tee
+ags1tem
+ags1term
+ags1th
+ags1tor
+ags1tre
+ags1tru
+ags1trä
+ags1tät
+ahe1u
+ahme1u
+ahäs1c
+ahös1c
+ai1
+aims1
+aintra1
+ais1chip
+aissi1
+ais1tor
+akadi1
+akmus1
+aknäs1
+alabri1
+alanti1
+ale1inp
+ale1uti
+al1eut
+alici1
+ali1eri
+ali1ern
+alile1
+alili1
+aline1
+alini1
+alizi1
+alleti1
+all1e1us
+alli1er.
+aloni1
+als1tit
+als1trau
+alstudi1
+aludi1
+amali1
+amandi1
+ambä1
+amera1
+ameri1
+ami1el
+ami1en.
+ami1erb
+ami1et
+amili1
+ammeri1
+amni1
+ams1tag
+ams1test
+anadi1
+anas1chi.
+ance1i
+ands1tag
+anebi1
+anesi1
+an1e1us
+anezi1
+angeri1et.
+angs1tes
+ani1ele
+ani1eli
+ani1els
+ani1ern
+ani1et.
+anqui1
+ansani1
+anseri1
+anspapi1
+ans1tor
+anthi1
+anti1en
+antons1
+aorgi1
+apali1
+aprämi1
+aragi1
+arali1
+aras1che.
+ara1un
+arce1
+ardini1
+arems1
+are1un
+ari1eh
+ari1en
+ari1era
+ari1erfa
+ari1erg
+ari1ers.
+ari1esf
+ari1ess
+ari1est
+ari1eta
+ari1eto
+armee1
+arm1enti1
+aroli2
+aroni1
+arri1er
+arri1et
+ars1tho
+arthi1
+arungs1
+asauri1
+asaus1
+ashi1
+asi1ek.
+asi1eri
+askus1
+asma1
+asmani1
+asowi1
+as1tev
+asthi1
+asti1en
+as1tink
+as1topf
+as1trep
+as1tür
+atbis1
+at1e1us
+athani1
+athe1u
+ati1el
+ati1en
+atoli1
+ats1chef
+ats1tem
+ats1tic
+ats1träu
+ats1tur
+attä1
+atungs1
+atus1t
+auci1
+aulmi1
+aupi1
+aure1u
+auri1er.
+auriti1
+ausseri1
+aus1tag
+aus1tanz
+aus1tea
+aus1tee
+aus1term
+aus1tick
+aus1tier
+aus1tig
+aus1tob
+aus1toi1
+aus1tom
+aus1tor
+aus1tot
+aus1tram
+aus1trat
+aus1trau
+aus1tric
+aus1trom
+austudi1
+aus1tup
+aus1tut
+aus1tür
+authi1
+averni1
+avri1
+awi1en
+aysi1
+azde1
+az1e1is
+azi1el
+azri1
+azzi1
+aéri1
+bade1
+badi1er
+bae1
+banki1
+bardi1e.
+bars1tal.
+bass1
+basti1
+bathi1
+bati1
+bdös1
+be1imm
+be1ing.
+be1inhalte.
+be1inhalten
+be1inhaltet
+beits1t
+beli1e.
+bens1tag
+bens1treu
+bens1tri
+bes1tag
+bes1tat.
+besti1e.
+bes1tod
+bes1tol
+bes1tou
+bes1trai1
+bes1trau
+bes1trun
+be1ufe
+b1euf
+be1uh
+be1um
+be1und
+be1ung
+be1unk
+be1unt
+be1urk
+b1eur
+be1url
+be1urt
+bgangs1
+bgas1
+bge1u
+bhös1
+bi1ell
+bi1en.
+bi1enb
+bi1ens
+bi1ent
+bilä1
+birs1ta
+bisis1
+bkr1eis1
+blage1
+blass1
+blas1test
+blese1
+bli1edl
+bli1er.
+bl1ings1
+bläs1c
+blöss1
+blüs1c
+bmagi1
+bnis1t
+bombi1
+bonni1er.
+borgi1
+bos1chel
+bosni1
+boulli1
+bpari1
+brani1
+brass1
+breli1
+bri1en
+bri1er.
+bri1ern
+bries1c
+brios1
+bsauri1
+bs1chef
+bseri1
+bsidi1
+bsstudi1
+bs1tag
+bs1tata
+bs1teic
+bs1t1eil
+bs1tob
+bs1tod
+bs1tou
+bs1treu
+bs1täti
+b1tags1
+bundes1
+bungs1c
+bussi1
+bus1tab
+bus1tei
+bus1term
+busti1
+bus1tis
+bus1tor
+bus1tr
+buzi1
+bäs1che1
+bä1us.
+béli1
+béri1
+böss1
+cadi1
+caffe1
+cafi1
+cahi1
+cale1
+cali1
+cami1
+canti1
+capes1
+carabini1
+carti1
+case1in
+casti1
+cavali1ere
+cavali1ers
+cce1
+ccheri1
+cchi1ere
+cegli1
+c1e1is
+cere1
+cerni1
+ces1chi
+c1e1u.
+ce1uh
+ce1um
+ce1un
+ce1us.
+c1eus
+1chaem
+1chaffela
+1champs
+1chanc
+1chanse
+1chansh
+1chanso
+1chaos1
+1chap.
+1charak
+chari1
+1chauff
+1checkl
+1chef.
+1chefr
+1chefs
+1chemie.
+1chemik
+1chemis
+1chen1ect
+1ch1eria
+1ch1eron
+1cherzan
+1cherzo
+1ch1etti
+1cheven
+1chiat
+1chiav
+1chicc
+1chieda
+chi1edi
+chi1edo
+1chieha
+chi1ern
+chi1esa
+1chietp
+1chi1ett
+1chillac
+1chillà
+1chimst
+1chini.
+1chinok
+1chinot
+1chio
+1chiph
+1chipl
+1chips
+1chirur
+1chirò
+1chizophr1enia1
+1chizz
+chnee1
+1chofi
+1chola.
+1cholars
+1cholastic
+1choles
+1chool.
+1choolb
+1choole
+1choolf
+1choolg
+1chools
+1choral
+1choreo
+1chores
+1chors.
+1chorä
+1christ
+1chromo
+1chron
+1chutn
+1chyl
+ci1eg
+ci1ek
+ci1el
+ci1enf
+ci1ens
+ci1ent
+ci1erg
+ci1eri
+ci1erp
+ci1err
+cili1
+cimi1
+cis1to
+ckaus1
+cki1el
+cki1en
+cki1est
+cks1tas
+cks1taub
+cks1turm
+ckungs1
+claudi1
+cle1
+cobs1t
+code1
+coe1
+coffe1
+coli1
+colli1er
+combi1
+comic1
+condotti1
+conti1
+cordi1
+cormi1
+cousi1
+coussi1
+couti1
+crassi1
+cressi1
+creti1
+crissi1
+cross1
+croupi1
+cseri1
+cudi1
+culi1
+cune1
+cuvi1
+cyste1
+dami1
+dani1el
+danti1
+dari1
+darni1er
+dasi1
+dats1t
+daumi1
+dauni1
+da1url
+dawi1
+dcolli1
+ddä1
+deaus1
+dechs1
+de1ik
+de1imp
+de1ino
+de1ist.
+d1eis
+de1isten
+de1isti
+de1ists2
+demi1en
+deni1er
+dens1tanz
+dens1top
+deorgi1
+des1chef
+des1tag
+des1tit
+des1tou
+des1trai1
+des1treu
+destudi1
+des1tät
+d1e1u.
+d1e1uf
+de1um
+de1un
+de1url
+d1eur
+de1us.
+d1eus
+dfoli1
+dhaus1
+dheits1
+dhäs1
+dhös1
+dia1
+didas1
+di1ek.
+di1elek
+di1em.
+di1enc
+di1end
+di1eng
+di1eni
+di1ens.
+di1ensc
+di1enz
+di1epp
+di1er'
+di1esse.
+di1et.
+di1ets.
+di1eva
+di1ez
+digli1
+dilli1
+dindi1
+diseri1
+diss1te
+dis1th
+dis1to
+ditschi1
+dji1
+dles1c
+dlili1
+dlos1
+dlungs1
+dmedi1
+dnuss1
+doni1er
+dorgi1
+dorni1
+dprämi1
+dreli1
+dress1
+dr1e1u.
+dr1e1us
+dri1el
+dri1en
+dri1eser
+driess1
+drowi1
+dsari1
+dsaus1
+ds1chine
+dsee1
+dseri1
+dski1
+ds1tabe
+ds1tag.
+ds1tagen
+ds1tas
+ds1tata
+ds1tauf
+ds1tea
+ds1t1eil
+ds1term
+ds1terr
+ds1t1eur
+ds1tex
+ds1th
+ds1tin
+ds1tis
+ds1tod
+ds1toi1
+ds1tor.
+ds1torp
+ds1tou
+ds1trau
+ds1trup
+ds1trü
+dstudi1
+ds1turb
+ds1tus
+ds1täti
+duilli1
+dus1tal
+dös1che
+1ea.
+eali1
+1eark
+earli1
+ease1
+easi1
+ebes1tem
+ebes1tes
+ebes1trä
+1ebi.
+ebiss1
+ebs1tanz
+ebs1tea
+ebs1t1emp
+ebs1tend
+ebs1th
+ebs1tie
+ebs1top
+ebs1tra
+ebungs1
+1ec.
+1ec'
+1eca
+1echel
+echi1en
+1echti.
+1eci
+1ecki
+ecks1tag
+1ect
+1ecz
+1edad
+edens1tau
+edens1t1emp
+1edetek
+1edit
+1edmo
+1edono
+edossi1
+1edron
+eds1cho
+eds1tag
+eds1tan
+eds1tee
+eds1tri
+eds1tru
+eds1trä
+edä1
+edös1c
+eeee1
+eehaus1
+ee1ig.
+e1eig
+ee1igs
+ee1ii
+e1e1in.
+eeni2
+eess1
+e1e1u.
+e1e1uf
+ee1um
+ee1un
+e1e1ur
+e1e1ut
+e1e1uw
+eeweiss1
+eew1eis
+efaus1
+1efdar
+efehls1
+1effas
+1effi
+1effö
+efoli1
+efos1
+1efpf
+1efpl
+1efsaa
+1eftap
+1ega.
+1egas
+1egat
+eges1tro
+ege1u
+1egg.
+1egia
+1egie
+egi1en
+egni1er
+1ego.
+egoni1
+1egos
+egratti1
+egs1tak
+egs1tal
+egs1term
+egs1th
+egs1tro
+egs1trä
+1egui
+egungs1
+1ehac
+ehi1er
+1eholms
+ehungs1
+ehäs1
+ehös1
+1ehöö
+1ei.
+eiaus1
+1eig
+1eil
+1eime
+1ein.
+1einb
+1einr
+eipi1
+1eir
+1eis
+eiseri1
+eis1tabe
+eis1tag
+eis1tanz
+eis1tas
+eis1top
+eis1tor
+eis1tou
+eis1tur
+1ej.
+1eki.
+1ekta
+1ekå
+1ela.
+1ela'
+elags1
+elais1
+elai1
+elari1
+1elas.
+1elce
+elci1
+eleti1
+ele1un
+1elia
+elici1
+1elick
+1elicz
+eli1ec
+eli1erb
+eli1erf
+eli1ern
+eli1erp
+eli1err
+elies1
+eli1ez
+elili1
+1elis.
+elissi1
+elite1
+1elito
+1elitä
+elizi1
+1eljär
+1ell.
+1elle.
+1ellem
+1ellen
+1eller
+elles1c
+1ello.
+1ells
+1elly
+1elm.
+1elo.
+1elon
+elosi1
+elporti1
+1elsk
+els1tafe
+els1tag
+els1terr
+els1tit
+els1topf
+els1tore
+1elund
+elungs1
+1elus.
+1emale
+emarci1
+emass1
+1embl
+1em1env
+1emeti
+1emi.
+1emia
+emi1er.
+emili1
+1emine
+1emis.
+1emię
+1emli.
+1emlif
+1emlis
+1emn
+1emoz
+1emp
+empi1
+emstudi1
+1emy
+1en'a
+1ena.
+1enabb
+1enabe
+1enabg
+1enabs
+1enabt
+1enabw
+1enad
+1enae
+1enaf
+1enag
+1enak
+1enal
+1enana
+1enand
+1enanf
+1enang
+1enans
+1enant
+1enanw
+1enanz
+1enapa
+1enapp
+1enar
+enari1
+1enass
+1enatm
+1enatt
+1enau
+1enbas
+1enbea
+1enbed
+1enbeg
+1enbek
+1enbeo
+1enbet
+1enbew
+1enbi
+1enbl
+1enboy
+1enbr
+1enbu
+1enbä
+1enbö
+1enbü
+1enca
+1ence
+1enci
+1encl
+1enco
+1encr
+1ency
+1end'
+1endar
+1ende
+1endi.
+1endic
+1endie
+1endl
+1endo
+1endr
+1endu
+1endw
+1endz
+1endä
+1endö
+1enea
+enebi1
+1enech
+1ened
+1enee
+1enef
+1eneg
+1eneh
+1en1eig
+1enemb
+1eneo
+1enep
+1enerfa
+1enes.
+1eneth
+1enev
+1enew
+1enex
+1enez
+enezi1
+1eneü
+1enfab
+1enfah
+1enfam
+1enfer
+1enfes
+1enfet
+1enfi
+1enflo
+1enfon
+1enfor
+1enfos
+1enfr
+1enfuz
+1enfä
+1enfö
+1enfü
+1enga
+1engeb
+1engef
+1engeg
+1engeh
+1engel
+1engem
+1enger
+1enges2
+1enget
+1engew
+1engi
+1engl
+1engr
+1engu
+1engä
+2enhag
+1enhal
+1enhat
+1enhau
+1enhe
+1enhil
+1enhoc
+1enhu
+1enhy
+1enhä
+1enhö
+1enhü
+1eni.
+1enia1
+2enic
+1enid
+1enik
+1enim
+1enin
+1enis
+1enj
+1enk
+2enknö
+1enla
+1enleh
+1enlen
+1enleu
+1enlie
+1enlit
+1enlo
+1enlu
+1enly
+1enlä
+1enlö
+1enmac
+1enmag
+1enmap
+1enmar
+1enmas
+1enmat
+1enme
+1enmi
+1enmo
+1enmu
+1enmy
+1enmä
+1enmü
+1enn
+enneli1
+2enner.
+1eno.
+1enobj
+1enof
+1enoh
+1enol
+enoli1
+1enop
+1enorc
+1enord
+1enorg
+1enori
+1enort
+1enou
+1enpap
+1enpar
+1enpf
+1enph
+1enpi
+1enpl
+1enpo
+1enpr
+1enpä
+1enq
+1enr
+1ens'
+1ensa
+ensee1
+1enseg
+1ensei
+1ensek
+1ensel
+1ensem
+enseri1
+1ensh
+1ensi
+ensi1e.
+1ensk
+1enso
+1enspe
+1enspi
+1enspo
+1enspr
+ens1tate
+1enstel
+ens1test
+1enstif
+ens1tipp
+ens1trai1
+ens1trös
+enstudi1
+1ensu
+1ensy
+1ensz
+1ensä
+1ensü
+1entab
+1entaf
+1entag
+1ental
+1entau
+1entb
+1entc
+1entea
+1entec
+1entf
+1entg
+1enti
+enti1en
+entini1
+entins1
+1entk
+1entl
+1entm
+1ento
+1entr
+1ents
+1entt
+1entu
+1entw
+1enty
+1entz
+1entä
+1entô
+1entö
+1entü
+1enunt
+1enur
+1enus
+1env
+1enwa
+1enwe
+1enwi
+1enwo
+1enwä
+1enzah
+1enzb
+1enzel
+1enzen
+1enzer
+1enzeu
+1enzg
+1enzh
+1enzi
+1enzk
+1enzm
+1enzo
+1enzp
+1enzr
+1enzs
+1enzt
+1enzu
+1enzv
+1enzw
+1enzy
+1enzz
+1enzä
+1enzü
+1enäm
+1enär
+1enäu
+1enöf
+1enü
+1eo.
+eonni1
+eorgs1
+eoseri1
+epagni1
+1epaj
+epi1ed
+episs1
+eprämi1
+eps1ton
+1epł
+1er'sc
+1era.
+1erako
+1erakü
+1eralle
+1eramo
+erani1
+1erano
+1erare
+1eras.
+eraus1t
+1erba.
+1erbas.
+1erbir
+1ercel
+erci1er
+1ercu
+1erda.
+1erdac
+erdi1er
+1erdir
+1erdis
+1erea
+1erebr
+1erebü
+1erede
+1eredi
+1eredr
+1eree
+1erefi
+1erefr
+1erefu
+1erefä
+1erefö
+1eregr
+1erehi
+1ereho
+1erehu
+1er1ei.
+1ereis.
+er1eis
+1erej
+1ereka
+1ereki1
+1erekn
+ereli1
+1erelo
+1erema
+1eremä
+1eremö
+1eremü
+1ereo
+1erepe
+1erepl
+1erepr
+eresi1
+1eresp
+eres1tie
+eres1to
+1ereta
+1erete
+1eretr
+1erety
+ere1un
+1erew
+1ereü
+1erfeu
+1erfos
+1erfuße
+1erfäu
+1erge.
+1ergio
+1ergäs
+1erhün
+1eria
+1erib
+eri1ene
+eri1ens
+eri1ent
+eri1enz
+eri1er.
+eri1ern
+1erif
+erims1
+1erimä1
+1erinfo
+1erini
+1erino
+1eris.
+2erism
+1eriw
+1erjar
+1erkac
+1erkier
+1erkoll
+1erlog
+1erlui
+1ermaché
+ermi1er
+1erna.
+1ernas.
+1erno.
+1ero.
+1ero'
+erobi1
+1erog
+1eron
+1eroph
+1eropo
+1eros.
+1erot
+1erou
+1erpaa
+1erpog
+1erpuz
+1erra.
+1erraf
+1erras.
+1errav
+1erre.
+erreli1
+1erret.
+1erri.
+1erris
+1errita
+1erro.
+1erry
+1ersdy
+erseri1
+1ershä
+1erskin
+erski1
+1erskli
+ers1tag
+ers1takt
+ers1tas
+1erstöh
+1ersva
+1erta.
+1erthem
+1erto.
+1ertum
+eruchs1
+erufs1c
+1erumä
+1erus
+1erva.
+1ervah
+1ervi.
+1ervil
+1erweib
+1erwein
+1erz.
+1erzb
+1erzon.
+1erzyc
+1erò
+esari1
+1esbau
+1esca
+1esco
+1escu
+eseki1
+eseri1
+ese1un
+1esfre
+1esi.
+esieges1
+1esiw
+1eski.
+1eslo
+1eslö
+esporti1
+1essaa
+esseri1
+ess1ten
+ess1tor
+1esta.
+es1tag.
+estari1
+1estas
+es1taum
+1estaz
+1esteb
+es1t1eil
+es1terman.
+esti1en
+1estin
+es1trac
+es1tr1eu.
+1estræ
+estudi1e.
+es1täubc
+es1töt
+1eszk
+1eta.
+e1tags1
+1etall
+1etalo
+etani1
+1etar
+etari1
+1etas.
+1etat
+1etees
+1eteet
+1etek.
+eteli1
+1eteni
+ethani1
+eth1e1is
+ethi1
+1ethn
+1ethy
+1eti.
+1eti1en
+1eties
+2eting
+1etism
+1etist
+1eto.
+1etok
+1etol
+1etoo
+1etra.
+1etraf
+1etral
+1etram
+1etrap
+1etre.
+1etrin
+1etro.
+1etro'
+1etros
+ets1t1emp
+ets1tep
+1etta
+1etti
+1etto
+1etts
+1etuv
+1ety.
+1età
+1etär
+1etät
+1eté
+1etê
+1eu.
+1eub
+eube1
+1euc
+1eud
+1eue
+1euf
+1eug
+1euk
+e1um.
+e1umb
+1e2ume
+e1umf
+e1umg
+e1umh
+e1umk
+e1uml
+e1umm
+e1ump
+e1umq
+e1umr
+e1ums
+eums1te
+eums1ti
+eums1tü
+e1umt
+e1umv
+e1umw
+e1umz
+e1unr
+e1unv
+1eup
+1eur
+eurasi1
+euri1er
+eurti1
+1eus
+e1usb
+eustudi1
+e1usz
+1eut
+eute1
+1euw
+1eux
+1eva.
+evali1
+evalli1
+evals1
+1eveso
+1evi.
+1evlu
+1evo.
+1ew.
+1ewb
+ewebe1
+1ewern
+1ewf
+1ewg
+1ewic
+1ewits
+1ewk
+1ewl
+1ewm
+1ewp
+1ewr
+1ews
+1eww
+1ewz
+1exp
+eydi1
+eyri1
+1eza.
+1ezas
+1ezh.
+ezi1es1
+1ezo.
+1ezoc
+1ezoe
+1ezog
+1ezok
+1ezom
+1ezop
+1ezoq
+1ezos
+1ezow
+eßsi1
+1eć
+1eń
+1eś
+eści1
+1eż
+fabi1
+faci1
+fali1
+fass1
+favi1
+fbesti1
+feaus1
+ferde1
+feri1et
+feti1
+fe1unt
+ffee1
+ffoli1
+ffoni1
+ffs1tag
+ffs1tal
+ffs1tau
+ffs1tep
+ffs1tic
+ffs1tie
+ffs1tou
+ffs1tut
+fide1
+fi1eh.
+fi1ei
+fi1ent
+fi1enz
+fi1erb
+fi1eri
+fi1ern
+fi1err
+fi1eso
+figli1
+flavi1
+flege1
+flili1
+fl1ings1
+fluss1
+flöss1
+fmagi1
+fmuss1
+fnungs1
+fnäs1
+fogli1
+foi1
+foli1e.
+fonci1
+fonds1
+forgi1
+forni1er
+forti1er
+forzi1
+fouchi1
+fourni1
+fporti1
+fprämi1
+fradi1
+frage1
+frazi1
+freni1
+fress1
+fri1en
+fs1chart
+fs1chor
+fseri1
+fshi1
+fsseri1
+fs1tak
+fs1tale
+fs1tank
+fs1tas
+fs1tauc
+fs1tee
+fs1t1eil
+fs1term
+fs1terr
+fs1tex
+fs1th
+fs1tipp.
+fs1tis
+fs1tit
+fs1toi1
+fs1ton
+fs1tor.
+fs1tore
+fs1tot
+fs1trab
+fs1trai1
+fs1trap
+fs1trep
+fs1trip
+fs1trol
+fs1tros
+fs1trub
+fs1truc
+fs1trup
+fstudi1
+fs1täti
+fs1tüte
+ft1eis1
+fteri1
+fts1chef
+ftsstudi1
+fts1taf
+fts1taus
+fts1tee
+fts1tep
+fts1tes
+fts1tier
+fts1tig
+fts1ton
+fts1tor
+fts1treu
+fts1tru
+ftstudi1
+fts1tut
+fts1tät
+funki1
+funni1
+furi1e.
+fuss1
+fäss1
+féti1
+gabri1
+gadi1
+galli1
+gambi1
+gani1
+ganti1
+gardi1
+gari1
+garni1er.
+gas1chem
+gas1chro
+gas1tank
+gas1tur
+gas1tü
+gauli1
+gaulti1
+gauti1
+gche1
+ge1imk
+ge1imp
+ge1ini
+ge1inse
+ge1inv
+ge1ix
+gens1tag
+ges1tal.
+ges1tale
+ges1th
+ges1tor.
+ges1tou
+ges1trun
+g1e1uf
+ge1uh
+ge1um
+ge1unt
+g1e1up
+ge1url
+g1eur
+ge1urt
+g1e1ut
+ggi1eri
+ghs1c
+ghts1
+ghäs1
+gici1
+gidi1
+gi1ele.
+gi1ell
+gi1en.
+gi1end
+giene1i
+gi1enh
+gi1ens
+gi1ersh
+gi1erzy
+giess1
+gi1et.
+gi1ev.
+gili1
+gioni1
+gions1
+giss1
+gis1th
+gis1trä
+gji1
+glasi1e.
+glas1tie
+glas1tis
+glas1tra
+glas1tri
+glili1
+glori1
+gläs1
+gmedi1
+gmuss1
+gni1ers.
+gnoli1
+gnose1
+gnungs1
+gobi1
+goli1
+gommi1
+gondoli1
+goni1er
+gooi1
+gorgi1
+gporti1
+gprämi1
+grangi1
+grari1
+gras1ta
+gras1tr
+gratis1
+grazi1
+greis1c
+gr1eis
+greli1
+gremi1
+greni1
+gress1
+groli1
+gross1
+grums1
+gräs1
+gsari1
+gsauri1
+gs1chans
+gs1chari1
+gs1chef
+gs1chip.
+gs1chol
+gs1chor
+gs1chör
+gseri1
+gshaus1
+gsporti1
+gsseri1
+gsstudi1
+gs1tabe
+gs1tabl
+gs1tafel
+gs1tag
+gs1takt
+gs1tal.
+gs1tala
+gs1tale
+gs1talk
+gs1tank
+gs1tanz.
+gs1tas
+gs1tat.
+gs1tate
+gs1tauc
+gs1taum
+gs1tausc
+gs1tax
+gs1team
+gs1tee.
+gs1tees
+gs1teic
+gs1t1eil
+gs1tempe
+gst1emp
+gs1tend
+gs1t1enn
+gs1teno
+gs1tep
+gs1term.
+gs1termi
+gs1terras
+gs1tex
+gs1ther
+gs1tid
+gs1tip
+gs1tis
+gs1tit
+gs1toi1
+gs1tole
+gs1too
+gs1tor.
+gs1torg
+gs1tors
+gs1tort
+gs1tose
+gs1tou
+gs1tow
+gs1trab
+gs1trac
+gs1trad
+gs1trag
+gs1trai1
+gs1trak
+gs1traum
+gs1tren
+gs1trep
+gs1tr1eu.
+gs1tria
+gs1trib
+gs1trie
+gs1troc
+gs1troi
+gs1trub
+gs1trun
+gs1trü
+gs1tul
+gs1tum
+gs1turb
+gs1turm
+gs1tus
+gs1tyc
+gs1täte
+gs1täti
+gs1törn
+gs1töt
+gs1tüm
+gs1türc
+gs1türme
+gs1tüte
+gugli1
+guiti1
+gungs1c
+guss1
+guste1
+guti1
+gäns1
+gäss1
+haci1
+hage1
+haluti1
+handeli1
+hanne1
+haos1
+hass1
+has1to
+haus1ta
+haus1tei
+haus1tis
+haus1tru
+hazi1
+hd1enti1
+hdös1
+hebe1in
+hechi1
+hee1id
+1heft.
+1heftc
+1hefts
+heide1
+heiss1
+h1eis
+heks1
+1held.
+helse1
+1hemd
+hemi1en
+hera1u.
+herbi1er
+herni1e.
+herungs1
+hes1tag
+he1unf
+he1unte
+hezi1e.
+hfoli1
+hglas1
+hhaus1
+hheits1
+hherni1
+hhäs1
+hidi1
+hi1eh.
+hi1ekk
+hi1eko
+hi1elb
+hi1ell
+hi1ener
+hi1erat
+hiess1
+hi1eta
+hi1ett
+hi1ewü
+higli1
+hischi1
+hise1
+hiss1
+hlachs1
+hle1int
+hleiss1
+hl1eis
+hli1e.
+hloss1
+hls1tag
+hls1ton
+hlungs1
+hluss1
+hlöss1
+hmedi1
+hmi1el.
+hmi1en.
+hnachts1t
+hnams1
+horbi1
+horgi1
+hosse1
+hoss1t
+houlli1
+hporti1
+hprämi1
+hrass1
+hreli1
+hres1tal
+hre1un
+hri1en
+hrs1taf
+hrs1tag
+hrs1t1eil
+hrös1c
+hsee1
+hseri1
+hshi1
+hsi1e.
+hsseri1
+hsstudi1
+hs1tafe
+hs1tag
+hs1tak
+hs1tal.
+hs1tale
+hs1tarta
+hs1tas
+hs1tata
+hs1tato
+hs1team
+hs1t1eil
+hs1term
+hs1terr
+hs1test.
+hs1tex
+hs1tiere
+hs1tiers
+hs1tilg
+hs1tis
+hs1ton.
+hs1tor.
+hs1tou
+hs1trak
+hs1tranc
+hs1tr1eu.
+hs1tr1eue
+hs1trub
+hs1trup
+hstudi1e.
+hs1tum.
+hstums1
+hs1täte
+hs1töt
+htale1
+htari1
+hthi1er
+hts1cham
+hts1chor
+hts1chro
+hts1tal
+hts1tee
+hts1tem
+hts1tep
+hts1test
+hts1ton
+hts1tor
+hts1trau
+hts1tr1eue
+hts1trun
+hts1träu
+hts1tur
+hts1tür
+hts1tüt
+huggs1
+hunds1ta
+huni1
+huri1
+hus1ti
+hweiss1
+hw1eis
+hygi1
+hyni1
+hzeits1t
+häls1c
+häns1che
+häs1chen
+häsche1
+häti1
+häus1
+hä1usp
+hémi1
+héni1
+hös1che
+höss1
+hüls1c
+iahi1
+iale1uten
+ial1eut
+ialeute1
+iams1
+iape1
+iardi1
+ia1un
+ia1ur.
+ia1url
+ibats1
+ibaudi1
+ibhaus1
+ibi1en
+ibiss1
+ibungs1
+1ic.
+icci1
+ic1haf
+ichi1er.
+ichori1
+ici1en
+ici1ers
+icki1er
+1idee.
+iderös1
+idi1en.
+1idio
+idiums1
+ids1tub
+ids1tur
+idungs1
+1idy
+iebes1ta
+iegi1
+iegs1c
+iegs1ta
+iegs1tr
+ienhi1
+i1ere1is.
+ier1eis
+ierre1iss
+ierr1eis
+ierre1iß
+iers1tis
+iers1ton
+iers1tres
+ierungs1
+ies1tal
+ifalls1
+ifi1er.
+1ifik
+ifoli1
+igali1
+igeni1
+iggs1
+ighi1
+iglas1
+igli1e.
+ignis1
+igs1tee
+igs1tig
+igs1tor
+igs1treu
+igungs1
+igä1
+iheits1
+ihi1er
+ihäs1
+ihös1
+ii1e.
+1iii1
+iji1
+1ijsb
+ikari1
+ikaus1
+1ikone
+ikure1
+ilates1
+ilaus1
+il1e1i.
+il1e1us
+ilfe1i
+illi1er.
+iloni1
+ils1tag
+ilstudi1
+ilungs1
+1imagin
+imali1
+imass1
+imi1el
+imnis1t
+1impor
+ims1tal
+imuss1
+imä1
+imös1
+1inabh
+1inabl
+1inase
+inaus1
+inavi1
+1ince
+1index
+1indiv
+1indiä
+1indok
+1indust
+ine1igel
+in1eig
+ine1isc
+in1eis
+inere1u
+in1e1uf
+in1e1us
+1infark
+1infek
+1infiz
+1inforc
+1infusi
+1ings
+ings1tric
+1ingt
+1inhaltes
+1inhaltete
+ini1e.
+ini1el
+ini1eri
+ini1ern
+ini1ers.
+ini1erv
+in1ings1
+1inisi
+1inist
+1initi
+1inkarn
+1innere
+inns1tem
+1inseln
+ins1tis
+ins1trai1
+ins1tät
+1inszent
+1intab
+1integ
+1intern
+1interv
+1intol
+1introd
+inungs1
+inus1
+1invent
+1inves
+iobs1
+iochi1
+iopi1er
+ioseri1
+ipari1
+ipedi1
+ipi1el
+ippe1
+ips1top
+ips1tre
+irani1
+irgs1c
+irgs1te
+iri1en
+iri1er.
+iri1eri
+iri1ern
+irks1c
+irniss1
+1irrb
+1irre
+1irrs
+1irrt
+irts1ti
+irös1
+isams1
+isauri1
+is1chia.
+is1chy
+ise1id
+ise1ik
+ise1inf
+ise1un
+ishi1
+isi1ec
+1isier
+isi1eri
+iskus1
+1ism.
+iss1tag
+iss1ten.
+iss1tet
+iss1tri
+iss1tup
+is1take1
+is1tasc
+is1tauc
+is1team
+is1tee
+is1t1eil
+is1t1eller
+isti1en
+is1tip
+is1too
+is1trai1
+is1treu
+is1trut
+is1tüm
+is1tüte
+1iteratmen
+1iteratmet
+1iteratt
+ite1un
+iti1el
+iti1en
+iti1ern
+itski1
+itsstudi1
+its1taf
+its1tea
+its1tee
+its1tes
+its1tol
+its1ton
+its1träu
+its1tur
+itungs1
+ituri1
+itus1
+ituts1
+1ity.
+itzi1en
+iungs1
+ivi1en
+izi1ell
+izi1en
+iäs1
+jagi1
+jahrs1
+janvi1
+jass1
+jas1th
+javi1
+jci1
+ji1e.
+jli1
+jmi1
+jners1
+jons1t
+jophi1
+jouti1
+juli1er
+jurassi1
+juri1e.
+jute1
+jäss1
+kabi1
+kali1e.
+kalmani1
+kameli1
+kanari1
+kareli1
+kari1e.
+kari1es
+karri1
+kase1
+kass1
+katri2
+kaufs1tem
+kazi1
+kdös1
+keaus1
+keits1
+keks1
+kens1tag
+kens1tat.
+kens1traum
+kes1taf
+ke1um
+k1e1up
+kfoli1
+kglas1
+kheits1
+khi1er
+khofs1
+khäs1
+ki1ella
+ki2enr
+ki1erf
+ki1ersk
+ki1erv
+ki1ev
+ki1ewer
+kindes1
+kinni1
+klecks1c
+kleri1
+kl1e1us
+klili1
+klivi1
+kläus1
+klöss1
+kmani1
+kmedi1
+kmuss1
+kmus1tes
+kode1
+koffe1
+kofi1
+korgi1
+kos1tep
+kprämi1
+krebs1c
+kre1ier
+kreli1
+kri1ens
+krole1in
+ksals1t
+ksauri1
+kseri1
+kski1
+ksseri1
+ksstudi1
+ks1tabl
+ks1taf
+ks1tale
+ks1tanz
+ks1tat.
+ks1taum
+ks1tausc
+ks1tax
+ks1team
+ks1tee
+ks1t1eil
+ks1tend
+ks1term
+ks1terr
+ks1tis
+ks1tit
+ks1tod
+ks1tor.
+ks1tot
+ks1tow
+ks1trad
+ks1tres
+ks1trib
+kstudi1
+ks1tul
+ks1tus
+ks1töl
+ks1tüm
+ks1tüte
+k1tags1
+kte1info
+kteri1
+ktesi1
+kthi1
+kti1e.
+kti1en
+kts1trun
+ktstudi1
+kules1
+kums1tis
+kuri1e.
+kurs1tu
+kuseri1
+kyri1
+käs1chen
+käsche1
+käs1tu
+küre1
+ladi1er
+laini2
+lai1
+lamts1
+landi1
+langi1
+las1tas
+las1t1eil
+las1tel
+las1t1emp
+las1tor
+las1tub
+las1tur
+laubi1
+laugi1
+laus1tal
+lbari1
+ldhi1
+ldossi1
+ldrös1
+lds1tag
+ldös1
+lebens1t
+le1ikon
+le1indu
+leiti1
+lemä1
+lesbi1er
+lesgi1
+lesi1
+leti1ers.
+l1e1uf
+le1uma
+le1umö
+le1ung
+lfi1er
+lfoli1
+lfs1tau
+lfs1tea
+lfs1tri
+lfs1tru
+lfs1tät
+lfts1t
+lge1in
+lgeri1
+lgi1erg
+lgi1ern
+lglas1
+lgs1tra
+lgs1tre
+lgs1tru
+lhaus1
+lhi1era
+lhäs1
+lhös1
+lici1er
+li1ee
+li1efa
+li1efb
+li1efg
+li1efh
+li1efk
+li1efl
+li1efo
+li1efw
+liege1
+li1egl
+li1egr
+li1ei
+li1eku
+li1el
+li1en
+li1epi
+li1erad
+li1erec
+li1eres
+li1eri.
+li1erli
+li1ers'
+li1ersi
+li1ersl
+li1erti
+li1ertü
+lies1che
+li1eth
+li1ett
+li1eu
+li1ewi
+li1ez.
+ligi1er.
+liguri1
+liki1
+lili1e.
+lindi1
+line1u
+liqui1
+liss1te
+lis1tag
+lis1th
+litäts1
+lius1
+lkani1
+lks1tag
+lks1ton.
+lks1tra
+lks1tum
+lkurs1
+lladi1
+llari1
+lle1isc
+ll1eis
+lleti1er.
+lle1un
+lli1er'
+lli1ers.
+lli1et
+lloqui1
+llosse2
+lls1tag
+lls1tor
+llstudi1
+llungs1
+llus1c
+lmati1
+lmedi1
+lmeti1
+lness1
+lnuss1
+lnös1
+lodi1en
+loi1
+lome1
+lommi1
+lomä1
+loni1er.
+looi1
+lorgi1
+lorze1
+lose1u
+los1tag
+los1tanz
+los1tic
+los1tob
+los1tro
+lotos1
+lours1
+lprämi1
+lr1eis1
+lreli1
+lrös1c
+lsaus1
+ls1chak
+ls1chor.
+ls1chör
+lseri1
+lski1
+ls1tabl
+ls1tage
+ls1tal.
+ls1tanz.
+ls1tas
+ls1tat.
+ls1tate
+ls1taum
+ls1teic
+ls1t1eil
+ls1tend
+ls1tex
+ls1tha
+ls1tho
+ls1tier
+ls1tir
+ls1tis
+ls1tor.
+ls1torp
+ls1tot
+ls1tou
+ls1trac
+ls1trep
+ls1trib
+lstudi1e.
+ls1turme
+ls1täte
+ls1täti
+ls1türl
+l1tags1
+ltati1
+lters1tic
+lters1toc
+ltra1un
+lts1tab
+lts1tea
+lts1ton
+lts1tri
+ltstudi1
+lts1tüt
+ltungs1
+ltäts1
+luis1
+lumbi1
+lunti1
+lusi1
+lus1tin
+lus1tor
+luteti1
+lute1u
+luthi1
+luvi1
+lvis1t
+lympi1
+lyri1
+läums1
+léori1
+lödi2
+magi1er.
+magi1eri
+magi1ers
+mali1er
+malli2
+manci1
+mannes1
+marni1er
+mas1ch1era.
+mas1chere
+mas1tor
+materi1
+matte1
+ma1unt
+mauri1
+ma1uta
+mbiss1
+mdidi1
+mdös1c
+meaus1
+medi1en
+meini1
+me1iso
+m1eis
+melde1
+mels1tem
+mens1tag
+mens1tanz
+mens1tor
+mens1trun
+menä1
+merasi1
+messi1er
+mesti1
+mes1tüt
+meti1er
+m1e1u.
+me1um
+meuni1
+me1unt
+me1us.
+m1eus
+mfoli1
+mgangs1
+mibi1
+michi1
+mi1ena
+mi1enb
+mi1enf
+mi1eng
+mi1enh
+mi1enl
+mi1enm
+mi1ens
+mi1ent
+mi1enz
+mihi1
+minti1
+mis1chie
+miseri1
+miss1
+mitri1
+mlili1
+mlungs1
+mmedi1
+mmeli1
+mmes1c
+mmes1ta
+mmes1tr
+mmes1tä
+mmi1ei
+mnibus1
+mns1
+mobili1
+mode1
+monni1
+morbi1
+morsi1
+mos1chin
+mose1
+mot1e1us
+mothe1
+mouti1
+mpeli1
+mpi1el
+mpuls1
+mrös1
+msams1
+ms1chef
+mseri1
+mse1u
+mski1
+ms1tag.
+ms1tal.
+ms1tas
+ms1t1eil
+ms1term
+ms1tex
+ms1th
+ms1tier
+ms1tische
+ms1torg
+ms1tou
+ms1trai1
+ms1trep
+mtess1
+mts1chin
+mts1ton
+mts1tät
+mulus1
+mumi1
+mungs1
+muni1
+muri1
+mus1cha
+mus1tau
+mus1trä
+musä1
+mydi1
+myri1
+mysi1
+mäus1
+méti1
+môti1
+möps1
+mös1che
+nace1
+nage1
+nahi1
+nali1e.
+nanas1
+nanci1
+nanti1
+nanzi1er.
+nari1er
+nastasi1
+nati1
+natri1
+nats1ti
+natti1er
+na1um.
+naus1tei
+nazi1
+nboni1
+nbonni1
+nchi1en
+nchs1c
+nci1en
+ncolli1
+nda1unt
+ndaus1
+nde1insp
+ndi1en.
+ndi1enh
+ndi1eri
+ndivi1
+ndnis1t
+ndrös1
+nds1chef
+ndungs1
+ndös1c
+nee1ic
+ne1e1ig
+ne1itä
+neli1er.
+neme1
+nere1id
+nerungs1
+nes1tag
+nes1tau
+nes1tum
+nes1tät
+neurs1
+n1eur
+nfangs1t
+nfoli1
+nfts1tr
+ngas1ta
+ngaus1
+ngni1er
+ngnis1
+ngs1cham
+ngs1chec
+ngs1taf
+ngs1tea
+ngs1tick
+ngs1top
+ngs1tore
+ngs1trup
+ngs1träu
+ngs1tub
+nhaus1c
+nheits1
+nhems1
+nhi1era
+nhäs1
+nhös1
+nici1
+ni1edi
+ni1ekt
+ni1el'
+ni1elb
+ni1elg
+ni1elh
+ni1ell
+ni1elm
+ni1elt
+ni1elw
+ni1ema.
+ni1emer
+ni1en
+ni1eri.
+ni1ern.
+ni1eve.
+ni1eves
+ni1ez.
+niki1
+ninti1
+nippes1
+nippe1
+nis1cham
+niseri1
+nisons1
+nis1taf
+nis1tag
+nis1tou
+nis1tö
+nitari1
+nke1ind
+nki1en
+nkolli1
+nkungs1
+nkurs1
+nlage1
+nlass1
+nlili1
+nmass1
+nmedi1
+nmeti1
+nmuss1
+nnesi1
+nnevi1
+nnhi1
+nni1em
+nni1ers.
+nnis1ti
+nnis1tr
+nnivi1
+nnoiseri1
+nns1chor
+nnseri1
+nns1tag
+nns1tan
+nns1tat.
+nns1tate
+nns1t1eil
+nns1th
+nns1tief
+nns1tol
+nns1topf
+nns1toren
+nns1tou
+nns1treu
+nns1trip
+nns1tru
+nnungs1
+nodi1
+nopi1er
+norgi1
+nothe1
+npazi1
+nporti1
+nprämi1
+nreli1
+nruss1
+nrös1c
+nsauri1
+ns1chef
+nseri1e.
+nshi1
+nsi1em
+nsi1er.
+nski1
+nsonni1
+nsseri1
+nsstudi1
+ns1tafe
+ns1tag.
+ns1tage.
+ns1tagen.
+ns1tages
+ns1tagn
+ns1tale
+ns1tas
+ns1teil.
+nst1eil
+ns1teile
+nsthi1
+ns1tite
+ns1toi1
+ns1torf
+ns1trac
+ns1trupp
+ns1täti
+ns1tüte
+ntali1
+ntalli1
+ntani1
+ntari1er
+nte1is.
+nt1eis
+nti1el.
+nti1ell
+nti1eme
+nti1ene
+nts1tee
+nts1tät
+nturi1e.
+nubi1
+nukle1
+nunti1
+nus1ta
+nus1te
+nus1to
+nus1tr
+nutri1
+nväs1
+nyi1
+nysi1
+nze1imi
+nzess1
+nzi1ell
+nzi1en
+nzi1eri
+nzi1ers.
+näs1chen
+näsche1
+näss1
+nä1um
+näus1
+oailli1
+oai1
+oari1
+oastri1
+obogi1
+obos1
+obungs1
+ocardi1
+oci1
+ocoti1
+odesi1
+odi1en.
+odi1enf
+odä1
+oe1ij
+oens1c
+o1etti1
+o1e1uf
+o1e1us
+oe1uv
+ofi1en
+ofs1trau
+ogni1
+ogs1tre
+ogä1
+ohels1
+ohemi1
+ohle1u
+ohms1t
+ohäs1
+oile1
+oini1
+oire1
+oirti1
+oissi1
+ois1to
+okee1
+oki1en
+okti1
+okus1
+okuss1
+olari1
+olati1
+ole1um
+ol1e1us
+olga1
+oli1et
+oli1ev
+olivi1
+olks1c
+olombi1
+olungs1
+omaus1
+omes1c
+omi1en
+ommi1er.
+onali1
+onars1
+onesi1
+on1e1uf
+oni1ess
+onseri1
+ons1tag
+ons1th
+ons1tis
+ons1treu
+ons1trup
+onus1
+oosi1
+oots1ta
+oots1ti
+opali1
+opari1
+ophe1
+opi1eri
+opi1ern
+opodi1
+opori1
+oprämi1
+opä1
+orani1
+ora1un
+oraus1t
+orca1
+ordeli1
+oreli1
+oresti1
+orgi1er
+ori1ens
+ori1ent
+orni1ers.
+orovi1
+orps1
+orri1er
+orseri1
+orsi1er
+or1ti1erfr
+orti1ers.
+orti1ersf
+osali1
+osauri1
+ose1inh
+oshi1
+osi1ers.
+ospermi1
+ossi1er.
+ossi1ers.
+os1tass
+ostati1
+os1tee
+osti1e.
+osti1en
+os1tip
+os1trab
+os1tuc
+ostudi1
+otari1
+ot1e1in.
+ote1ina
+ot1e1inb
+ote1ind
+ote1inf
+ote1inm
+ote1inp
+ote1inq
+ot1e1inr
+ote1int
+ote1inv
+ote1inw
+ote1inz
+ote1isc
+ot1eis
+oteli1
+othe1u
+oti1en
+otili1
+ots1taf
+ots1trau
+otstudi1
+ottes1c
+ottes1tr
+otus1
+ouli1
+ouqui1
+ouri1et
+ourri1
+ourti1
+ous1che
+ousti1
+ouvi1
+ouvri1
+ouzi1
+overni1
+oweiss1
+ow1eis
+ozess1
+pade1
+pae1
+paigi1
+pai1
+palmi1
+palti1
+pami1
+pas1chi
+pass1
+pati1
+pa1unt
+pa1ura
+pedi1en
+pee1
+peise1
+p1eis
+penhaus1
+p1enhau
+perse1id
+p1e1us
+pfaus1
+phans1
+phibi1
+phi1en
+phodi1
+phös1
+pici1
+pi1ede
+pi1edi
+pi1edr
+pi1eds
+pi1en
+pierre1ih
+piess1
+pi1ezo
+pils1
+pini1
+pipi1
+pirä1
+pissi1
+pleiss1
+pl1eis
+plessi1
+pli1er.
+pli1ers
+pnäs1
+poi1
+poiri1
+poiti1
+pomeli1
+pomi1
+pommi1
+pompi1
+popi1
+porgi1
+posti1er.
+potti1
+ppali1
+ppi1ev
+ppus1t
+pranari1
+prass1
+pree1
+pre1ind
+preis1c
+pr1eis
+premi1
+press1
+probe1
+prote1i
+prämi1e.
+ps1tabl
+ps1tot
+ps1tro
+ps1tüt
+ptili1
+ptri1en
+ptus1
+pugli1
+pumi1
+pungs1
+punti1
+puss1
+pus1tr
+pyi1
+päss1
+päus1
+qi1e.
+qui1ere.
+rags1to
+raki1
+rali1er
+ralli1
+randes1c
+randidi1
+rani1er
+raos1
+rari1e.
+ras1chi.
+ras1chin
+ras1tep
+ras1tüt
+ra1urb
+ra1url
+rawi1
+raxis1
+rbesti1
+rbeti1
+rbe1un
+rbi1eri
+rbis1tu
+rbonni1
+rbs1tis
+rbs1tät
+rbungs1
+rbusi1
+rchi1en
+rci1en
+rci1er.
+rcus1
+rcuti1
+rdani1
+rdelli1
+rdeni1
+rdi1ern
+rdossi1
+rds1tap
+rds1tem
+rds1tru
+rdös1c
+redi1en
+reesi1
+reichs1t1emp
+re1impl
+reini1
+re1instal
+reins1treu
+rein1tra1ue
+reis1taf
+r1eis
+reis1tei
+reis1terr
+reis1tis
+reki1
+reli1ef.
+reli1efs
+rems1tr
+r1enci1
+renä1
+res1tag
+res1takt
+res1tang
+res1tauc
+res1tem
+res1tief
+res1tob
+retä1
+reuss1
+r1eus
+rfoli1
+rfs1tag
+rghaus1
+rghi1
+rgi1er.
+rgi1ern
+rgoni1
+rgs1tru
+rgui1
+rgungs1
+rh1e1i.
+rheits1
+rhi1er
+rhäs1
+rhös1
+rics1
+ri1edic
+ri1efas
+ri1e1i.
+ri1ekt
+ri1ell
+ri1en.
+ri1enan
+ri1enb
+ri1enc
+ri1enf
+ri1enh
+ri1enl
+ri1enm
+ri1enp
+ri1enw
+ri1erar
+ri1erbü
+ri1erem
+ri1erfü
+ri1erga
+ri1erinn
+ri1erjä
+ri1erki
+ri1erkn
+ri1erkr
+ri1erkö
+ri1ermo
+ri1ermu
+ri1ern.
+ri1ersk
+ri1ett
+ri1eä
+rigni1
+rindi1
+rine1
+rkadi1
+rkis1to
+rkolli1
+rkose1
+rks1tor
+rks1tur
+rkungs1
+rkus1t
+rlachs1te
+rli1et.
+rlili1
+rls1tag
+rmali1
+rmaus1
+rmedi1
+rmeni1
+rmeti1
+rmi1el
+rmi1en.
+rmiti1
+rmstudi1
+rmuss1
+rnali1
+rnari1
+rnaus1
+rneli1e.
+rnesi1
+rn1e1uf
+rnhaus1
+rni1eri
+rnseri1
+rochä1
+rofi1
+roli1er
+rooi1
+rope1
+rorgi1
+rosni1
+ross1t
+rozi1
+rp1enti1
+rpiss1
+rpodi1
+rporti1
+rpr1eis1
+rradi1
+rre1un
+rri1el
+rri1en
+rri1er.
+rri1era
+rri1erb
+rriere1
+rri1erf
+rri1erg
+rri1eri
+rri1erm
+rri1ern
+rri1ers.
+rri1erw
+rroni1
+rronni1
+rrovi1
+rrseri1
+rruss1
+rsali1
+rsauri1
+rs1choo
+rsee1
+rsili1
+rski1
+rsstudi1
+rs1tafel
+rs1teil.
+rst1eil
+rs1toil
+rstoi1
+rs1tou
+rs1trai1
+rs1trak
+rs1tros
+rs1trüb
+rstudi1e.
+rs1täti
+rsus1
+rteri1
+rthi1er
+rti1ell
+rti1en
+rti1erg
+rti1erhä
+rti1eri
+rti1erkl
+rtini1
+rtri1er
+rts1taf
+rts1tau
+rts1tea
+rts1trau
+rts1tr1eu.
+rubi1
+ruhe1
+rule1u
+rungs1tr
+runi1
+rupi1
+ruri1
+rv1enti1
+rweiss1
+rw1eis
+rygi1
+rysi1
+rzas1
+rzi1ell
+rzi1en
+rächs1te
+räss1c
+räs1ti
+réti1
+rös1chens
+röss1
+saci1
+sage1
+sagli1
+saisonni1
+sai1
+sangli1
+sardi1
+sassi1
+sathe1
+sbesti1
+sbi1eri
+sbis1tu
+sci1
+scolli1
+scous1
+sdossi1
+sdös1
+se1imp
+se1info
+se1io
+se1irr
+s1eir
+sels1tur
+semilie1
+semili1
+seni1er
+sens1tis
+sepi1
+sess1
+s1e1u.
+se1uh
+se1um
+se1unf
+se1ung
+s1eus1
+se1ute1
+s1eut
+sexi1
+sfoli1
+shami1
+sherni1
+shi1er
+shäs1
+shös1
+sibiri1
+sichi1
+si1ell
+si1en.
+si1enb
+si1enf
+si1eng
+si1enh
+si1enl
+si1eno
+si1enp
+si1ens
+si1ent
+si1erke
+si1ero
+si1ett
+si1etz
+si1ez.
+sigli1
+siness1
+sini1
+sinki1
+sions1
+sis1tak
+sis1tes
+sis1th
+sius1
+ski1en
+ski1ern
+skäss1
+sli1er
+slili1
+smedi1
+smeti1
+smodi1
+snadi1
+snäs1
+sobi1
+soe1u
+sogli1
+sohnes1
+soi1
+soldi1
+sorci1
+sorge1
+sorgi1
+sori1
+spani1
+spezi1
+spi1ed
+spi1err
+sreli1
+srös1c
+ssali1
+ssams1
+ssandi1
+ssari1
+sse1ini
+sse1un
+ssias1
+ssi1ern
+ssi1et
+ssonni1
+ssseri1
+ss1t.
+ss1t'
+ss1tabl
+ss1tax
+ss1td
+ss1te.
+ss1ted
+ss1tee
+ss1t1eil
+ss1tem.
+ss1ter.
+ss1tes
+ss1tex
+ss1tf
+ss1tg
+ss1th
+ss1tid
+ss1tis
+ss1tit
+ss1tl
+ss1tm
+ss1tn
+ss1toi1
+ss1ton
+ss1tou
+ss1tow
+ss1trai1
+ss2trat
+ss1ts2
+ss1tue
+ss1tus
+ss1tw
+ss1tz
+ss1täti
+ss1töl
+s1tags1
+stani1
+stazi1
+ste1io
+stelli1
+stes1ti
+sti1ens
+stili1
+stis1t
+sts2
+stungs1
+suchs1ti
+sui1
+sungs1t
+szi1en
+szugs1
+säss1
+söss1
+taats1
+1tabak
+1tablar
+1tabled
+1tablet
+1tabu
+tade1
+tadi1
+1tafeln
+1taga
+1tageg
+1tagfr
+1tagh
+1tagk
+tagli1
+1tagmi
+1tagmo
+1tagnä
+1tags
+tags1ta
+tags1te
+tags1tr
+1tagt
+1tagu
+1tagv
+1taill
+tai1
+take1
+taki1
+1taktf
+1taktg
+1taktik
+1taktun
+1talern
+1talg.
+1talgl
+1talh
+tali1er
+talts1
+tami1er
+1tamta
+1tanga.
+tani1er
+1tankwa
+1tanne
+tanni1
+tansi1
+1tantc
+1tantiem
+tapas1
+1tape.
+1tapet
+1tapez
+1taps
+tareli1
+tari1e.
+tari1er.
+1tariern
+1tarif
+tarli1
+1tarnf
+tarni1
+1tarnu
+tarseri1
+tarsi1e.
+1tarza
+1tastl
+1tastu
+1tatb
+1tatsa
+1tattoo
+tatus1
+1taufe.
+1taugl
+ta1umw
+ta1unf
+ta1url
+2tausee
+1tausen
+1taxe
+tbis1tu
+tche1u
+tcolli1
+tdös1
+1teate
+1techn
+1techte
+1teddy
+tedes1
+1teekü
+1teelö
+1teena
+1teeni2
+te1enti1
+1teez
+1teilc
+t1eil
+1teildi
+1teilend
+1teili
+1teiln
+1teils.
+1teilt.
+1teilte
+1teilun
+1teilz
+te1imm
+te1imp
+te1inhab
+te1insy
+1telef
+1teleg
+1telep
+teli1er
+1tempo.
+t1emp
+1tempos
+tens1th
+1teppic
+1terato
+1terme.
+1termen.
+1termin.
+1terms
+1termäp
+1terrai1
+1terrar
+1t1erre.
+1terror
+1terzet
+tessi1er
+tes1tag
+tes1t1emp
+1testet
+tes1tisc
+1tests2
+1testun
+tes1tät
+t1e1u.
+1t1euf
+te1um
+te1unt
+1text.
+1texte
+tfoli1
+1thail
+thai1
+1thal.
+1thale
+1than.
+thaus1
+1thea
+th1e1i.
+the1ism
+th1eis
+the1ist
+1thek
+1thema
+1theme
+1then
+1theo
+1therap
+1therm
+1these
+1thet
+1thi.
+thias1
+thi1en.
+thi1err
+thivi1
+1thm
+thmus1
+2thol
+1thr
+1thw
+thäs1
+thä1us.
+thäus1
+1thè
+1thür.
+1thüre
+1ticket
+tidi1
+1tidn
+1tiefe.
+1tiefer
+1tiefs.
+1tiefst
+ti1elek
+ti1ena
+ti1enb
+ti1end
+ti1ene.
+ti1enf
+ti1enh
+ti1enm
+ti1eno
+ti1enp
+ti1ens.
+ti1ensc
+ti1ent
+ti1enu
+ti1enz
+ti1epi
+ti1epo
+1tierab
+1tierar
+1tierda
+1tierfr
+1tierga
+ti1eri.
+1tierlo
+1tierpa
+1tierpe
+1tierpf
+1tierpr
+1tierra
+1tiersa
+ti1ersga
+ti1ersl
+ti1ersm
+ti1ersso
+ti1ersun
+ti1erswo
+1tierta
+1tiertr
+1tierve
+1tierzo
+ti1et.
+ti1eth
+ti1eto
+ti2eurk
+ti1eur
+1tigeri
+tiles1
+1tilgb
+1tilgu
+tindi1
+tini1er.
+1tinti
+tions1
+1tip.
+1tipps
+1tirad
+1tischc
+1tischp
+1tischs.
+tissi1
+tis1tag
+tis1tep
+tis1tüt
+1titer
+1titt
+tius1
+tjes1
+tkolli1
+tl1ings1
+tlos1
+tlungs1
+tmass1
+tmedi1
+tmuss1
+tness1
+tnis1t
+1toas
+1tobe.
+1tobel
+1tobt
+tochi1
+1tocht
+1tod.
+todes1
+1todoulo
+1tods
+toi1
+1tokai1
+1tollh
+1tomb
+1tonar
+1tonf
+1tonisc
+1tonl
+1tonn
+1tonsu
+1topi
+topi1er
+1topog
+1torei
+1torf.
+1torf'
+1torff
+1torfs
+torgi1
+tori1e.
+1torna
+1torne
+1torso
+1tortu
+toseri1
+toss1t
+tos1tem
+1tota
+1tote.
+1totem
+1toten
+1town.
+1tox
+tpeli1
+tpelli1
+tp1ensi1
+tporti1
+1trab.
+1trabt
+1tradit
+1trafik
+1trag.
+1trage.
+1tragh
+1tragi
+1trags
+1tragt
+1tragu
+1tragö
+1trail
+trai1
+1trains
+1traints
+1trank
+1trans
+1tratet
+1tratsc
+1tratst
+1traue
+tra1unt
+1traut
+1trauu
+1tree.
+1treff
+1treib
+tre1ink
+tre1isc
+tr1eis
+treli1
+1trend.
+1trends
+1trennu
+tr1enn
+1trennw
+1treppe
+1tresen
+1tresor
+tress1
+1trete
+1tretm
+1treuem
+tr1eue
+1treues
+1treuha
+1treuhä
+1triad
+1tribü
+1trickfi
+1trieb.
+1trieben
+1triebs
+1triebw
+tri1ens
+tri1ent.
+tri1ente
+tri1est.
+tri1ests2
+1trifl
+1trigg
+1triko
+1trill
+1trime
+1trink
+1trio.
+1trito
+1triv
+trizi1
+1tromml
+1trompe
+troni1
+tronni1
+1tropf
+1trophä
+1trost.
+1trott
+1troub
+1troß
+1trug.
+1truge
+1trugs
+1truhe1
+1trupp.
+1trupps
+1trust
+1träc
+1träg
+1tränc
+1träne
+1tränk
+1träsk
+1träumer
+trä2ume
+träuss1
+1tröp
+1tröte
+1trübh
+1trübu
+1trüg
+1trümm
+tsari1
+tsaus1
+ts1chor.
+ts1chör
+ts1chüe
+tsee1
+tseri1
+tshaus1
+tshi1
+tsseri1
+ts1tabe
+ts1tafe
+ts1tag
+ts1tak
+ts1tal.
+ts1tale
+ts1tank
+ts1tant
+ts1tanz
+ts1tas
+ts1tat.
+ts1tate
+ts1taug
+ts1tauw
+ts1tax
+ts1team
+ts1t1eil
+ts1tend
+ts1term
+ts1terr
+ts1tex
+ts1th
+ts1tid
+ts1tief.
+ts1tis
+ts1tit
+ts1toi1
+ts1ton.
+ts1tor.
+ts1tore
+ts1tort
+ts1tot
+ts1tou
+ts1tow
+ts1trac
+ts1trad
+ts1trag
+ts1trai1
+ts1trak
+ts1traum
+ts1tren
+ts1trep
+ts1trie
+ts1trub
+ts1trup
+ts1trut
+ts1ts2
+tstudi1e.
+ts1tus
+ts1tuto
+ts1täte
+ts1täti
+ttennis1
+tt1enn
+tti1eri
+tti1ess
+ttili1
+ttrös1c
+tts1chef
+tts1chin
+ttsstudi1
+tts1tem
+tts1ter
+tts1tief
+tts1tor
+ttstudi1
+ttungs1
+1tuberk
+1tubi
+1tubu
+1tuch
+tudi1en
+1tuend
+1tuer
+tuffi1
+tufi1
+1tuge
+1tull.
+1tulls
+tumi1
+1tumo
+1tums.
+1tumsal
+1tumsan
+1tumsau
+1t1umsb
+1t1umsd
+1tumse
+1t1umsf
+1t1umsg
+1tumsh
+1tumsi
+1tumsk
+1tumsl
+1t1umsm
+1tumso
+1tumsp
+1t1umsr
+1t1umss
+1tumsta
+tums1tr
+1tumstu
+1tumsu
+1t1umsv
+1t1umsw
+1tumsz
+1tumsö
+1tumu
+1tun.
+tune1
+tuni1
+1tunik
+1tunn
+1tuns.
+1turbu
+turi1er.
+turi1ers.
+1turn
+1turtl
+1tusc
+tus1tag
+tus1tu
+tuts1t
+tware1
+1typ
+tyri1
+tysi1
+tze1un
+1täfe
+1tägi
+1tägl
+1täle
+1tänn
+täns1
+1tänz
+1täs
+täss1
+1tätigk
+1täto
+1tätsc
+1täus
+téli1
+1töch
+1tölp
+1tön
+1töpf
+1törns
+1törtc
+töss1
+1tötu
+1tüch
+tücks1tel
+1tüf
+1tüll
+1tümpel
+1tür.
+1türco
+1türe
+1türfl
+1türfü
+1türg
+1türk
+1türla
+1türmc
+1türr
+1türs
+1türt
+1türv
+1türö
+1tütc
+uage1
+uagli1
+uani1
+uardi1
+uares1
+uarni1
+uasi1
+uate1i
+ubi1el
+ubs1tab
+ubs1tas
+ubs1term
+ubs1th
+ubs1tip
+ubs1trau
+ubs1tri
+ucavali1
+1ucc
+uci1en
+ucli1
+uconni1
+udde1
+udi1en.
+udi1ena
+udi1enb
+udi1enf
+udi1enl
+udi1enm
+udi1enw
+udi1eri
+udi1ern
+udös1
+ues1tan
+ufalls1
+ufoli1
+ufski1
+ufs1tag
+ufs1tea
+ufs1ten
+ufs1ter
+ufs1tes
+ufs1tick.
+ufs1tou
+ufs1trau
+ufs1trick
+ufungs1
+ugeni1
+uge1u
+uggs1c
+ugnaci1
+1ugop
+ugs1tea
+ugs1tem
+ugs1term
+ugs1tür
+uhmes1
+uhsi1
+ui1el
+ui1em
+ui1en
+ui1er.
+ui1era
+ui1eres
+ui1ese
+ui1et.
+ui1eti
+uile1u
+ukani1
+ukasi1
+ulali1
+ulanzi1
+ul1enti1
+uli1eri
+uli1ern
+uli1erp
+uli1et
+ulivi1
+1ulkt
+ulli1er.
+ulni1
+uls1test
+ulstudi1
+ulungs1
+umbri1
+1umdr
+2ume
+umedi1
+umeis1c
+um1eis
+1umof
+1umsb
+1umsd
+1umsf
+1umsg
+1umsj
+1umsm
+1umsr
+1umss
+ums1taf
+1umsv
+1umsw
+umzugs1
+1unda
+und1e1ur
+unesi1
+ungs1tau
+ungs1tem
+ungs1tes
+ungs1tri
+ungs1tro
+ungs1tü
+1ungü
+1uni.
+1unif
+1unio
+1unkt
+1unku
+1unlu
+uns1tem
+1unwi
+uoi1
+uonti1
+1upd
+upi1er.
+upi1erb
+uprämi1
+urani1
+urci1
+urdi1er
+ureli1
+uresti1
+ure1un
+uri1el
+uri1en
+uri1eran
+uri1erh
+uri1erl
+uri1ern
+uri1ertr
+uri1erz
+uri1ez
+urmi1
+1ursac
+urs1taf
+urs1tag
+urs1term
+urstudi1
+urundi1
+urusi1
+us1e1i.
+useli1
+1usevan
+usi1ern
+usporti1
+ussi1er.
+ussi1ers.
+uss1tag
+uss1ten
+uss1tet
+uss1tor
+uss1tudiums
+us1tari
+us1tast
+us1taum
+us1taus
+us1teils
+ust1eil
+us1tep
+us1tilg
+us1tou
+us1trab
+us1trac
+us1trag
+us1trai1
+us1trak
+us1trip
+us1trit
+us1troc
+us1trudelt.
+us1trup
+us1trät
+us1träu
+us1tub
+us1tuc
+us1turm
+us1tyc
+us1tyr
+us1tüte
+1ut1ensi
+uti1en
+utine1
+uts1tem
+utungs1
+1uu.
+uule1
+uungs1
+uus1c
+1uu1uu.
+uvali1
+uverni1
+uzi1en
+vagni1
+vals1c
+vani1
+vanns1
+vanti1
+vardi1
+varni1
+vasi1
+vati1
+vaugi1
+vauti1
+ve1int
+veli1
+vendi1er
+v1endie
+verbi1er
+verni1er
+vers1tal
+vers1t1eil
+veti1
+v1e1uf
+ve1un
+vfoli1
+viari1
+vice1
+vide1
+vi1ed
+vi1ej
+vi1ellu
+vi1en.
+vi1enb
+vi1ene.
+vi1eng
+vi1ens
+vi1ent
+vi1erne.
+vi1esk
+vi1et
+vi1ev
+vi1ew
+vi1ez
+vili1
+villi1
+vini1
+vinzi1
+viri1
+vivi1
+vize1
+vni1
+voi1
+voili1
+voisi1
+voli1
+vori1
+vulli1
+wachs1tü
+warte1
+weis1taf
+w1eis
+weis1ton
+weni1
+werbe1
+werbs1ta
+werde1
+wetens1
+whitti1
+wici1
+wi1elk
+wi1erz
+wi1ets
+wiss1
+witani1
+witzi1
+wochs1
+woi1
+woni1
+wseri1
+ws1tic
+wuns1t
+wuss1
+xabi1
+xanti1
+xavi1
+xenhi1
+xi1en
+xi1et
+xini1
+xorgi1
+xterri1
+xtili1
+x1tra1ut
+xtstudi1
+xus1
+yce1
+ydi1en.
+yeni1
+yezi1
+yfoli1
+yhäs1
+yki1
+yklus1
+ylanzi1
+yloni1
+ymi1en
+ymi1er
+ynere1
+ynesi1
+ynke1
+ynni1
+yoga1
+ypri1
+yri1en
+yri1er
+ysauri1
+yse1in
+yseri1
+ys1talg
+ys1th
+yteri1
+ythe1
+ythi1
+zachä1
+zanti1
+zari1
+za1ur
+zbesti1
+zdossi1
+zdös1
+zeani1
+zechi1
+ze1inta
+zeki1
+zes1taf
+zes1treu
+ze1uh
+ze1um
+zfoli1
+zhi1er
+zhös1
+zi1eln
+zi1enb
+zi1end
+zi1ene
+zi1enf
+zi1eng
+zi1enh
+zi1enl
+zi1enm
+zi1ent
+zi1enz
+zi1enö
+zi1erku
+zi1esk
+zi1ess
+zinni1
+zirks1
+ziss1
+zius1
+zkiss1
+zlili1
+zmedi1
+znäs1
+zoni1
+zorgi1
+zprämi1
+zqui1
+zreli1
+zsauri1
+zseri1
+zski1
+zungs1
+zvi1eri
+zzes1
+ßaus1
+ßfoli1
+ßhäs1
+ßorgi1
+ßprämi1
+ßseri1
+ßungs1
+âqui1
+äbnis1
+äcks1tu
+ädi1en
+äfts1
+äge1
+älte1
+ämi1en
+äms1c
+äps1c
+ärfe1
+ärhi1
+ärs1tag
+ärts1t
+ärungs1
+äsche1
+äse1
+äste1
+äs1th
+äs1tor
+äte1ind
+äte1u
+äti1en
+ätpi1
+äts1chor
+ätsstudi1
+äts1tan
+äts1tau
+äts1te
+äts1tie
+äts1to
+äts1tre
+äts1tri
+äts1tro
+äts1tru
+äude1
+äure1
+ä1us'.
+äuse1
+ä1usg
+ä1usk
+ä1usn
+ès1
+ébas1to
+édi1en
+égi1er
+égni1
+égui1
+éhaus1
+émoni1
+éoti1
+équi1
+éridi1
+éri1en
+érisi1
+évri1
+ézi1
+ôchi1
+ôteli1
+ödi1
+ögens1
+ökokos1
+ölbe1
+ömi1
+önchs1
+öni1
+önizi1
+öoti1
+öps1che
+örri1
+örungs1
+ös1chent
+öze1
+öös1
+øi1
+øveri1
+übungs1
+üchs1c
+ücki1
+ücks1tag
+ücks1tru
+üf1etti1
+üfungs1
+ühls1ta
+ürbis1
+üse1
+üseri1
+üss1
+üts1t
+ąski1
diff --git a/tables/de-g1-core.cti b/tables/de-g1-core.cti
new file mode 100644
index 0000000..13f42ce
--- /dev/null
+++ b/tables/de-g1-core.cti
@@ -0,0 +1,32 @@
+# liblouis: German grade 1 braille
+#
+# Copyright (C) 2018 SBS Schweizerische Bibliothek für Blinde, Seh- und Lesebehinderte
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#-------------------------------------------------------------------------------
+
+include de-g1-core-patterns.dic
+
+nocross au 16 # 1 #
+nocross eu 126 # 2 #
+nocross ei 146 # 3 #
+nocross ch 1456 # 4 #
+nocross sch 156 # 5 #
+nocross st 23456 # ] #
+nocross äu 34 # \ #
+nocross ie 346 # 0 #
diff --git a/tables/de-g1.ctb b/tables/de-g1.ctb
new file mode 100644
index 0000000..f8fcd00
--- /dev/null
+++ b/tables/de-g1.ctb
@@ -0,0 +1,47 @@
+# liblouis: German Grade 1 Braille
+#
+# Das System der deutschen Blindenschrift (2015/2018)
+# http://www.bskdl.org/textschrift.html
+#
+# Bemerkung:
+# - Gross-/Kleinschreibung wird nicht berücksichtigt (d.h. für
+# Abkürzungen u.ä. braucht es Vorprogramm)
+# - Akzente: Hinweis auf die beiden Tabellen (bis jetzt nur als
+# Kommentar in de-g0.utb)
+#
+# -----------
+#-name: Deutsche Vollschrift
+#-index-name: German, partially contracted
+#-display-name: German partially contracted braille
+#
+#+locale: de
+#+type: literary
+#+contraction: partial
+#+grade: 1
+#+direction: forward
+#
+#-has-nocross: yes
+# ------------
+#
+# Copyright (C) 2018 SBS Schweizerische Bibliothek für Blinde, Seh- und Lesebehinderte
+#
+# This file is part of liblouis.
+#
+# liblouis is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# liblouis is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with liblouis. If not, see
+# <http://www.gnu.org/licenses/>.
+#
+#-------------------------------------------------------------------------------
+
+include de-g0.utb
+include de-g1-core.cti
diff --git a/tables/de-g2-core-patterns.dic b/tables/de-g2-core-patterns.dic
new file mode 100644
index 0000000..a314b80
--- /dev/null
+++ b/tables/de-g2-core-patterns.dic
@@ -0,0 +1,26711 @@
+UTF-8
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% auto-generated file, don't edit! %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+.'e1m
+.aa1
+.aa1l1
+.ab1ei
+.ab1ello
+.a1bel
+.a1bell
+.abm1a
+.abrie1
+.a1br
+.abrin1
+.aci1e
+.ad1
+.adab1
+.adi1e
+.ae1n1
+.ae1s
+.ag2ei
+.ag1em
+.ag1er
+.ag1es
+.aht1
+.ai1
+.aids1
+.aid1
+.akkadi1
+.alb1em
+.alb1er
+.albrech1
+.ale1ut
+.a1ll'
+.a1lla
+.a1llb
+.a1llc
+.a1lld2
+.a1llegi
+.a1llel
+.a1llenb
+.allen1
+.a1llend
+.a1llens
+.a1llet
+.a1llf
+.a1llg
+.a1llh
+.a1llied
+.a1llig
+.a1llis
+.a1llit
+.a1llk
+.a1ll1l
+.a1llm
+.a1lln
+.a1llo
+.a1ll2p
+.a1llq
+.a1llr
+.a1lls
+.a1llt
+.a1llu
+.a1llv
+.a1llw
+.a1llz
+.a1llü
+.alm1
+.a1log
+.alpers1
+.al2p
+.alv1
+.a1m1a
+.ami1t
+.amwe1
+.a1nati
+.an2a
+.and2em.
+.and1erb
+.an1kau1
+.anm1
+.anti1ge
+.an1ti
+.ant1oi1
+.an1to
+.apis1
+.a2p
+.apuli1
+.a1rb1en.
+.1arb
+.arb1en
+.a1rb1er.
+.a1rb1erg
+.a1ren.
+.a1ren'
+.a1ren2p
+.arg1er
+.1arg
+.ari1e
+.1ari
+.arun1
+.1aru
+.arvo1
+.1arz1
+.arzi1e
+.aslan1
+.assi1e
+.a1ssi
+.a1sti1e
+.at1
+.aub1
+.audi1
+.aufzu1
+.aug1
+.aus1che
+.au1sch
+.aus1see
+.aus1ta
+.au2s1t1eil1
+.au1ste
+.aust1ei
+.aus1tes
+.aus1th
+.aus1to
+.avers1
+.av1e
+.avo1
+.axi1
+.ayg1
+.azei1
+.az2e
+.az1u1m
+.az1ur
+.az1us
+.barschaf1
+.b1arsc
+.bau1
+.b1ea1l
+.1bea
+.b1eam.
+.b1eamt.
+.1be1di2
+.b1eec
+.1bee
+.b1eem
+.b1ee1s
+.b1eet
+.b1eic
+.b1eifuß
+.b1eind
+.b1eins
+.b1eint
+.b1einv
+.b1ei1ru
+.b1eisu
+.b1eit.
+.b1eite
+.b1eitn
+.b1eiza
+.b1eizo
+.belgi1
+.1b1elg
+.b1eliz1
+.b1eloc
+.b1enc
+.b1enf
+.b1eng1
+.b1enh
+.b1enin
+.b1enj
+.b1enk
+.b1enn
+.b1enr
+.b1ens
+.b1en1t
+.b1env
+.b1enw
+.b1enz
+.b1er.
+.b1erac
+.b1erb
+.b1erc
+.b1erd
+.b1erek
+.b1erend
+.b1ereng
+.b1eres
+.b1erf
+.b1erg
+.berg1eb1en
+.b1erh
+.b1eris
+.b1erj
+.b1erk
+.b1erl
+.b1erm
+.b1ern
+.b1erolle.
+.b1erq
+.b1err
+.b1ers
+.b1ert1
+.b1erv
+.b1erw
+.b1erz
+.b1eser
+.b1esl
+.b1ettec
+.1bett
+.bi1gend
+.big1en
+.bi1nat
+.bin2a
+.bi1nom
+.bin2o
+.1bio1
+.1bi1sm
+.bla1s
+.bleich1
+.blä1s
+.boe1
+.b1oi1
+.brech1
+.brich1
+.brus1c
+.1bru
+.1brü1
+.bun1
+.bänd1
+.1bä
+.büb1
+.cae1
+.cai1
+.cerisi1
+.chab1
+.chee1
+.chi1en1
+.chi1er
+.chun1
+.cib1
+.cob1
+.c1ob1i1
+.coo1rt
+.c1oor
+.couri1
+.cou1
+.c1our
+.cue1s
+.1dae1
+.1dai1
+.da1las
+.da1lie
+.da1ll
+.da1neb2
+.dea1l
+.1dea1r
+.dee1n1
+.1dee
+.dee1r
+.deg1en
+.de1i.
+.de1ind
+.de1inst
+.1de1ll
+.de1miss
+.1d1emi
+.de1montage.
+.d1emon
+.demon1tag
+.de1mora
+.d1emor
+.de1n1er
+.deo1
+.de1rang
+.derb1
+.de1rea
+.derma1l.
+.derni1
+.derun1g
+.de1scr
+.de1sens
+.de1skr
+.de1ssa
+.de1sser
+.de1st
+.destri1
+.dest2r
+.dev1
+.didi1e
+.dieb1
+.1di2en1
+.divi1e
+.1div1
+.dizi1
+.1diz
+.dmi1
+.dni1
+.doe1
+.doo1
+.dou1
+.dui1ns
+.dun1
+.dv1
+.dw1
+.dys1c
+.dys1to
+.dys1t2r
+.dz1
+.dzi1
+.ea1c
+.ea1l
+.ea1r
+.eat1
+.eb1el
+.eb1en2a
+.eb1enb
+.eb1end2
+.eb1ene
+.eb1enf
+.eb1eng
+.eb1enh
+.eb1enm
+.eb1enr
+.eb1enw
+.eb1er
+.echs1
+.ee1
+.eeg1
+.eet1
+.egb1
+.eg1el
+.eg1en
+.eg1er
+.ego1
+.e1h
+.ehe1i
+.ehe1l
+.ehe1ne
+.ehen1
+.ehe1ri
+.eidsvo1
+.eise2st
+.eis1sc
+.ei1s1so
+.eis1s2p
+.eis1st
+.eis1ta
+.ei1s1t2r
+.eis1tü
+.eit1
+.1eiv1
+.e1l.
+.eleg1
+.e1l1em.
+.e1len.
+.elen1
+.e1lenk
+.elis1che
+.1elisc
+.e1ll
+.els1c
+.elv1
+.1e1m.
+.e1mm
+.e1n.
+.end1
+.eng1ele
+.en1gel
+.eng1en
+.eng1er
+.enns1
+.ens1o
+.enti1e
+.en1ti
+.en2tin
+.en1tlic
+.1entz1
+.env1
+.erb1ei
+.erdan1
+.er1da
+.erde1s
+.erob1
+.errun1
+.er1ru
+.erz1u
+.esb1
+.e1sche
+.e1schi
+.e1sh
+.e1ss
+.essens1
+.essen1
+.e1sta
+.e1ste
+.este1ll
+.e1sti
+.e1sto
+.e1st2r
+.eti1
+.1eug1
+.ev1
+.ew1
+.exhaus1to
+.exhau1
+.eye1l
+.faa1
+.fab1
+.fah1renh
+.1fah
+.f2ahr
+.fahrenhei1
+.fah1rn1er
+.fai1
+.fa1ller
+.1fal
+.fa1lln1er
+.fea1
+.fe1ll
+.1fel
+.fels1ti
+.fel1st
+.fels1tu
+.fels1tü
+.fen1
+.fib1
+.fi1era
+.1fie
+.fi1e1st
+.fi1g.
+.1fig
+.fischlä1
+.1fisc
+.fit1
+.fleg1
+.fun1
+.gai1
+.ga1ll
+.galle1s.
+.ga1lle
+.ganb1
+.gang1es
+.g1e.
+.ge1b1ea
+.g1ee1l
+.gegenw2
+.g1eid
+.g1ein
+.g1elate
+.g1elb1
+.1g1eld1
+.g1elig
+.g1elos.
+.gelun1
+.gem1a
+.g1emon
+.g1en.
+.g1enab
+.gen2a
+.g1enak
+.g1enb
+.g1end
+.g1ene.
+.g1en1en1
+.g1enese.
+.gen1es
+.g1en1et
+.g1en1ex
+.g1enf
+.g1eng
+.g1enk
+.g1enl
+.g1enm
+.g1enn
+.g1en2p
+.g1enr
+.g1ens
+.g1en1t
+.g1env
+.g1enw
+.g1enz
+.germani1e
+.g1erm
+.gerun1
+.geränd1
+.1gerä
+.g1eser
+.gev1
+.g1ey
+.gfe1
+.g1fäh1
+.gha1t
+.gla1s
+.gle1b1
+.gli2
+.gni1
+.gob1
+.goe1
+.gott1es
+.gotte2
+.gou1
+.gri2
+.grue1
+.gru2n1dig1
+.gsta1
+.gue1n1
+.gun1
+.gunt1er
+.guri1e
+.hab1ec
+.ha1b1er
+.ha1bi
+.hae1
+.ha2l1lan
+.ha1ll
+.hant1
+.harun1
+.h1aru
+.haub1
+.hau1f
+.haus1to
+.hea1r
+.hee1
+.he1he
+.hei1t
+.he1lla
+.he1n.
+.hen1
+.her1oe1s
+.h1ero
+.he1sh
+.hib1
+.hi1erar
+.hilli1
+.hint1
+.hintere1ss
+.hoe1
+.hol1lan
+.hoo1
+.horg1
+.hornun1
+.horn2u
+.hot1
+.hou1
+.how1
+.hun1
+.hunde1i
+.hunt1er
+.hv1
+.häg1
+.hände1r
+.händ1
+.iai1
+.ib1
+.ibb1
+.i1cha
+.i1chb
+.i1che
+.i1chf
+.i1chg
+.i1chi
+.i1chl
+.i1chm
+.i1chn
+.i1cho
+.i1chr
+.i1chs
+.i1cht
+.i1chw
+.id1
+.i1e
+.i1g1
+.igni1
+.ii1
+.ikt1
+.ilg1
+.imi1e
+.imi1t
+.imm2ern
+.impers1
+.im2p
+.ind2em.
+.in1de
+.ingv1
+.ini1e
+.in1i
+.ins1ol
+.ion1i1
+.irg2end
+.isa1m
+.is1chä
+.isis1
+.istri1
+.ist2r
+.iv1
+.iz1
+.izi1
+.jenomm1
+.je1nom
+.jen2o
+.je1ses
+.je1st
+.job1
+.j1oi1
+.jugi1
+.jug1
+.kaa1
+.kab1
+.kag1
+.kai1n.
+.kai1ne
+.kai1n1i
+.kai1ns.
+.kai1nz
+.kalb1
+.ka1ll
+.katio1
+.kau1
+.keg1
+.ke1ll
+.ke1ss
+.ke1st
+.kev1
+.kha1t
+.kib1
+.kieb1
+.ki1erb
+.kies1t
+.kie1s
+.klan1
+.kla1s
+.kle1b
+.klo1re
+.klän1
+.koe1
+.kolli1
+.kott1
+.koz1
+.krai1
+.krich1
+.krü1
+.kt1
+.kub1
+.kue1
+.kun1
+.kung1
+.kv1
+.kw1
+.kyb1
+.köpfe1r
+.kö2p
+.lachs1te
+.lae1
+.lag1ere
+.lagni1
+.la1la.
+.lama1l
+.la1ma
+.lan1gers.
+.lang1ers
+.lani1er
+.lanti1e
+.lan1ti
+.lasa1
+.la1ssb
+.la1sses.
+.lau1
+.lav1
+.le1br
+.lee1
+.leg1en.
+.leg1er
+.leib1
+.le1ll
+.le1mm
+.le1mon1t.
+.leng1
+.len1
+.les1e1i
+.le1sh
+.le1ss
+.le1st
+.l1i
+.li2en1
+.ligni1e
+.lili1
+.lint1
+.lis2
+.liv1
+.lizu1
+.liz1
+.loe1
+.los1si
+.los1st
+.los1t2r
+.l1ost
+.lou1
+.lub1
+.lun1
+.läus1
+.mab1
+.mae1s
+.mag1er
+.mai1n2a
+.mai1ns
+.mai1nt
+.m1al
+.ma1lli2
+.m1all
+.manta1
+.maz1
+.mb1ei
+.mc1k
+.mee1
+.meeg1
+.me1ll
+.meni1e
+.men1
+.me1sh
+.me1st
+.mez1
+.mi1e1do
+.mi1el.
+.mi1erz
+.mob1
+.1moe1
+.mog1
+.mohan1
+.moi1ne.
+.m1oi
+.m1oos1
+.1moo1
+.morti1
+.mou1
+.mua1
+.muli1e
+.mun1
+.munt1
+.mz1
+.naa1
+.n2a
+.nab1
+.nag1el
+.nah1mer
+.na1ll
+.nd1
+.nea1l
+.nea1r
+.1neb1el
+.neb2en
+.nee1
+.neg1er
+.n1e1ii1
+.n1ei
+.ne1ll
+.n1el
+.neo1
+.ne1st
+.n1es
+.nev1
+.nez1
+.ng1
+.nib1
+.nich1te.
+.n2ic
+.nich1ten.
+.nicht1en1
+.ni2enb
+.ni1en1
+.ni2end
+.ni2enh
+.nigg1
+.nirg1
+.ni1s
+.nob1
+.n2o
+.noo1
+.nov1
+.nu2r.
+.n2u
+.1oa1
+.ob1
+.od1
+.oe1
+.1ogg1
+.ogi1e
+.1ogi
+.1olb1
+.olds1
+.1old
+.oo1
+.oral1
+.org1el
+.orgi1e
+.ori1e
+.orm1
+.osb1
+.osteri1e
+.1ost
+.ost1er
+.o1steri
+.ostt1
+.ott1
+.ou1
+.oz1
+.pai1
+.2p
+.pee1
+.pe1ll
+.pelti1
+.perle1b1
+.pe1ss
+.pfa1ll
+.p1fal
+.pfun1
+.pib1
+.pi1ed
+.pi1ell
+.pi1e1m
+.pi1era
+.pi1erd
+.pi1erf
+.pi1ern
+.pi1err
+.pi1eta1
+.pi1eti
+.pi1ev
+.ping1
+.politi1ken1
+.po1rose
+.p1oros
+.porti1er.
+.porti1ere.
+.porti1eren.
+.prag1
+.prech1
+.pri2en1
+.pris1c
+.pse1l
+.ps1e
+.pt1
+.pun1g1
+.puni1e
+.raa1
+.rae1s
+.rai1
+.ra1ll
+.rand1e
+.rau1fspi
+.raufs2p
+.rauhei1t.
+.raz1
+.rech1tet
+.rech1thal
+.reg1el
+.reg1er
+.re1insz
+.reis1che
+.rei1sc
+.reli1e
+.re1mer
+.re1missi
+.re1mm
+.renée1
+.re1run
+.re1sch
+.re1sea1
+.re1sek
+.re1set
+.re1sh
+.re1skr
+.re1sorb
+.1res1or
+.re1sor2p
+.re1ss
+.re1st
+.re1un
+.rieb1
+.rie1bsa1
+.ri1ei
+.rie1l
+.ri1ell
+.ri1esk
+.rivi1e
+.rob1es
+.r1obe
+.robi1er
+.r1ob1i
+.rodi1e
+.r1odi
+.roe1
+.r1oi1
+.roni1e
+.ron1i
+.ro1ro
+.ro1ssi1e
+.rostan1
+.r1ost
+.rou1
+.row1
+.run1d
+.run1ge
+.run1gs
+.ränd1
+.rös1chen.
+.röschen1
+.saa1
+.sabb1
+.sa1g1er.
+.sa1gr
+.1sa1gu
+.sali1e
+.sa1lla
+.sa1lles
+.sa1llo
+.1salz1
+.sa1m
+.sang1
+.sat1zer.
+.1satz
+.satz2e
+.sau1
+.saunt1
+.1sau2n
+.sauri1
+.schee1
+.s1chett
+.1schet
+.schia1ch.
+.s1chia2p
+.schlän1
+.schm1
+.s1ch1ool1
+.schwi1l
+.1schw
+.sea1l
+.sea1r
+.see1i
+.see1r
+.seh1re.
+.selb1e
+.se1ll
+.sen1
+.senti1e
+.sen1ti
+.s1eri1e.
+.serv1
+.sesti1
+.se1st
+.sevi1e
+.shaf1
+.shan1
+.sib1
+.sieg1es
+.s1ieg
+.si1en1
+.si1err
+.si1est
+.sie1s
+.si1et
+.ski1er
+.slan1
+.slän1
+.sm1
+.smi1t
+.s1ofa1
+.1sohn1
+.s1oh
+.s1on
+.s2one.
+.sons2s
+.s1os.
+.s1s
+.s1ta.
+.s2tag
+.1sta1ll
+.stau1
+.1ste1mm
+.sti1l1lo
+.1stil
+.stun1
+.stüb1
+.sue1s.
+.sug1
+.sumo1
+.su1m
+.sun1
+.sunb1
+.sv1
+.sw1
+.swi1s
+.sz1
+.taa1
+.tag1es
+.tai1
+.tal1lag
+.ta1lli
+.tau1
+.tav1
+.t1e.
+.t1ea
+.t1eb
+.t1ec.
+.t1eca
+.t1ech.
+.t1echi
+.t1echn2ic
+.1techn
+.t1echniq
+.t1echnisi
+.t1echn2o
+.t1echt
+.t1echu
+.t1eck
+.t1eco
+.t1ect
+.t1ed
+.t1ee1
+.t1ef
+.t1eg
+.t1eh
+.t1ei
+.t1eil1
+.t1ej
+.t1ek
+.t1el
+.1teleg1
+.tele1i
+.te1ll
+.t1em
+.te1mm
+.teni1e
+.t1en1
+.t1eo
+.t1e2p
+.t1eq
+.t1er
+.terwi1
+.t1es
+.te1sch
+.te1ss
+.te1st
+.t1et
+.t1eu
+.t1ev1
+.t1ew
+.t1ex
+.t1ez
+.thani1
+.tha1t
+.thie1r.
+.thie1rs
+.ti1en.
+.tien1
+.tieng1
+.ti1ev
+.ting1
+.tit1
+.1tob1el
+.t1obe
+.toe1
+.too1
+.trai1
+.t2r
+.trich1
+.tri1est
+.tri1nat
+.trin2a
+.trü1
+.tsa1m
+.tschun1
+.t1schu
+.tun1g.
+.tun1gs.
+.tun1gst
+.tuu1
+.tv1
+.twi1l
+.twi1s
+.ub1
+.ue1la
+.ue1ls
+.ue1r
+.ug1
+.ugri1
+.ui1
+.ulan1
+.um1man
+.u1m
+.um1mel
+.um1mo
+.umv1
+.u1n'
+.un1da
+.un1de
+.un1dr
+.un1g
+.urä1
+.usa1g
+.use1l
+.uz1
+.vai1
+.va1ll
+.vat1
+.veb1
+.vee1
+.ve1ll
+.velo1
+.veni1e
+.ven1
+.v1ers1chen.
+.verschen1
+.vint1
+.voe1
+.vo1nd
+.vo1ng
+.vo1nh
+.vo1nl
+.vo1nt
+.väs1c
+.wai1
+.w1art
+.web1er
+.weg1
+.we1gen1er
+.we1genst
+.weib1
+.weig1
+.wei1sf
+.wei1tli
+.werni1s
+.w1ien1
+.w1ier
+.wies1c
+.w1ies
+.woh1len1
+.wo1llmann
+.wou1
+.xi1e
+.yb1
+.yv1
+.zea1
+.z2e
+.zee1
+.ze1lla
+.ze1llo
+.zerb1
+.zerg1
+.zerz1
+.ze1s
+.zet1
+.ziel1
+.zins1
+.zmi1
+.zob1
+.z1ub1ers
+.z1ugau
+.z1ug1ei
+.z1ugla
+.z1uglo
+.z1ugra
+.z1ugro
+.z1ugrä
+.z1uid
+.z1uker
+.z1un1g
+.z1upfe
+.zu2p
+.z1ush
+.z1uur
+.zv1
+.zvi1
+.zwe1g1
+.zwei1s
+.zwi1l
+.zwo1
+.züb1
+.äg1
+.ä1rg1
+.ét1
+.éti1
+.év1
+.êt1
+.öl1
+.örg1
+.ört1
+'ab1
+'a1c
+'ai1
+'a1l
+'alb1
+'a1n
+'appe1
+'a2p
+'ap2p
+'a1r
+'1arg1
+'arvi1
+'aub1
+'au1m1
+'av1
+'az1
+'b1
+'bri1
+'de1l
+'e1h
+'e1l
+'e1n
+'env1
+'e1sch
+'e1ss
+'e1st
+'este1
+'et1
+'g1en
+'g1er
+'g1es
+'ha1b
+'hallo1
+'ha1ll
+'hol1
+'i1g
+'i1n
+'int1
+'ke1
+'le1s
+'l1l
+'ma1l
+'me1l
+'o1
+'oe1
+'offici1e
+'of1fi
+'of1fic
+'rou1
+'rumg1
+'ru1m
+'sa1
+'se1l
+'si1
+'s1o
+'sun1
+'u1n.
+'urb1
+'we1
+'word1
+'êt1
+aaa1
+aab1
+aadi1
+aa1l
+aalan1
+aalv1e
+aa1nd
+aa1ne
+aa1nga
+aa1ngr
+aani1
+aa1nk
+aa1n2p
+aa1nr
+aa1nst
+aa1nte
+aa1ra
+aarb1es
+a1arb
+a1a1rd
+aa1re
+a1are1i
+aare1sc
+a1ares
+a1a1rg
+a1a1rh
+aa1ri.
+a1ari
+aa1ria
+aa1ris
+a1a1rk
+a1a1rl
+a1a1rn
+aarne1
+a1a1r2p
+a1a1rr
+aa1rs
+aarschaf1
+a1arsc
+aa1rtj
+aa1ru2p
+a1aru
+a1a1rw
+aarzun1
+a1arz
+aa1s1ta
+aats1t
+aa2uf
+aaus1
+aaz1
+a1bab
+a1bad1
+abae1
+a1bak
+abali1e
+a1bal
+a1ban
+a1bar
+a1bau
+a1bbe
+a1bd
+ab1ebb
+a1beck
+a1beg
+ab1egg
+ab1eic
+ab1ein
+a1bek
+ab1eks
+a1bel
+ab1elac
+ab1elan
+ab1elu
+ab1elä
+a1bem
+ab1emu
+ab1en
+ab2enam
+aben2a
+abe1n2ic
+a1ben1t
+ab1eran
+abe1rat
+ab1erau
+ab1erc
+ab1er1da
+ab1er1do
+abe1rec
+abe1reg1
+ab1erf
+ab1erge
+ab1ergi
+abe1ric
+ab1erk
+ab1erl
+ab1ern
+ab1er2p
+ab1err
+ab1erso
+abe1ru
+ab1erz
+ab1erä
+ab1es1ei
+ab1eser
+ab1esl
+ab1esz
+ab1ex
+ab1ey
+a1bf
+abgas1
+a1bhi
+abi1et
+a1big
+ab1is
+a1bi1s.
+abi1s1s
+abi1st
+a1bk
+a1bla
+a1ble
+a1bliche.
+a1blo
+a1bn2a
+abni1s
+a1bo
+ab1oa1
+a1b2p
+a1br
+abre1u
+a1bsa
+absa1m1
+a1bsv1
+a1bt2r
+a1bw
+a1bz
+abäus1
+a1bä
+acai1
+ace1lan
+ace1me
+ace1si
+ache1me
+ache1mo
+a1chord
+achs1tig
+achs1tu1m
+achzu1r
+aci1er.
+aci1ers
+ackha1t
+acob1
+acoe1
+adami1
+adar1
+ade1he
+ade1lad
+ade1lat
+ade1leg1
+ade1lis
+ade1lle
+a1dell
+ad1em
+ade1mac
+ad1ema
+ade1mal
+ade1man
+aden1
+ade1nis
+a1deni
+ade1ram
+ad1e1reg
+ade1reis
+ade1ric
+ad1e1rol
+ade1rö
+ade1sa
+ade1sc
+ade1se
+ade1sh
+a1de1si
+ade1sl
+ade1s1or
+ade1spa
+ades2p
+ade1ss
+ade1st
+ade1sä
+adev1e
+adial1
+a1dia
+adi1enl
+a1dien1
+adi1ent
+adi1eri
+adies1
+adie1se
+adi1et
+adi1nam
+adin2a
+a1dio1
+adlun1
+adni1
+adon1i1
+a1don
+adoo1
+ad1rü
+adse1r
+adungs1
+adv1e
+adwoh1
+aeb1
+aeg1er
+ae1h
+ae1i.
+ae1id
+aelb1
+ae1lbe
+ae1lc
+ae1ld
+ae1lec
+ae1len1
+ae1lic
+ae1ll
+aella1
+ae1l1st
+ae1lu
+ae1lz
+a1e1m.
+ae1mar
+ae1me
+ae1mi
+ae1mm
+ae1mt
+ae1mu
+ae1mü
+aen1
+ae1ne
+aen1e1i
+ae1ng
+ae1nk
+ae1n1o2p
+aen2o
+ae1n2u
+ae1nw
+ae1nzl
+a1e1ra.
+ae1ren
+ae1re1u
+ae1ri
+ae1rkt
+ae1rn
+aerni1
+a1e1ro.
+ae1rob
+ae1roc
+ae1rod
+a1e1rog
+ae1rok
+ae1rol
+ae1rom
+ae1ron
+a1e1roph
+aer1o2p
+ae1ropl
+ae1ros
+ae1rot
+a1e1roz
+ae1rs.
+ae1rsk
+ae1rt
+ae1ru
+ae1ry
+a1e1rz.
+ae1rzt
+ae1s'
+ae1sc
+ae1sen
+ae1sh
+ae1sid
+ae1sl
+ae1s1o
+ae1ss
+ae1st
+aestan1
+ae1su
+ae1sy
+ae1sz
+a1e1ub1
+a1e1ug
+ae1u1m
+ae1us
+aev1
+afa1lls
+a1fal
+afe1li
+a1fel
+afen1
+afe1se
+affi1el
+af1fi
+af1fie
+afia1l
+afi1en.
+a1fie
+afien1
+afi1ens
+afni1
+aftd1
+af1t1seit
+aft1s1ei
+afts1tem
+aft1ste
+afts1trä
+aft1st2r
+afungs1
+afü2
+agai1
+a1gaj
+a1gak
+a1gal.
+a1gala
+aga1lit
+aga1ll
+a1gals
+agan1
+a1gao
+a1ga2p
+a1gass
+a1gaw
+a1g2ebl
+a1ge1bä
+a1g1elb
+ag1elec
+ag1eler
+ag1elet
+age1lic
+age1los
+a1g1em.
+ag1en
+a1genba
+a1genda
+a1geni
+a1genkl
+a1gen2o
+a1gen1t.
+agen1t
+a1gente
+a1gen1to
+a1gen1tu
+agenw1a
+a1geo
+a1gepu
+ag2e2p
+ag1eran
+ag1erauf
+ag1eraus
+ag1erem
+a1gerga
+ag1erg
+age1riem
+age1ring
+ag1eru1m
+ag1escr
+ag1esel
+ag1esex
+ag1esl
+ag1esm
+ag1esn
+ag1ess
+age1sser
+ag1esw
+ag1esö
+a1geu
+ag1ex
+aggeb1
+agg1ele
+agg1en
+agg1ero
+agg1eru
+agg1ese
+agha1s
+agha1t
+a1gic
+agi1ern
+agi1erwe
+agi1erzi
+agi1ez.
+a1gif
+a1gig
+a1gint
+a1giq
+a1glan
+agli1er
+a1glot
+agma1l
+agmi1
+agni1et
+agob1
+agou1
+a1gree1
+a1gros
+agrun1
+a1gré
+agsa1g
+a1gschen1
+ags1tab
+ags1tal
+ags1t1ee
+ags1tem
+ags1term
+agst1er
+ags1th
+ags1tor
+ags1tre
+agst2r
+ags1tru
+ags1trä
+ags1tät1
+a1gua
+a1gui
+a1gul
+agungs1
+a1gur
+a1gut
+a1gé
+aha1b.
+aha1bs
+aha1ts
+ahea1
+ahee1n1
+aheg1eh
+ahe1h
+ahe1ll
+ahe1se
+ahe1u
+ahg1eh
+ahi1dee1
+ahi1e.
+ahi1es
+ah1lsti
+ahl1st
+ahmb1
+ahme1l
+ahme1u
+1ahn
+ahne1st
+ahn1es
+ahnz1ug
+ahot1
+2ahr
+ahre1h
+ah1rü
+aht1ese
+aht1ex
+ahtv1e
+ahv2erh
+ahv1e
+ahz1
+ahäs1c
+ahös1c
+aib1e1ss
+aid1
+aidt1
+ai1e
+aie1l
+aie1ss
+ai1g'
+ai1ga
+ai1gg
+ai1gh
+ai1gi
+ai1gl
+ai1gm
+ai1gn
+ai1go
+ai1gr
+ai1gu
+ai1gv
+aii1ra1
+ail1lack
+ai1lla
+aims1
+ai1n'
+ai1nac
+ain2a
+ai1nas
+ai1nat
+ai1nau
+ai1nbl
+ai1nbo
+ai1nc
+ai1n1dl
+ai1ndo
+ai1n1dr
+ai1ned2
+ai1nee1
+ai1nen.
+ain1en1
+ai1n1es
+ai1nfr
+ai1nga
+ai1n1geb
+ai1n1geg
+ai1nhar
+ai1nie
+ain1i
+aini1er.
+ai1nin
+ai1nla
+ai1nme
+ai1n1n2a
+ai1n1ni
+ai1nor
+ain2o
+ai1now
+ai1npe
+ain2p
+ai1nq
+ai1nseg
+ai1ns1ei
+ai1nsm
+ai1nstä
+ai1nsz
+ai1n1t.
+ai1n1to
+ai1nts
+ai1n2u
+ai1nvi
+ai1ny
+ai1nz.
+ai1nä
+ai1rb1
+airt1
+ais1chi2p
+aise1la
+aise1re
+ais1sc
+aissi1
+ais1s1or
+ai1sso
+ais1s2p
+ais1st
+ais1tor
+aiw1
+aiz1u
+aje1st
+akab1
+akadi1
+akal1
+akape1
+aka2p
+akau1
+ake1lan
+ake1me
+akenv1
+aken1
+ake1sh
+ak1e1uc
+akib1
+aki1en1
+akla1s
+aklän1
+akma1l1
+akmus1
+aknäs1
+akob1
+akomb1
+akota1
+akou1
+aksb1
+aks1o
+akun1
+akv1e
+akw1
+a1lager
+a1lags
+alanti1e
+alan1ti
+al1b1ede
+alb1eis
+alb1en2a
+albrin1
+aldgeg1
+aldni1
+aleb1
+1aled2
+1alef
+ale1hu
+ale1in2p
+ale1men1
+1alenb
+alen1
+1alend
+1alene
+1alens
+ale1sch
+ale1ss
+ale1st
+ale1uti
+alg1en2a
+alg1enü
+alhof1
+1ali.
+1alia
+a1lied
+a1lief
+ali1eri
+ali1ern
+a1ließ
+1aligenb
+alig1en
+1aligenf
+1aligen2p
+1aligens
+1aligen1t
+1aligenv
+ali1gl
+ali1gr
+alile1
+alili1
+1aliu
+alizi1e
+aliz1
+1alió
+1alj
+a1lla1bf
+a1llah
+a1llans
+a1llaug
+a1llax
+a2l1lebe
+a1llec
+a1llee
+a1llenc
+allen1
+a1lleni
+a1llenm
+a1llen1to
+a1llerbar
+a1llergi
+a1llergo
+a1llers.
+a1lleti1
+a1llett
+a1lle1us
+a1lli1er.
+a1llies
+a1llik
+a1llind
+a1lline
+a1lliz1
+a1llj
+a1llou
+all1sc
+allschaf1
+a1llud
+a1llut
+a1lly
+a2l1län
+a1llät
+alnatu1
+aln2a
+alni1s
+alob1
+a1lob.
+aloni1e
+alon1i
+alsa1m
+al1sa
+1al1sd
+1al1sf
+1al1sg
+1al1sh
+1al1sk
+1al1sl
+alsle1
+1al1sr
+1al1s1s
+als1tit
+al1st
+als1trau
+alst2r
+1al1sv
+1al1sw
+alt1ein
+alt2ero
+alt1er
+a1lthy
+aludi1
+1aluh
+1alus
+a1lux
+alvo1r.
+1aly
+a1lym
+a1läc
+a1läg
+1alé
+1alí
+1alø
+a1m'
+a1ma
+amab1
+ama1l.
+am1ale
+amali1e
+am1a1ll
+amam1
+amandi1e
+a1mb
+am1b1ea
+amb1ei
+amb1en
+ambess1
+am1bä1
+a1mc
+amd1
+a1mdo
+a1mdu
+a1med
+a1mee
+amee1r
+a1mei
+a1mel
+ameldun1
+ame1lli
+a1menb
+amen1
+a1menf
+a1meng
+a1menh
+a1menk
+a1menm
+a1mens
+a1ment
+a1menw
+am1e2ra
+amera1u
+a1m1eri
+ameri1e
+a1m1ers
+ame1sc
+ame1set
+ame1sl
+ame1s2p
+a1me1ss
+ame1sta
+ame1sz
+a1met
+a1mfe
+a1mfl
+a1mfo
+a1mfr
+a1mfu
+a1mga
+amg1eh
+a1mgu
+a1mhe
+a1mhi
+ami1chl
+ami1el
+ami1en.
+amien1
+ami1erb
+ami1et
+amili1
+ami1r
+ami1ta
+a1mi1tb
+ami1td
+ami1te
+ami1tf
+ami1ti
+ami1tk
+ami1tl
+ami1to
+ami1t2p
+ami1t2r
+ami1ts
+ami1tw
+a1mj
+a1mla
+a1mm.
+a1mm'
+a1mma
+am1mass
+am1mee1
+a1mmel
+a1mmer
+ammeri1e
+amm1eri
+a1mmg
+a1mmi
+am1mic
+a1mml
+a1mmo
+am1mod
+a1mmt
+a1mmu
+am1mus
+a1mni1
+a1mo
+am1oi1
+amou1
+a1mpa.
+am2p
+a1mpe
+a1mpf
+ampfe2
+a1mpi
+a1mpl
+a1mpo
+a1mpr
+a1mps
+a1mpu
+a1mr
+a1msc
+a1ms1o
+a1msta
+ams1tag
+ams1test
+a1mstä
+a1msu
+amsun1
+amsv1
+amswe1
+a1mta
+amt1ex
+a1mth
+a1mti
+a1mtl
+a1mtn
+a1mto
+a1mt2r
+a1mts
+a1mtu
+a1mtä
+a1mtö
+a1mtü
+a1mu.
+a1mue
+a1mui
+a1mul
+a1mu1m
+a1mur
+a1mus
+amu1ss
+a1mut
+amv1e
+a1mwä1
+a1my
+a1mé
+a1möl1
+ana1cho
+an2a
+anada1
+anadi1e
+anag1eri
+anama1r
+ana1ma
+anas1chi.
+ana1us.
+an1b1ee
+ance1i
+andersa1m
+ande1seil
+andes1ei
+an2dh
+andni1
+an1dres
+ands1tag
+a1ndsvä
+andv1e
+anebi1
+anee1
+a1negr
+ane1he
+an2eh
+ane1les
+an1el
+ane1lle
+ane1llo
+ane1s2p
+an1es
+a1n1eul
+ane1us
+anezi1
+anfall1
+an1fal
+an1ga.
+an2gehe
+an1geh
+an2ge1hi
+ang1ei
+ang1elab1
+an1gel
+ang1elun
+an1gen2a
+ang1enau
+an1g1enb
+ang1en1es
+an1gene
+an1g1eng
+an1geni
+an1g1enk
+an1g1enm
+an1g1en2p
+an1g1enr
+an1gen2u
+an1g1env
+an1g1enw
+an1g1enz
+an1g1erb
+angeri1et.
+ang1erin
+an2gez
+angli1er
+an1glü1
+an1gne
+an1gsd
+an1gsh
+angs1tes
+an1gston
+an1gstra
+angst2r
+an1gsä
+an1gur
+an1gus
+anhof1
+anic1ki
+an2ic
+a1nied
+ani1ele
+ani1eli
+ani1els
+ani1ern
+ani1erz
+ani1et.
+anim1
+anint1
+anis1st
+a1nix
+anklan1
+an1kla
+ankrü1
+anm1al
+anne1la
+ann1el
+anne1rö
+ann1er
+annich1
+an1ni
+ann2ic
+annsz1
+ano1ro
+an2o
+ansa1m
+ansani1
+anseri1
+a1nsia
+ans1o.
+anspapi1
+ans2p
+anspa2p
+ans2sen1
+ans1s
+ans1tor
+ansv1
+ant1ela
+ant1ele
+ant1eli
+ant1elu
+ant1er
+anti1c
+an1ti
+anti1en1
+antons1
+an1to
+antrü1
+ant2r
+a1numm
+an2u
+anu1m
+a1nuo
+anus1s2p
+anv1e
+anw1a
+anwe1g
+a1nwh
+an1zu
+anzu1m1
+anz1upfef
+anzu2p
+anzu1r
+a1näc
+a1nüs
+aog2
+aoke1n1
+ao1re
+aorgi1
+aori1
+aos1s
+aou1
+apb1
+a2p
+ape1is
+ape1lle
+ape1lli
+ape1sc
+apfb1
+april1
+aprämi1
+arab1er
+arafal1l.
+ara1fal
+aragi1e
+arai1
+arali1e
+ara1ll
+ara1log
+ara1nor
+aran2o
+ara1nov
+ara1rea
+ar1a1ro
+aras1che.
+a1rasu
+ara1u2n
+1arb
+arb1ebe
+arb1ech
+arb1eid
+arb1ein
+arb1en
+arbänd1
+ar1bä
+1arc
+1ard
+ard1e
+ard1e1me
+arde1ss
+ar1din1i1
+ar1di
+ardun1g
+1are.
+a1re'
+a1reak
+1areh
+are1ha
+are1ho
+are1hä
+1arei
+a1reib
+a1reic
+a1reih
+are1ind
+are1leg1
+ar1e1lix
+are1mac
+are1mo
+arems1
+are1nah
+aren2a
+1arendo
+are1n1es
+1ar1enik
+1arenj
+1ar1eny
+a1repu
+are2p
+are1rau
+are1ri
+are1rol
+1ares
+are1sam
+are1sh
+are1sim
+are1spr
+ares2p
+are1sse
+are1ssi
+are1st
+1aret
+are1uf
+are1un
+1arf
+1arg
+argeg1
+arg1ela
+arg1eler
+arg1end
+1arh
+arha1t
+arhun1
+a1rhy
+1ari
+aria1r
+ar1i1e1h
+ari1el.
+ari1e1ll
+ari1els
+a1riem
+ari1en1
+ari1era
+ari1erd
+ari1erfa
+ari1erg
+ari1eri
+ari1erk
+ari1er2p
+ari1err
+ari1ers.
+ari1erv
+a1riese
+ari1esf
+ari1ess
+ari1est
+ari1eta
+ari1ete
+ari1eto
+ari1s1so
+a1ritu
+a1ritz1
+a1riv1e
+1arj
+1ark
+1arl
+arle1mo
+arlun1
+1arm
+armenti1e
+armen1
+armen1ti
+1arn
+a1rn'
+arnv1e
+1aro
+arob1
+arocai1
+aroli2
+aro1ma1
+aroni1e
+aron1i
+arou1
+a1rout
+1ar2p
+1arr
+arri1er
+ar1rie
+arri1et
+1ars.
+1arsa
+1arsc
+arschla1g
+1arsi
+arsi1er.
+ars1o
+ars1s1o
+1arste
+ars1tho
+1arsz
+1art'
+1arta
+1artb
+1arte
+1artg
+1arth
+1arti
+a2rtig
+artle1b1
+1artm
+art1s1o
+1artt
+1artu
+1artz
+1artä
+1aru
+a1ruck
+arun1de
+arungs1
+aruse1
+arv1e
+1arw
+1ary
+1arz
+arze1ll
+arz2e
+arz1u.
+1arä
+aränd1
+aräs1
+arät1
+a1rös
+a1rüc
+asaa1
+asa1lle
+asa1m
+asatt1
+asauri1
+asaus1
+aschee1n1
+as1ch1ero
+aschz1u
+aseb1
+asee1r
+aseg1
+asegg1
+ase1he
+ase1ho
+as1ei
+ase1lle
+ase1me
+asen1
+asg1en
+asgrun1
+asha1b1
+ashi1e
+asi1ek.
+asi1eri
+asi1ers.
+asmani1
+asni1s
+as1o.
+asob1
+as1of
+as1og
+as1ol
+as1on
+as1os
+as1ou1
+as1ov
+as1ow2
+asowi1
+a1ssac
+as1sack
+a1ssaf
+a1ssai
+a1ssal
+as1same
+assa1m
+a1ssar
+a1ssbi
+a1ssbl
+a1ss1bä
+as1sc
+a1sseg
+a1sseh
+a1ssek
+a1ssel
+a1ssenb
+assen1
+a1sse2p
+a1sseu
+a1ssev
+a1ssfa
+a1ssho
+a1ssi
+a1ssla
+a1s2sle
+a1ssli
+a1ssma
+a1ssni
+ass1o
+a1s1sod
+a1ss1oh
+a1ss1ok
+a1ssol
+a1ss1om
+a1ss1or
+a1ss1os
+as1spat
+ass2p
+as1spri
+as1spü
+a1ssrö
+as1stau
+a1ssti
+as1stra
+asst2r
+as1stä
+assv1e
+a1ssvi
+a1sswa
+a1ssy
+as1sän
+as1sär
+a1sta
+as1tank
+a1stel
+aste1ll.
+aste1llb
+aste1lli
+aste1lls
+ast2e1llv
+aste1llz
+astet1s
+as1tev1
+asthi1
+a1stie
+a1sti1el1
+asti1en1
+a1stin
+as1tink
+a1stl
+as1topf
+ast1o2p
+a1st2r
+as1tre2p
+astrich1
+a1sty
+astz1ug
+as1tür
+asu1m1
+asv1e
+asyl1
+a1ta
+atai1
+at1a1res
+a1tb
+atbeg1
+atbis1
+a1tc
+a1td
+at2e.
+at2ear
+at2ed
+at1ee1
+at1ei
+at1el.
+at1elf
+at1elj
+at1eln
+at1elr
+at1els
+at1emi
+at1er.
+at1era
+at1erb
+at1erc
+at1erd
+at1ere
+at1erf
+at1erg
+at1erh
+at1eri1ea
+at1eri1eb
+at1eri1e1lo
+at1eri1et
+at1eri1ev
+at1erj
+at1erk
+at1erl
+at1erm
+at1ern
+at1ero
+at1er2p
+at1err
+at1ers
+at1ert
+at1eru
+at1erv
+at1erw
+at1erz
+at1esi
+at1esk
+at1esm
+ate1sse
+a1tf
+a1tg
+atg1en
+a1th
+athani1
+athe1le
+athe1u
+athof1
+a1tia
+a1tib
+a1tic
+ati1el
+ati1en1
+ati1ern
+ati1gr
+a1tik
+a1til
+a1tim
+a1ti2p
+atis1tel
+a1tix
+a1tj
+a1tk
+atla1s
+a1tn
+atni1
+a1to
+atoli1
+atom1m
+a1t2r
+atrai1
+atsa1g
+ats1chef
+ats1tem
+at1ste
+ats1tic
+at1sti
+ats1träu
+at1st2r
+ats1tur
+a1t1ta
+att1ech
+att1el.
+att1ela
+att1elb
+att1eld
+att1ele
+att1elf
+att1elg
+att1elh
+att1elk
+att1elm
+att1eln
+att1el2p
+att1elr
+att1els
+att1elt
+att1elu
+att1elz
+a1ttens
+att1en1
+a1tt1er
+a1tti
+a1ttm1
+a1tto
+a1tt2r
+attrich1
+a1ttu
+a1tty
+atungs1
+atus1t
+a1tv
+a1tw
+a1ty
+a1tì
+a1tı
+auat1
+aub1en2a
+aubrin1
+au1brü1
+au1chl
+audeg1
+audi1er.
+aueb1
+auftrich1
+auft2r
+aufun1ge
+au1fu
+au1g1ehe
+aug2ell
+aug1en2a
+aug1eru
+augi1er
+auhb1
+aulmi1
+aum1m
+au1m
+au2n
+aunb1
+auni1s
+aunt1er.
+aunt1ere
+aunv1
+aupb1
+au2p
+aura1l
+aureg1
+aure1u
+auri1er.
+auriti1
+ausa1g
+auseh1
+ausit1
+auslandschaf1
+ausland1
+aus1landsc
+aus1saa1
+au1ssa
+aus1sac
+aus1sag
+aus1sal
+aus1sa1m
+aus1san
+aus1sau
+aus1sc
+aus1seh
+aus1s1ei
+aus1sende.
+au1ssen1
+auss1end
+aus1senden
+ausseri1
+aus1she
+aus1sin
+au1ssi
+aus1sk
+aus1s1or
+au1sso
+aus1s2p
+aus1st
+aus1sz
+aus1tag
+aus1tanz
+aus1t1ea
+au1ste
+aus1t1ee
+aus1term
+aust1er
+aus1tick
+aus1tier
+aus1tig
+aus1tob1
+aus1tod
+aus1t1oi
+aus1tom
+aus1tot
+au1s1tram
+aust2r
+aus1trat
+aus1trau
+aus1tric
+aus1trom
+aus1tu2p
+au1s1tut
+aus1tür
+aut1eb
+aut1ei
+aut1ele
+authi1
+autrot1
+aut2r
+autsa1m
+aut2s
+auzun1
+ava1lam
+ava1ll
+av1e
+avee1
+ave1rid
+averni1
+avri1
+avö1
+aw1a
+awa1r.
+awb1
+awe1gg
+awi1en1
+awi1er
+awt1
+axma1l
+aya1le
+ayint1
+ayng1
+aysi1
+aza1ll
+azb1
+azde1
+aze1h
+az2e
+aze1is
+aze1ma
+aze1rol
+aze1ros
+aze1sc
+aze1st
+azi1c
+azi1el
+azi1ge
+azi1gr
+azm1
+azri1
+az1ui
+az1uo
+az1ur.
+az1u1ra
+az1u1ri
+az1urs
+azz1
+aßa1l
+aßv1e
+aéri1
+1ba.
+1ba'
+1baa
+baa1c
+baa1r
+ba1b1el
+bab1er
+1babi
+bablag1
+ba1bla
+ba1ble1
+1ba1by
+ba1chö
+bad1
+1bad.
+bade1i
+bade1la
+badi1er
+badi1g1
+bae1n1
+bae1r
+bag1el
+baha1t
+1bai1
+1bal
+baldun1
+balg1er
+ba1ll
+bal1liga
+ba2llok
+bal1sa1
+balv1
+ba1mb1
+bandstan1
+bandun1
+banki1e
+barab1
+bardi1e.
+b1ard
+bar1di
+ba1re2p
+bari1er
+b1ari
+ba1rif
+barkau1
+b1ark
+barle1b1
+b1arl
+1b1arr
+barsa1m
+b1arsa
+bars1tal.
+1bas
+base1lin
+base1m
+ba1stel1
+bat1ea
+bathi1
+ba1th
+bati1e
+bau1fl
+baumv1
+bau1m
+baus1s
+1baz
+1b1ba.
+1bbac
+bbagg1
+1bbat
+bbau1
+bbb1
+bb1eb1
+bb1ein
+bb1eis
+bb1eiz
+bb1elu
+bb1en
+bbe1nä
+bb1er.
+bb1erb
+bb1erf
+bb1erg
+bb1erh
+bb1erj
+bb1erk
+bb1erl
+bb1erm
+bb1ern
+bb1er2p
+bb1err
+bb1ers
+bb1ert
+bb1erw
+bb1erz
+bb1eu
+bb1ey
+bb1i
+b1bi1s.
+bbrech1
+bbrich1
+b1brü1
+1b1by
+bbänd1
+b1bä
+bdea1
+b1de1ll
+bd1em
+bdös1
+1bea
+b1ea1chs
+b1eade
+b1ea1le
+b1ea1ls
+b1eame
+b1ea1ne
+b1ea1ni
+b1ea1n2o
+b1ea1ns.
+b1ea1rab
+b1ea1rma
+be1arm
+b1ears
+b1ease
+b1east
+b1eat.
+b1eater
+b1eatl
+b1eatmet1er
+b1eats
+b1eatt
+beaus1
+b1eaux
+1be1ba
+beb1en
+1bebi
+1be1bä
+1be1bü
+1bede
+1be1di
+bedun1
+1bee
+b1eeb1
+b1eek
+b1ee1li
+b1ee1n.
+been1
+b1ee1ne
+b1ee1nl
+bee1ns
+b1ee1r.
+b1ee1rg
+b1ee1rs
+bee1s
+1befa
+1befi
+1befl
+1befo
+1befre
+b2efr
+1befü
+beg1ee
+be1g1ehe
+beg1ehu
+beg1eni
+b1ehc
+b1ehe.
+b1ehl
+b1ehn
+behni1
+be1ho
+b1ehr
+b1eht
+b1ehw
+b1ehz
+1behö
+b1eicht
+beilschaf1
+b1eils
+beimi1
+b2e1imm
+b1ein.
+b1ein'
+b1einab
+bein2a
+b1einar
+b1einau
+b1einb
+b1eine
+b1einf
+b2e1ing.
+b1einge
+b1eingl
+be1inhalte.
+be1inhalt1en1
+be1inhaltet
+b1einhe
+b1ein1i
+b1eink
+b1einl
+b1einm
+b1ein2p
+b1einr
+b1eins.
+b1einw
+beinwoh1
+b1einz
+b1eis.
+b1eisel
+b1eisen
+b1eisl
+b1eiso
+b1eiss
+bei1t2r
+beits1t
+b1eitö
+1bej
+bekt1
+1b1el.
+b1el'
+b1elaf
+b1elak
+b1elal
+b1elam
+be1lang
+b1elar
+belau1f.
+b1elb
+b1elc
+b1eld
+b1ele.
+b1eled2
+belee1
+b1elef
+b2eleg
+beleg1en
+b1eleie
+b1elel
+b1el1em.
+b1elen1
+b1eler
+b1elet
+b1elex
+b1elf
+1b1elg
+b1elh
+b1eli.
+b1elid
+beli1e.
+b1elig
+b1elim
+b1elind
+b1elj
+b1elk
+1bell
+be1lls
+b1elm
+b1eln
+b1elos
+b1elot
+b1elou
+b1el2p
+b1elq
+b1elr
+b1els
+b1elt
+b1eluc
+b1elug
+b1eluh
+b1elu1m1
+b1elun
+b1elut
+b1elv
+b1elw
+b1ely
+b1elz
+belz1un1g
+bem1al
+be1man
+b1emb
+b1eme.
+be1mei
+be1men1
+1bemi
+1bemo
+be1mä
+1bemö
+b1en.
+b1en'
+benag1
+ben2a
+b1ename
+b1end
+b1ene.
+b2eneb
+b1enec
+b2en2eh
+b1enek
+b1en1em
+b1en1es
+b1enet.
+ben1et
+b2eneu
+b1enhü
+b1enig
+b1enis
+b1enit
+benleg1
+b1enmä
+bennun1
+ben1n2u
+b1enos
+ben2o
+b1ens.
+bens1tag
+bens1treu
+benst2r
+bens1tri
+b1ensz
+ben1t
+bentrich1
+bent2r
+b1enus
+ben2u
+benv1e
+benw1ar
+b1en1zü
+beob1
+1beq
+b1er'
+b1eraf
+b1erau2n
+b1eraut
+berd2em.
+b1erea
+b1ereb
+b1eree1
+bereg1
+b1eregu
+b1ereie
+b1eren.
+b1erenb
+b1erene
+b1ereni
+b1erenj
+b1erens
+bere1sc
+bere1ss
+b1eret
+b1erew
+b1erex
+b1erez
+berg1erin
+b1erhof1
+b1eri.
+b1eria
+b1erib1
+b1erig
+b1erik
+b1eril
+b1erin.
+b1erings
+b1erinn
+b1erisc
+b1eritz1
+1b1erl.
+b1erling
+b1ermai1
+b1ermat
+b1erob
+b1erom
+b1eros
+be1rou
+b1erow
+1b1er1ry
+1berschen1
+bers1on
+1b1ert.
+b1ertos
+b1erul
+berun1d
+b1erung
+b1erunt
+b1eru2p
+b1erut
+1b1ery
+berzun1
+berzu1r
+beränd1
+b1es.
+b1es'
+besa1me
+b1esanga
+b1esant
+b1esa2p
+b1esar
+besau1
+b1esb
+1besc
+b1esco
+b1esd
+b1ese.
+b1eseif
+bes1ei
+b1esel.
+b1eselc
+b1esele
+b1esen.
+b1es1en2a
+b1esenb
+b1esenf
+b1esenge
+b1esengi
+b1esengr
+b1esenh
+b1esenk
+b1esenm
+b1esenr
+b1esens
+b1esent
+b1esenv
+b1esenz
+b1ese2p
+b1esex
+b1esf
+b1esg
+1besh
+b1eshö
+b1eshü
+b1esim
+b1esir
+b1esj
+b1esk
+b1esm
+b1esn
+1bes2p
+b1espar
+b1espf
+b1espä
+b1esq
+b1esr
+b1essc
+b1essk
+be2sso
+b1ess2p
+b1esst
+bessun1
+b1essz
+b1essü
+be1staa1
+b1estag
+besti1e.
+b1estol
+b1esträ
+best2r
+besun1
+b1esur
+b1esv
+be1sy
+b1esä2p
+bete2
+1beti
+betit1
+1beto
+1bet2r
+1bett
+b1eune
+b1euni
+b1eus
+b1eut
+1bev
+bev1e
+bev1ord
+1bewi
+1bewu
+b1ey.
+b1eyb1
+b1eye
+b1eyr
+1bez
+bez1ug
+bfall1
+b1fal
+bfeg1
+bfe1ll
+b1fel
+bfun1
+bgangs1
+bgas1t
+bg1ehen1
+b1gehe
+bgerun1
+bgeränd1
+b1gerä
+bgw1
+1bha.
+1bhar
+bhau1
+bhea1
+bheb1
+bhe1ll
+bher1
+bhof1
+bhol1
+bhun1
+bhös1
+1bi.
+bial1
+1bib1
+bibb1
+bibrin1
+1bic
+bi1chr
+bic1ki
+bieb1
+bi1ec
+bi1e1ll
+bi1en.
+bien1
+bi1en2a
+bi1enb
+bi1enf
+bi1enk
+bi1enm
+bi1enn
+bi1en2p
+bi1enr
+bi1ens
+bi1ent
+bi1en2u
+bi1env
+bi1enw
+bi1esk
+bi1eta
+bi1ett
+bi1ety
+bi1gam
+bi1gr
+1bih
+1bij
+1bil.
+bild1
+bile1mo
+bili1e.
+bilä1
+binde1se
+bin1de
+bin1g1el
+bing1em
+bi1nü
+1bio
+bi1rs1c
+birs1ta
+1bis.
+bi1sa
+bisa1m1
+bi1sb
+bi1sc
+bi1sd
+bi1se
+bi1sf
+bi1sg
+bi1sha
+bi1sho
+bi1si
+bisis1
+bi1sj
+bi1sk
+bi1sle
+bi1sli
+bi1slu
+bi1slö
+1bism
+bi1sma
+bi1sme
+bi1smi
+bi1smo
+bi1sn
+bi1so
+bi1s2p
+bi1sq
+bi1sr
+bi1ss
+bis1sa1m
+bis1s1or
+bi1sso
+bis1spe
+biss2p
+bi1st1er
+bi1sto
+bis1tor
+bi1st2r
+bis1tu1m
+bi1su
+bi1swi
+bi1swo
+bi1swü
+bi1sz
+bi1sä
+1bit.
+1bita
+1bitc
+1bite
+bit1ei
+1bitl
+bitra1g
+bit2r
+1bits
+bitt1el
+1bitu
+1bi1té
+bius1
+biv1
+1biy
+bißv1
+bje1s
+bkape1
+bka2p
+bkau1
+bke1l
+bkitt1
+bklan1
+bkla1s
+bkle1b
+bkont1
+bkreis1
+bla1sste
+blas1test
+blau1
+blea1c
+1blec
+blee1
+bleg1en
+ble1l
+ble1ment
+blemen1
+ble2mm
+bles1e1i
+ble1sel
+ble1sh
+ble1s2p
+ble1ss
+blet1
+bl1i1edl
+bli1er.
+blings1
+1block
+1blon
+blou1
+1blow
+blubb1
+blue1s
+1blu1m
+blut1ei
+bläs1c
+blüs1c
+bmag1
+bmagi1
+bmee1
+bmeta1
+bmi1t.
+bnab1
+bn2a
+bn1e1s
+bnich1
+bn2ic
+1bnik
+bo1a1rd
+b1oa
+bog1er
+bohn1
+boi1ne
+b1oi
+1bol
+bomb1
+1bon
+bonni1er.
+bo1n1ni
+boo1
+borgi1e
+borgni1s
+borio1
+borlän1
+borni1s
+bo1s1chel
+bo1s1chet
+bose1r
+bosit1z
+b1osi
+bosni1
+b1osn
+bos1o
+bou1
+boulli1
+bovo1n
+bow1
+boz1
+bp1ari1
+b2p
+bpe1ll
+brabb1
+brafe1
+brai1
+bral1
+brand1
+brani1
+1brea
+brech1tsf
+b1rechts
+1bred
+bree1
+breli1
+bre1mon
+1bren
+bre1sch
+bre1s2p
+bre1ss
+bre1st
+1bret
+brich1t.
+brich1ts
+brie1ll
+bri1ens
+brien1
+bri1enz
+bri1er.
+bri1ern
+bri1ers.
+bries1c
+bri1eta
+brios1
+bromme2
+brot1ei
+1bru
+brun1
+bränd1
+brät1
+1brü
+bsa1mm
+bsa1mt
+bsatt1
+bsauri1
+1bsb
+bsbeg1
+bs1chef
+bseb1
+bseg1
+bseh1
+bs1ei
+bsen1
+bseri1e
+bsfall1
+bs1fal
+1bsg
+bsint1
+1bsk
+1bsl
+1bsm
+bsob1
+bs1od
+bs1of
+bs1on.
+bs1ondere
+bs1ons
+1bsr
+1bs1s
+bss1o
+bs1tag
+bs1ta1ta
+bs1t1eic
+bst1ei
+b2s1t1eil1
+b1ste1mm
+bs1tob1
+bs1tod
+bs1tou1
+bs1treu
+bst2r
+b1stän
+bs1täti
+bstät1
+1bsv
+1bsä
+bsäng1
+b1tags1
+bt1ea
+bt1ee1
+bt1ei
+bt1el.
+bt1ele
+bt1eln
+bt1els
+bt1er
+bt1eu
+btrai1
+bt2r
+1btreus
+btrich1
+b1tsa
+1bu.
+bubb1
+bub1el
+bub1en
+bubi1g
+bub1i
+1buc
+budwei1
+1bul
+bumb1
+bu1m
+bumv1
+bun1d
+bun1ga
+bungs1c
+bunt1er.
+bunt1ere
+1bu2p
+1burg
+burg1er
+1bury
+1bus
+bu1s1chas
+bu1sch
+bus1chau
+bus1o
+bus1sa1m
+bu1ssa
+bus1sc
+bussi1e
+bu1ssi
+bus1ski
+bus1spa
+buss2p
+bus1st1ei
+bus1st2r
+bus1tab
+bus1t1ei
+bu1ste
+bus1term
+bust1er
+busti1e
+bus1tis
+bus1tor
+bus1t2r
+1buz1
+buzi1e
+bv1e
+bv2erhä
+bw1ar
+bwä1
+1by
+bygrun1
+byke1
+bylg1
+1bzelter.
+bz2e
+bzelt1er
+1bzet
+bzott1
+bz2uch
+bz1uc
+bz1uges
+bzu1m1
+bz1upfe
+bzu2p
+bzu1r
+bzuz1u
+1bä
+bäbi1
+bäb1
+bäg1
+bänd1er.
+bäng1
+bäs1che
+bäug1
+bä1us.
+béb1
+béli1
+béri1
+1bí
+1bö
+bøg1
+1büc
+büg1
+bürg1er
+1büs
+büt1
+1bı
+caa1
+cad1
+cadi1e
+cae1r
+cae1s
+cafi1
+cagni1s
+cahi1
+cale1u
+cali1e
+ca1ll
+calv1
+cami1e
+canb1
+cand1
+can1de1ll
+cang1
+cans1
+canti1e
+can1ti
+cape2st
+ca2p
+capg1
+carabin1i1
+caree1
+carni1
+c1arn
+carti1e
+c1arti
+case1in
+cas1ei
+case1l
+caste1ll
+ca1stel
+cat1er
+caug1
+ca1url
+caut1
+cavali1ere
+cavali1ers
+caz1
+ccheri1e
+cchi1e
+cci1e.
+cci1er
+ccre1s
+c1ea1le
+c1ea1ne
+cegli1
+ce1ha
+ce1ho
+ce1hu
+ce1hö
+ce1i.
+ce1ind
+ce1is
+ce1lab1
+ce1lau
+ce1law1
+ce1leg1
+ce1lei
+ce1leu
+ce1lif
+ce1lit
+ce1ll
+ce1lok
+ce1lä
+ce1lö
+cem1a
+ce1mai1
+ce1man
+cemb1
+ce1mod
+ce1mon
+ce1mu
+ce1mä
+ce1mü
+cen1
+ce1n1et
+c1e1nez
+cenleg1
+cerb1
+ce1reg
+cere1u
+ce1rit
+cerni1e
+ce1rob
+ce1roc
+ce1saa
+ce1sam
+ce1sche
+ce1s1ei
+ce1sek
+ce1sh
+ce1s2p
+ce1ss
+ce1st
+ce1su
+ce1sz
+cet1es
+ce1u.
+ce1uh
+ce1u1m
+ce1un
+ce1us.
+cev1
+ceva1
+cg1el
+1chae1m
+chae1r
+1chaffela
+cha1f1fel
+chaf1ti
+chaf1tz
+cha2llöc
+cha1ll
+1chanc
+1chanse
+1chansh
+1chanso
+1chaos1
+1chap.
+cha2p
+chau1fk
+1chav1
+chdun1
+1checkl
+chee1ns
+cheen1
+1chef.
+1chefs
+2cheh
+che1lad
+1chellingw
+che1lling
+che1mal
+che1man
+che1mar
+1chemie.
+1chemik
+1chenect
+chen1
+che1not
+chen2o
+che1rol
+ch1ero
+1cherzan
+1cherzo
+che1set
+che1sie
+che1s1o
+1cheven1
+1chiat
+1ch1ie1da
+chi1e1di
+chi1e1do
+1chieha
+ch1ie1h
+1chiermo
+chi1ern
+chi1esa
+1chiet2p
+1chi1ett
+1chillac
+chi1lla
+1chillà
+1chinok
+chin2o
+1chinot
+1chiph
+chi2p
+1chipl
+1chips
+1chirur
+chi1ru
+1chi1rò
+1chizophr1enia
+chiz1
+chiz1o2p
+1chizz
+chlau1
+chnau1
+chn2a
+chnee1
+1ch1ofi
+1cholars
+ch1olar
+1cholastic
+chola1s
+1choles
+ch1ole
+1cho1ol.
+ch1ool1
+1cho1olb
+1cho1ole
+1cho1olf
+1choolg
+1cho1ols
+1choral1
+1choreo
+1chores
+1chors.
+1chorä
+1christ
+1chro1mo
+chrom1
+1chron1i
+1chsell
+chug1
+1chutn
+1chyl
+chäs1t
+1chüec
+ci1a1ro
+cic1k
+ci1dre1h
+ci1dr
+ci1ed
+c1i1eg
+ci1ej
+ci1ek
+ci1el
+cie1ll
+ci1en1
+ci1erg
+ci1eri
+ci1er2p
+ci1err
+ci1et
+ci1eu
+cili1e
+cimi1e
+cisg1
+cis1st
+cis1to
+citi1g
+ckat1
+ckau2f.
+ckaus1
+cke2lle
+cke1ma
+cke1nas
+cken1
+cken2a
+cke1ras
+1ckert.
+cke1s1ei
+cke1st
+cki1e1l
+cki1en1
+cki1est
+ckie1s
+1ckler
+1ckli.
+ckm1al1
+1ckman.
+ckob1
+cksal1
+1cks1burg1
+cks1char
+1ck1stad
+cks1tas
+cks1taub
+cks1turm
+cksz1ug
+ckt1er
+cku1m1
+ckungs1
+1ckw1ard
+ckw1ar
+clae1
+clan1
+cla1s
+clea1
+clee1
+cle1i
+cle1ll
+cle1st
+cle1u
+club1
+clue1
+coa1c
+c1oa
+cobs1t
+c1obs
+cocai1ne
+coct1
+cod1
+code1l
+c1ode
+code1n
+coe1li
+c1oel
+coe1m
+c1oe1u
+coffe1
+coi1n.
+c1oi
+coi1ns
+c1olb1
+colee1
+c1ole
+cole1m
+cole1sl
+coli1e
+colli1er
+combi1e
+comic1
+co1mi
+cond1
+condotti1
+con1dot
+conste1l
+coob1
+copai1
+c1o2p
+cope1l
+cordi1e
+cor1di
+co1rh
+cormi1e
+corni1s
+co1roc
+corsa1g
+cosi1c
+c1osi
+cos1o
+cou1
+c1oub1
+count1er
+cousi1e
+cou1ssi1
+couti1e
+cov1
+cow1
+cpai1
+c2p
+cra1ssi1
+cree1
+cre1ss
+cressi1
+cre1st
+creti1e
+crib1
+crissi1
+crou1
+croupi1
+cr1ou2p
+crub1
+cseri1
+cs1o
+cs1s
+css1o
+ct1el
+ct1er
+ct1es
+ct1eu
+ctez1
+ctob1
+ctrai1
+ct2r
+ct1s1o
+cub1
+cu1ba1l
+cude1l
+cudi1
+cue1in
+culi1e
+cumb1
+cu1m
+cun1
+cune1
+cunt1
+cus1o
+cuvi1
+cv1e
+cw1at1
+cyb1
+cyn1i1
+cyste1
+cze1l
+cz2e
+cze1st
+czm1
+cz1u
+d'ang1
+d'a1n
+1d'g1
+d'u1ne
+1da.
+1daa
+daa1c
+daa1n
+1dab.
+dabs1o
+1daci
+1dae
+dae1l
+dae1m
+1dag
+1dai
+daib1
+dai1g
+dai1n.
+da1lag.
+da1lage
+da1lam2p
+dalee1
+da1leu
+da1lic
+1dalk
+da1ll'
+da1lla
+da1lld
+da1llg
+da1llm
+da1lls
+da1llt
+dalm1
+dals1o
+dalv1e
+1dam.
+1dame
+da1me1l
+dami1e
+1damt
+1dan.
+1danc
+da1neb
+dani1el
+1dank
+danleg1
+danm1
+1dan2o
+da1not
+1dans.
+dan1z1u
+1dar.
+dari1e
+d1ari
+darni1er
+d1arn
+1das.
+1dase
+1dasj
+1dasy
+1da1ta
+dat1ei1
+dat1er
+1dati
+1da1to
+dats1t
+datt1
+daub1
+1daug
+daumi1
+dau1m
+dauni1e
+dau2n
+da1url
+1dav
+daxb1
+1day
+1dbab
+db1eat
+d1bea
+1dbeb1
+1d1b1ee1
+db1eig
+db1ein
+dbem1
+db1eng
+db1enz
+1dbeo
+db1erg
+db1ern
+db1ert
+db1esen
+db1eu
+db1ey
+dbi1el
+dbi1s
+dbla1s
+1dbli
+1dblo
+1dblu
+db1oa1
+1dboo1
+1dbor
+dbrech1
+1dbro
+d1brü1
+1dbyb
+d1by
+1dbän
+d1bä
+dbänd1
+1dbär
+1dbög
+d1bö
+1dbüh
+dbürg1
+dcolli1
+dcore1
+1ddac
+ddea1
+ddelschaf1
+dd1em
+1dde2p
+dde1st
+ddha1n
+1ddic
+ddie1
+1ddin
+ddle1m
+1ddor
+1ddra
+1ddrü
+ddä1
+1deag
+dea1lle
+deam1
+1dean
+dea1n'
+dea1ne.
+d1eane
+d1ea1ns.
+1dear
+1deas
+1de1ba
+debb1
+deb1ein
+de1bei
+deb1en
+1debi
+1debl
+1de1bo
+debrech1
+1de1bü
+1dec
+dechs1
+1de1da
+dede1ss
+1de1di
+1de1do
+dedun1
+1dee
+deeb1
+dee1ns.
+deen1
+d1ee1r.
+dee1rf
+d1ee1ri
+dee1rt
+1defe
+1defi
+1defl
+1defo
+1defä
+1defü
+deg1en.
+deg1en2a
+deg1enb
+deg1ene.
+deg1en1en1
+deg1enf
+deg1eng
+deg1enh
+deg1eni
+deg1enk
+deg1enr
+deg1ens
+deg1en1t
+degg1
+1degl
+1dego
+1degr
+de1ha
+de1hec
+de1hef
+de1hei
+de1hel
+de1hem
+de1hen1
+de1her
+1de1hi
+1dehn
+1de1ho
+1de1hu
+1de1hy
+1de1hä
+de1hö
+1de1hü
+de1ik
+de1im2p
+de1info
+2deinh
+d1e1in2o
+de1inse
+de1i1sc
+de1ism
+de1ist.
+de1i1st1en1
+de1isti
+de1ists
+1dej
+1deke
+1deki
+1deku
+1dekä
+1dekö
+1del'
+de1la1bo
+delab1
+de1lak
+1delal
+1deld
+de1leb
+de1lee1
+deleg1
+de1lege
+de1leib
+de1leic
+de1leut
+de1lich
+de1lin1i
+de1li2p
+de1list
+1dell
+de1ll.
+de1ll'
+de1llab
+de1llann
+de1llar
+de1lla1s
+de1llb
+de1llc
+de1lld
+de1lle.
+de1llen1
+de1llf
+de1llg
+de1llh
+de1llk
+de1ll1l
+de1llm
+de1lln
+de1ll2p
+de1llr
+de1lls
+de1llt
+de1llun
+d2e1llv
+de1llw
+de1lly
+de1llz
+de1log
+de1lok
+de1lose
+1delsblad
+del1sb
+1delta
+1delu
+de1luc
+de1luk
+d1e1lun1d
+de1lux
+delv1e
+1delwa
+delz1u
+1delä
+d1ema
+de1mam
+de1ma2p
+de1m1arc
+de1m1ark
+de1masc
+de1mast
+de1mau
+d1emb
+de1mec
+de1med
+de1mei
+d1emel
+de1meng
+demen1
+de1mens
+d1emen1t.
+d1ementa
+d1emente
+d1emen1ti
+d1emen1to
+d1emenz
+d1emer
+de1mes
+d1emet
+d1emeu
+d1emh
+1d1emi
+demi1en1
+de1mil
+de1mitt
+d1emk
+d1emm
+de1mme
+de1mmi
+d1emob
+de1m1ob1i1
+d1emoc
+d1emod
+d1emog
+d1emol
+d1emom
+d1emon
+d1em1o2p
+d1emor
+d1emos
+d1emot
+de1motiv1
+d1emt
+1demu
+d1emul
+d1emu1m
+d1emut
+d1emv1
+d1emw
+1de1mä
+1demö
+1d1emü
+1den2a
+d1e1nack
+de1nag
+de1nah
+de1n1arr
+de1nase
+1denb
+1deni
+d1eni1er
+1denj
+1denke
+1denl
+denleg1
+1denm
+1denn
+1den2o
+de1not
+1den2p
+1denq
+1denr
+dens1tanz
+dens1t1o2p
+den1t
+dental1
+1den2u
+1denv
+1denä
+de1nä2p
+1deoh
+1de1o2p
+deorgi1
+1depe
+de2p
+1depf
+1deph
+1depi
+1depl
+1depo
+1deps
+1depu
+1deq
+d1er'
+de1rabb
+de1rais
+d1erai
+de1ram2p
+d1eras
+d1erau.
+d1erbu
+d1er1bä
+derbänd1
+d1erbü
+d1erc
+d1erde
+derdun1
+de1refo
+d1ereg
+de1rege
+de1regl
+de1reic
+de1reit
+d1erek
+de1renn
+de1re2p
+dere1ss
+de1resta
+d1eret
+de1reu
+de1rev
+d1er1fel
+derhof1
+de1r1ieg
+de1riem
+de1rings
+de1ri2p
+de1ritt
+derkau1
+d1erl.
+d1erlec
+d1erman
+d1ermat
+d1ernac
+dern2a
+d1erol
+d1eros
+d1erpo
+der2p
+d1ersch.
+d1ersen1
+d1ersga
+dersle1b
+d1ers1on
+d1ers1s1o
+d1erston
+1dertjä
+1dertn
+deru1m1
+d1ery
+d1erä
+de1rät
+de1röh
+d2e1rüc
+de1saa
+desa1m
+de1same
+de1scher
+de1schr
+1desee
+de1sek
+de1selig
+de1senk
+de1seq
+desfall1
+des1fal
+desgeg1
+1desi
+de1sic
+de1so.
+de1s1oc
+de1sog
+de1spor
+des2p
+de1spu
+de1sse.
+de1sser.
+1dessi
+de1stab
+de1stat
+1deste
+de1stel
+de1stem
+de1stes
+de1stu
+de1suc
+de1sy
+de1sz.
+de1säc
+1desö
+1deti
+1deto
+detrich1
+det2r
+1dets.
+1dety
+1detü
+1deu
+de1u.
+d1eub1
+de1uf
+de1u1m
+de1un
+de1url
+de1us.
+de1usi
+1devi
+devo1n
+1dewi
+1dewu
+1dewä
+1deza
+dez1uber
+dezug1
+1dezw
+1dezä
+1dezü
+1deä
+1deü
+dfall1
+d1fal
+1d1fam
+1dfed
+dfe1ll
+d1fel
+1dfelt
+1dfen
+1dfet
+dfing1
+dfoli1
+1dfort
+1dfos
+1dful
+dfun1
+1dfül
+1dgau
+dg1ehen1
+d1gehe
+dg1ei
+dg1en.
+dg1end
+dg1eni
+dg1ens
+dgeränd1
+d1gerä
+dgetunt1
+1dgi
+dgla1s
+dgras1
+dgs1
+1dgun
+dgw1
+1dgä
+1dh.
+1dhai
+1dhak
+1dha1t
+1dhau
+dhaus1c
+dhea1
+dheb1
+dhee1
+1dhef
+1dhei
+2dh1eil.
+dheil1
+dheits1
+dhe1ll
+dhi1er
+dhint1
+dhoe1
+dhof1
+dhol1
+1dhor
+dhot1
+dhou1
+1dhun1
+dhunt1
+1dhy
+dhäs1c
+1dhäu
+1dhö
+dhös1
+1dhü
+1di.
+1dia
+dia1c
+dia1lei
+dia1llo
+dia1lu
+1dib
+1dicappa
+dica2p
+dicap2p
+1dich
+di1chl
+didas1
+didg1
+d1ieg1
+di1ego
+di1egu
+di1ek.
+di1elek
+1dien1
+di1en.
+di1ena2p
+dien2a
+di1enat
+di1enbe
+di1enbo
+di1enc
+di1end
+di1enfa
+di1eng
+di1eni
+di1enn
+di1enor
+dien2o
+di1enr
+di1ens.
+di1ensc
+di1ense
+di1ens2p
+di1enz
+di1eo
+di1e2p2p
+d1ie2p
+di1er'
+di1ern.
+die1s.
+die1sb
+die1sf
+die1si
+die1ss
+di1esse.
+die1st
+di1et.
+di1ets.
+di1eu
+di1eva
+di1ez
+1dif
+dig1
+digo1
+di1gra
+di1gri
+di1gä
+dilan1
+1dile
+di1lli1e
+1dinc
+din1di1
+1dine
+din1e1m
+di1ness
+din1es
+1ding
+ding1eli
+din1gel
+1din1i
+1din2o
+1dio
+1di2p
+1dis.
+disb1
+di1s1chet
+diseri1
+1dish
+1disi
+1disk
+dis1st2r
+1dist
+dis1th
+dis1to
+1disz
+1dit
+dit1ei
+ditschi1
+1diu
+1div1
+diw1
+1diz
+1djag
+djea1
+1djer
+1djou
+1dju
+1djä
+1dkad
+dka1ne
+1dkas
+dkau1
+1dke.
+1dker
+1dkes
+1dkis
+dkla1s
+dkle1b
+dklän1
+1dkri
+dkrü1
+1dkug1
+1dkv
+1dkö2p
+1dlac
+dlae1
+dlag1er
+dlat1
+dlau1
+dleb1
+dle1ber
+1dled2
+dleg1
+dle1l
+1dles.
+dle1s1c
+1dley
+dlic1k
+1dlie
+dlili1
+dl1l
+1dlm
+dlob1
+dlos1
+1dls
+dlungs1
+1dläc
+1dmac
+1dmad1
+dmag1
+1dmai
+dmang1
+1dmann
+dmee1
+dmeta1
+dmi1r
+1dmis
+dmi1t.
+dmont1
+1dmun
+1dmut
+1dmäu
+1d1mün
+1dnas
+dn2a
+dne1st
+dn1es
+1dnie
+dnt1
+1do.
+dobb1
+dob1era
+d1obe
+dodeg1
+d1ode
+doeb1
+doe1m
+d1oe1s
+1dof
+1dog
+1d1oi
+doi1n1el
+1dok
+dokt1
+1dol
+d1olb1
+dole1m
+d1ole
+1dom
+domai1
+do1ma
+domi1t.
+do1mi
+d2omit
+1don
+dong1
+doni1er
+don1i
+do1ra2p
+do1rev
+1dorf
+dorgi1
+do1rhe
+dorni1e
+do1rä
+1dos
+dos1o
+1dot
+dou1n1g
+1dous
+1dow
+1dpac
+d2p
+1dp1oi1
+dprämi1
+1dpuf
+1dqui
+1dqv
+1dra.
+1drab
+1drag
+1drai1
+1dral
+dra1lin
+dra1ll
+1drar
+dreb1
+1dreh
+dreli1e
+1drem
+dre1mm
+dre1sc
+dre1ss
+dre2sson
+dre1st
+dre1u.
+dre1us
+dreßg1
+1drick
+dri1el
+dri1en1
+dri1eser
+1drig
+1drit
+1drom
+drowi1
+1dru
+drun1d
+drung1
+1dry
+dränd1
+1drö
+1drüd1
+1ds'
+dsa1mm
+dsa1mt
+ds1ari1
+dsaus1
+1dsbr
+dschee1
+ds1chend
+dschen1
+1dschin
+ds1chine
+dseb1
+dsee1i
+dseg1
+dseh1
+ds1ei
+dsen1
+dseri1
+1dset.
+1dsets
+1dsfö
+dshof1
+1dshö
+ds1ieg1
+dski1e
+dslan1g.
+dsob1
+ds1ol
+1ds1om
+ds1on
+ds1ou1
+1dsprin
+ds2p
+1dspü
+ds1s
+dsseg1
+1dssk
+dss1o
+ds1tabe
+1d1stad
+ds1tag.
+ds1tag1en
+ds1tas
+ds1ta1ta
+ds1tauf
+ds1t1ea
+d2s1t1eil1
+dst1ei
+ds1term
+dst1er
+ds1terr
+ds1t1eur
+dst1eu
+ds1tex
+ds1th
+ds1tin
+ds1tis
+ds1tod
+ds1t1oi
+ds1tor.
+ds1tor2p
+ds1tou1
+ds1trau
+dst2r
+ds1tru2p
+1dström.
+d1st1röm
+1dströms
+ds1trü
+ds1turb
+ds1tus
+ds1täti
+dstät1
+dsun1g
+1dsu2p
+1dsvi
+1dswu
+1dswü
+1dszä
+1dsäc
+dsäng1
+1dt.
+dta1ll
+dtam1
+1dtan
+dt1ee1
+dt1eh
+dt1ei
+dt1ele
+dt2en2a
+dt1en1
+dt1er.
+dt1erb
+dt1erg
+dt1eri
+dt1erm
+dt1ern
+dt1err
+dt1ers
+dt1ert
+dt1eru
+dt1erw
+dt1eu
+dtev1
+dtez1
+1dtha
+1dtis
+dtit1
+1dtl
+dtleg1
+dtm1a
+dtob1
+1dtou
+dtrai1
+dt2r
+1dtre
+1dtru
+1dts
+dt1s1o
+dtt1e
+1dtur
+1dtv
+dtv1e
+1dtw
+1dtän
+1dtör
+1dtür
+1dtüt
+1du.
+1dub1
+due1se
+due1si
+1dug
+duilli1
+1duk
+1dul
+dulg1
+1du2m.
+du1m
+1duma
+1dumb
+1dumc
+1dume
+1dumg
+1dumh
+1dumk
+1duml
+1dumm
+1dumt
+1dumv1
+1dumw
+dun1gu
+1dunk
+du1noc
+dun2o
+1durc
+durv1
+1dus
+dus1sc
+dus1st
+dus1tal
+1dut
+1duy
+1duz
+1dva
+dva1l
+dvat1
+1dvei
+dv1era
+dv1erb
+dv1erd
+dv1ere
+dv1erf
+dv1erg
+dv1erha
+dv1erj
+dv1erk
+dv1erl
+dv1erm
+dv1ern
+dv1ero
+dv1er2p
+dv1err
+dv1ers
+dv1ert
+dv1eru
+dv1erw
+dv1erz
+dv1erä
+1dvis
+dvorg1
+1dw1al
+dw1ar
+dwa1r.
+dw1at1
+1dweg1
+1dwic
+1dwit
+1dwr
+1dwäh
+dys1sen1
+dys1so
+dy1s1tok
+dyt1
+dze1st
+dz2e
+dz1ugi
+dz1uk
+1dzul
+1dzu1m
+dz1un1g
+1dzu2p
+1dá
+däg1
+1däh
+1däm
+1där
+dä1us
+1dé
+1dí
+1dö.
+1döb1
+1död1
+döl1l.
+dörg1
+dös1che
+1döv1
+düb1eri
+dügg1
+1dün
+1dž
+eab1
+1ea1ch.
+1ea1cha
+1ea1chb
+1ea1chc
+1ea1che
+1ea1chf
+1ea1chl
+1ea1ch2p
+1ea1chr
+1ea1chv
+1ea1chw
+1ea1chy
+1eaco
+1ead.
+1eadb
+1eads
+1eagl
+1eak.
+eakb1
+1eakh
+1eaks
+1eal.
+ea1l'
+ea1lba
+ea1lbr
+1eale
+e1a1led2
+e1a1lend
+ealen1
+ea1leri
+ea1lerk
+ea1lerm
+ea1lern
+ea1lers
+ea1ley
+ea1lfac
+ea1lg.
+eali1e
+eal1la
+eal1lo
+ea1llt
+ea1lmä
+1eals
+e1a1ly
+1eami
+1eams
+1ean.
+ea1nat
+ean2a
+eand1e
+1eane
+ea1ney
+ea1nhe
+1eani
+eani1er
+ea1nnek
+ea1nnie
+ean1ni
+ea1n1ny
+ea1nors
+ean2o
+1ean2p
+ea1npo
+ea1nro
+1eans.
+ea1nsb
+ea1nsd
+ea1nsf
+ea1nsg
+ea1nsh
+ea1nsj
+ea1nsk
+ea1nsl
+ea1nsm
+ea1nsn
+ea1nso
+ea1nsr
+ea1ns1s
+ea1nsw
+1ea1n1to
+ea1nut
+ean2u
+ea1ny
+ean1z1u
+1ear.
+ea1r'
+1earab
+ea1rank
+ea1r1by
+e1arb
+ea1rce
+e1arc
+ea1rcy
+1e1ard
+ea1rd.
+ea1rd'
+ea1rd1e
+ea1r1do
+ea1r1dr
+ea1rds
+ea1rdy
+ea1red
+eare1sc
+e1ares
+1e1a1rh
+1e1ari
+ea1rie
+e1a1rj
+1e1ark
+e1a1rl
+earli1e
+1earma
+e1arm
+1e1arn
+ea1rn.
+ea1rnag
+earn2a
+ea1rne
+ea1rni
+ea1rns
+ea1rny
+1e1ar2p
+ea1rpi
+e1a1rs.
+ea1rs'
+e1a1rsa
+ea1rs1o
+e1a1rt'
+e1a1rta
+e1a1rtb
+ea1rtl
+e1a1rtm
+1ea1rto
+ea1rts
+1e1arw
+ea1rwo
+1e1a1ry
+eas1e1i
+easi1e
+1easl
+eas1s1o
+eas1s2p
+eas1st
+1ea1tb
+1eat2e.
+eat1el
+1eaten.
+eat1en1
+1ea1tf
+1ea1tg1
+1ea1th
+1eatie
+1eatin
+1eatmus
+1ea1tn
+1eaton
+ea1to
+1eat2p
+1eau.
+1eau'
+1eaua
+1eaub
+1eauc
+1eaud
+1eaufi
+1eaufo
+1eau1fret
+1eau1fö
+1eauj
+1eauk
+1eaul
+1eau1m
+1eau2n
+1eau2p
+1eaur
+1eaus.
+1eausa
+1eausc
+1eauso
+1eauti
+1eauty
+1eauté
+1eauv
+1eauw
+1eav
+eavo1
+eaz1
+e1ba
+ebab1
+eband1
+1ebbt
+e1bc
+e1bd
+eb1eamt.
+e1bea
+e1bebr
+e1bebu
+e1bec
+e1befe
+e1beg
+eb1egg
+e1behe
+e1bei
+eb1eic
+eb1eint
+e1bek
+eb1elit
+eb1elü
+eb1en1en1
+eb1enü
+e1be2p
+eb1er.
+eb1erab
+eb1erar
+eb1erb
+e1berbl
+eb1erd
+eb1ere.
+e1berec
+eb1ereh
+eb1erem
+eb1eren
+eb1erer
+eb1erf
+eb1erg
+eb1erh
+eberher1
+eb1erin
+eb1eris
+eb1erj
+eb1erk
+eb1erl
+eb1erm
+eb1ern
+eb1er2p
+eb1erq
+eb1err
+eb1ers
+eb1ert
+eb1erv
+eb1erw
+eb1erz
+e1berä
+eb1esan
+eb1esau1
+eb1eseh
+eb1esel
+eb1esen
+eb1eser
+e1b1esh
+eb1esin
+eb1esl
+eb1espe
+e1bes2p
+eb1estem
+eb1estes
+eb1estra
+ebest2r
+eb1estro
+eb1esun1
+eb1esw
+eb1esz
+e1betu
+e1bf
+e1bil
+ebint1
+e1bi1s
+e1bit
+e1bka
+e1bko
+e1bkr
+e1bla
+ebla1s
+e1ble
+ebleich1
+e1blu
+e1bm
+e1bo
+eb1oa1
+eboe1
+eb1oi1
+eborg1
+e1b2p
+e1bra
+ebrequi1
+e1bri
+e1bro
+e1brü1
+e1bs.
+e1bsa
+ebsa1g
+e1bsc
+e1bse
+ebs1tanz
+ebs1t1ea
+ebs1t1em2p
+ebs1tend
+ebst1en1
+ebs1th
+ebs1tie
+ebs1t1o2p
+ebs1tra
+ebst2r
+ebungs1
+e1burg1
+ebwi1
+e1bzu
+ebänd1
+e1bä
+e1bü
+1ec'
+1echel
+echi1en1
+1echnica
+echn2ic
+1echnici
+1echnico
+1echnicu
+1echnif
+1echnion
+1echniu
+1echniz
+1echnob1
+echn2o
+1echnoc
+1echnod
+1echnog
+1echnok
+1echnom
+1echnon
+1echn1o2p
+1echnor
+1echnos
+1echnot
+1echnov
+1echné
+1echo.
+echs1tau
+1ech1ti.
+echtrich1
+echt2r
+ech1tsen.
+echtsen1
+ech1tshof
+echz1u
+1ecia
+1ecin
+1eckn
+1eckr
+ecks1tag
+1eckt
+1ecn
+ecre1s
+ecue1s
+1ecul
+1ecu1m
+1ecz
+1ecú
+e1d.
+e1da
+e1db
+e1dd
+edea1l
+e1ded
+ede1lad
+ede1llo
+e1dell
+ede1mar
+ed1ema
+ede1mas
+ed1eme
+e1d1e1mi
+edens1tau
+edens1t1em2p
+ede1rech
+ederschaf1
+ede1sel
+ede1st2r
+1edetek
+edev1e
+e1di
+edi1enl
+e1dien1
+edlec1
+edm1
+1edmo
+e1dn
+e1do
+1ed1o1n2o
+e1don
+edossi1
+e1dos
+e1dr
+edritt1
+e1drit
+1edron
+edrun1
+e1dru
+e1ds
+edsa1g
+eds1cho
+eds1tag
+eds1tan
+eds1t1ee
+eds1tri
+edst2r
+eds1tru
+eds1trä
+edt1er
+edun1d
+edung1
+edv1e
+e1dwa
+e1dwen
+edä1
+edös1c
+1ee.
+1ee'
+1eea
+ee1b1ee
+eeb1en
+eece1
+1eech
+1eecks
+1eeckx
+1eed
+1eee
+eeeb1
+1e1eee1
+1eef.
+1eefa
+1eefb
+1eefe
+1eefh
+1eefs
+1eeft1
+1eefy
+1eege
+1ee1ha
+eehaus1
+1ee1hi
+1ee1ho
+ee1hu
+eehunt1
+1ee1hä
+1ee1hö
+ee1hü
+e1e1ig.
+ee1igs
+e1e1ii1
+ee1i1n.
+eeis1s
+1eej
+1eek.
+1ee1l.
+ee1l'
+1ee1la
+ee1lb
+ee1lc
+ee1ld
+ee1le.
+ee1leg
+ee2lek
+1ee1ler
+ee1les
+e1e1ley
+ee1lg
+1ee1lh
+ee1li.
+ee1lic
+ee1lie
+ee1lis
+ee1ll
+ee1lm
+1ee1lo
+ee1lr
+ee1ls
+ee1lta
+ee1lu
+ee1lw
+1ee1ly
+1ee1lz
+ee1lä
+1ee1lö
+e1e1m.
+ee1ma
+ee1mdg
+e1emd
+ee1me
+1eemi
+ee1mil
+ee1min
+ee1mit
+ee1ml
+1ee1mo
+1ee1ms
+ee1mt
+ee1mu
+1ee1mä
+ee1mü
+een1
+ee1n'
+1een2a
+e1e1na.
+ee1nag
+ee1nah
+ee1na2p
+e1e1nav
+2eend
+ee1neb
+ee1n1el
+ee1neri
+een1er
+ee1ney
+1eenh
+1eeni2
+ee1nie
+ee1nig
+1eenl
+ee1noc
+een2o
+ee1not
+e1e1nsh
+e1e1ny
+ee1näc
+1eeo
+eeob1
+1ee2p
+1eer.
+1ee1r'
+1eera
+e1e1ra.
+ee1rab
+ee1rad
+eera1ll
+ee1ran
+ee1ras
+ee1rat
+ee1rau
+1ee1rba
+ee1rbl
+ee1rbo
+ee1r1bä
+ee1rbü
+1ee1rc
+1ee1rd.
+eerde1s
+ee1r1do
+1ee1r1dr
+ee1rdu
+1ee1re
+ee1rfe
+ee1rfr
+ee1rfu
+ee1rfö
+ee1rga
+ee1rgr
+ee1rgu
+ee1rho
+ee1rhä
+ee1rhü
+1eeri
+ee1ri.
+ee1rie
+ee1rif
+ee1rig
+e1e1rio
+ee1rit
+e1e1riw
+ee1rj
+1e1e1rk.
+ee1rka
+ee1rki
+1ee1rko
+ee1rku
+ee1rkü
+1ee1rli
+eerm1
+ee1rma
+ee1rmu
+ee1rns
+ee1rob
+ee1roc
+ee1rom
+ee1ros
+ee1rou
+1eer2p
+ee1rpe
+ee1rpf
+ee1rpi
+ee1rpu
+ee1rq
+ee1r1ra
+ee1rri
+ee1r1ro
+ee1rs'
+eersa1m
+eerschaf1
+ee1rse
+ee1rsh
+ee1rsi
+ee1rsm
+ee1rso
+ee1rt.
+ee1rta
+ee1rte
+ee1rth
+1ee1rto
+ee1rtz
+ee1rtö
+1eeru
+ee1ruc
+ee1ru1m
+ee1run
+eerun1d
+ee1rut
+1ee1rv
+eerv1e
+ee1rwo
+ee1rwu
+ee1rwä
+1ee1ry
+ee1rzu
+ee1rä
+eeränd1
+ee1röl
+ee1rü
+1ee1s.
+ee1s'
+ee1sa
+eesa1m
+ee1sb
+1ee1sc
+1eese
+ee1see
+ee1sen
+ee1sg
+ee1sh
+eeshau2p1
+1ee1si
+e1esi1e.
+ee1sj
+1ee1sl
+ee1sm
+1ee1s1o
+1ee1s2p
+ee1ss
+ee1s1sid
+1ee1st
+ee1su
+ee1sw
+ee1sz
+ee1sä
+1eet.
+eetal1
+1eetb
+1eete
+1eetf
+1eetk
+1eetl
+1eeto
+1eet2p
+1eet2r
+1eets
+1eetu
+1eetü
+1eeu
+ee1u.
+ee1uf
+ee1u1m
+ee1un
+ee1ur
+ee1ut
+e1e1uw
+1eev
+1eew
+eewei1s
+1eez
+1eeü
+efall1
+e1fal
+efa1lli
+efang1
+efaus1
+1efdar
+efeb1
+efehls1
+e1feh
+efen1
+efe1so
+1efeu.
+e1feu
+1ef1fi
+1e1ffö
+efib1
+efoli1
+efos1c
+1efpf
+ef2p
+1efpl
+2efr
+1efsaa
+1efta2p
+eft1eh
+eft1el
+2efu
+efun1d
+efzug1
+efäng1
+1efé
+e1ga.
+ega1c
+egai1
+ega1lan
+egal1la
+ega1los
+eg1a1lus
+e1gam
+egang1
+ega1nor
+egan2o
+ega1raf
+ega1ras
+egb1eam
+eg1bea
+e1gb1erg
+eg1elab1
+eg1eler
+e1geli
+eg1elu
+ege1ma
+eg1enab
+egen2a
+eg2enac
+e1g1enad
+e1geners
+egen1er
+egenfall1
+egen1fal
+eg2enä
+eg1erag
+eg1eram
+eg1eran
+eg1eraus
+e1g1erd
+eg1eren
+eg1eres
+eg1eret
+e1geri
+eg1erinn
+e1g1erm
+e1g1ern
+e1g1er2p
+eg1eruh
+eg1eru1m
+eg1erun
+eg1esk
+eg1esl
+eg1esm
+eg1esn
+eg1es1or
+eg1espar
+eges2p
+eg1espl
+eg1esw
+ege1u
+e1gewes1
+eg1ex
+1e1gg.
+e1gge.
+e1gg1en.
+egg1esi
+e1ggis
+e1ggli.
+1eggs
+e1gh.
+e1ghau2p1
+1e1gia
+e1gic
+egi1en1
+egje1
+e2glü
+e1gn1er
+egni1er
+egon1i1
+1egoz
+egra1tti1
+egs1tak
+egs1tal
+egs1term
+egst1er
+egs1th
+egs1tro
+egst2r
+egs1trä
+egs1tur
+egungs1
+egv2erh
+egv1e
+e1gwart
+egw1ar
+e1h.
+1ehab1end
+ehab1en
+e1haf
+e1hah
+1ehai
+e1ha1ll
+e1ham.
+e1hamw
+1ehan.
+e1hand1
+1ehanz
+eha1ts
+e1hav1
+e1head
+e1hed2
+e1heft
+e1he1h
+e1heim1
+ehei1t
+ehe1la
+e1helf
+ehe1ll
+e1helm
+ehe1lo
+ehe1ma
+e1he1mm
+1ehemo
+ehe1mor
+1ehen'
+ehen1
+ehe1nam
+ehen2a
+1ehenc
+2ehenkt
+1ehenm
+1ehen1n2a
+1ehe2p
+ehe1rec
+ehe1res
+ehe1ric
+eh1e1ro
+e1herz2e
+ehe1se
+ehe1s2p
+e1heu
+ehe1un
+1ehic
+e1hie
+ehi1er
+ehint1
+e1hi2p
+e1hirt
+e1his
+e1hit
+1ehj
+e1hoc
+e1hoe1
+e1hof
+e1hol
+1eholms
+eh1olm
+e1hot1
+e1how
+1ehq
+eh1ran
+eh1renw
+eh1rling1en
+ehrschaf1
+eh1rsh
+eh1rö
+e1hudel
+ehun1d
+1ehunf
+1ehuni
+e1hur
+e1hus
+e1huz1
+e1hym
+e1häl
+e1häm
+e1hän
+ehäs1c
+e1höl
+ehös1
+1ehöö
+1ehübu
+e1hüh
+e1hün
+e1hür
+e1hüt
+eia1l
+eiaus1
+eich1tet
+ei1d1e1mi
+1eiderb
+eid1e1ros
+1eidg
+1eidl
+1eidou
+1eidsc
+eieb1
+1eiel
+1eier
+1eifu1ssa
+1eifussd
+1eifusse
+1eifussger
+1eifussh
+1eifussk
+1eifuss1s
+1eifusst
+1eifußa
+1eifußd
+1eifuße
+1eifußg
+1eifußh
+1eifußk
+1eifußs
+1eifußt
+1eig.
+1eigb
+1eige.
+1eigebrau2n
+eige1bra
+1eigefar
+1eigegel
+1eigegr
+1eig1el.
+1eig1el'
+1eig1eln
+1eig1els
+2eig1elt
+eigelun1
+1eig1em.
+1eigen.
+eig1en
+1eig1er.
+1eig1es.
+1eiges1ei
+ei1gese
+1eigeto
+1ei1getö
+1eigh
+1eign
+1e2igt
+1eihai
+1eii
+e1iii1
+1eije
+1eiji
+1eike.
+1eil.
+1eilar
+1eilb
+1eilc
+1eile.
+1eilen.
+eilen1
+1eiles.
+1eilf
+1eilh
+1eilk
+1eill
+eil1la1s
+ei1lla
+ei1lle1m
+ei1l1lin
+eil1los
+ei1llo
+1eils
+1eilt
+1eimer
+2eimm
+eim1ma
+1einac
+ein2a
+1einad
+ei1nag
+eina1li
+1einam2p
+1einans
+1einc
+einde1ra
+ein1de
+1eineb
+1einek
+1eine1mü
+ein1em
+eine1ras
+ein1er
+1einest
+ein1es
+1eineta
+ein1et
+1eineu
+1einfl
+2eing.
+1einga
+1eingr
+e1ings
+1einhaa1
+1einhac
+1einhalf
+1einhalt1er
+1einhaltu
+1einhar
+einha1t
+1einhau
+1einho
+1einhä
+1einj
+1einka
+1einn
+1ein2o
+1ein2u
+ei1nul
+1einwi
+1einö
+1einü
+eiob1
+eipi1e
+ei2p
+1eir.
+1eira.
+ei1ra
+1eirak
+1eirav
+1eird
+1ei1rl
+1eirs1
+ei1sam
+ei1sber
+ei1sbr
+ei1sc
+1ei1schel
+eise1ma
+ei1serf
+eiseri1e
+ei1ski
+eislan1
+eisle1b
+ei1spi
+eis2p
+ei1ss.
+ei1ss'
+ei1ssac
+ei1ssat
+ei1ssb
+ei1sse
+ei1s1sek
+ei1ssh
+eis1sil
+ei1sska
+ei1ssl
+ei1ssn
+eis1soz
+ei1sso
+ei1sspa
+eiss2p
+ei1sspe
+ei1sspi
+ei1sspo
+ei1sspr
+ei1ss1s
+ei1ss1t.
+ei1sst'
+ei1ssta
+ei1sstem
+ei1sst2r
+ei1sstu
+ei1sstä
+ei1sstö
+ei1ssz
+ei1ssü
+eis1tabe
+eis1tag
+eis1tanz
+ei1stan
+1ei1st1er
+eis1t1o2p
+eis1tor
+eis1tou1
+ei1st2r
+ei1stu
+eis1tur
+ei1sä
+ei1tbü
+eitd2
+1ei1tee
+eit1ehe
+ei1teh
+eit1ei
+eit1e1ss
+ei1tru
+eit2r
+ei1twä
+ei1tz.
+ei1tzm
+eitz1ug
+1eiv
+1eiz.
+1eize.
+eiz2e
+1ei1zeic
+1eizen1
+1eizer.
+1eizj
+1eizl
+1eizm
+1eizt
+1eiz1ung
+1eizv
+1eizz
+1eiß
+eißv1e
+1eiä
+1eiö
+1eiü
+ejea1
+ejeb1
+1ejk
+1ej2p
+eka1n2u
+ekb1
+ekeb1
+eke1st
+ekha1t
+ekla1s
+ekle1b
+eklun1
+eklän1
+ekma1l1
+ekrai1
+ekre1me
+ekrich1
+ekt1er
+ektv1e
+1ekz
+ekzi1
+1ela.
+1ela'
+1elaa
+elab1
+1ela1bd
+e1la1bel
+1elabg
+1elabn
+1ela1bw
+e1la1by
+1ela1bz
+e1lac.
+elae1r
+elag1er
+elags1
+1elai1
+elais1
+1elaj
+1elalg
+1elalk
+1elan.
+1elane
+1elanh
+1elan2o
+1elan2p
+1elanä
+1elao
+1elap.
+ela2p
+1elaps
+el1ari1
+ela1roc
+el1aro
+el1a1ru
+1elas.
+1elas'
+1elasco
+1ela1ta
+1elati
+1ela1to
+1ela1t2r
+1elau.
+e1laub
+e1laune
+elau2n
+1elausr
+el1bee1
+1elboc
+elbrech1
+1elbro
+1el1bö
+1elce
+elci1
+1elcr
+1eldac
+eldui1
+1eldäc
+elea1nor.
+elean2o
+eleb1e
+1el1ee.
+1el1eea
+1eleeb
+1el1eed
+1el1eee
+1eleef
+1eleeg
+1eleeh
+1eleek
+1eleem
+elee1n.
+eleen1
+1el1eeo
+1elee1s
+1eleet
+1el1eev
+1el1eez
+1elegr
+e1legs
+e1legu
+2eleh
+ele1her
+e1lehr
+1elei.
+1eleien1
+e1leist
+ele1la
+ele1lin
+ele1ma
+ele1met
+1elemn
+e1lems
+ele1mu
+1eleph
+ele2p
+e1lerc
+e1lerne
+1elernä
+e1lesb
+ele1sch
+ele1si
+1elesk
+ele1sl
+ele1spo
+eles2p
+ele1ss
+ele1st
+eleti1
+e1leuch
+el1euc
+ele1un
+1eley
+1elf.
+1elfes
+1elfet
+1elfis
+1elfle
+el1fsb1
+1elft
+1elgh
+1elgur
+1elgü
+1elhaa1
+1elhef
+1elhem
+1elherz
+elhof1
+elhol1
+1elhor
+1elhör
+1elia
+elib1
+1elica
+1elick
+1elico
+1elicu
+1elicz
+1elida
+1elidi
+2eli1ec
+e1lied
+el1i1edl
+eli1efd
+eli1eff
+1eli1en1
+1elier
+eli1erb
+eli1erd
+eli1erf
+eli1ern
+eli1er2p
+eli1err
+eli1erv
+e1lies1c
+eli1ez
+1elifi
+eli1gar
+1elii
+1elij
+1elika
+1eliki
+1elil
+elili1
+1elimo
+e1limou
+1elin2a
+1elin1gm
+1elin2o
+1elinsk
+1elio
+1eliq
+1elis.
+1elisa
+1elisc
+1elisi
+1elisk
+elissi1
+1elisw
+1elito
+1elitä
+1eliu
+1eliv
+1elix
+elizi1
+eliz1
+1eliè
+1eljo
+1eljär
+1elknä
+1elkoc
+el1ko
+e1lla1bf
+e1llabs
+1el1ladu
+e1llaf
+1ellai1
+e1llal
+e1llan2a
+e1llanz
+e1ll1arb
+e1llars
+1ellaw1
+e1llbi
+e1llbla
+1elled2
+ellee1
+e1llersche
+elle1st
+e2lleu
+e1llev
+e1llfar
+e1llfas
+e1llfol
+e1llge1m
+e1llhaf
+1ellic
+1ellied
+e1llier
+e1lli1er.
+e1llinh
+e1llj
+e1llkre
+e1llmal
+e1llmau
+e1lln2o
+e1llon
+1elloo1
+e1ll1o2p
+e1llov
+e1llq
+e1llru
+e1ll1so
+e1llsti
+ell1st
+e1llto
+e1lltu
+e1lltö
+e1lltü
+1elluf
+1ellumm
+ellu1m
+2ellv
+ellv1e
+e1llwäs
+e1llza
+1el1läc
+e1llä2p
+1ellät
+1ellö
+1elm.
+1elmark.
+elm1ark
+1elmast
+1el1mey
+elmunt1
+1elmäh
+1elmü
+1elnas
+eln2a
+1elnb
+elng1
+1elnh
+1elnk
+1eln2u
+1elnü
+1elo.
+1elofe
+1eloga
+e1l1ogo
+1eloh.
+1el1oi
+1elol
+1elom
+1elon.
+1elon2a
+1elons
+1el1ony
+e1loo1
+1elorn
+1elo1ru
+1elos1o
+e1loti
+1elott
+1el1ou2p
+1elpad
+el2p
+1elpfl
+1elpi
+1elpon
+elporti1
+1elps
+1elpul
+1elrö
+elsa1m
+el1sa
+1els1oc
+1els1os
+1el1s1oß
+els1tafe
+el1st
+els1tag
+els1terr
+elst1er
+els1tit
+els1topf
+elst1o2p
+els1tore
+elt1eb
+elt1ei
+elt1ek
+elt1eli
+elt1e1sc
+1elty
+1eltä
+1elu.
+1elug2p
+1eluk.
+elu1m1
+1elun1d
+e1lundb
+1elunf
+elungs1
+1elunw
+1elus.
+1eluse
+1elusg
+1elush
+1elusi
+1elusl
+e1lust
+1elute
+elwei1s.
+1elwil
+1elwun1
+1elwy
+1elwä
+1ely.
+1elya
+1elys
+1elyt
+elz1uge
+elz1u2p
+1elzö
+1elá
+1elähn
+e1läm
+e1läng
+e1lä2p
+1elè
+1elé
+1elí
+e1löc
+1elöfe
+e1lø
+e1lüc
+e1lüs
+1em.
+emaa1
+1emae
+emai1
+e1mais
+em1a1ll
+em1alu
+e1mange
+e1mann
+1emar.
+e1marci1
+em1arc
+1em1arl
+1em1ars.
+1emas.
+e1mass
+e1mate
+e1mats
+e1matt
+e1matu
+1emay
+1embl
+1emd
+e1mee1
+1emek
+eme1la
+e1meld
+1emell
+eme1n1es
+emen1
+1emenv
+1em1eri
+eme1rie
+1emes.
+eme1sc
+eme1s1or
+eme1s2p
+eme1st
+1emeti
+e1meut
+1emfl
+emg1en
+1emi.
+1emia
+1emid
+emi1er.
+emi1er'
+emi1erl
+emi1erm
+emi1ers
+emili1
+e1mimi
+1emin2a
+1emine
+emi1neg
+1emio
+1emis.
+1emisi
+1emisto
+1emiw
+1emiz1
+1emię
+1emja
+1emli.
+1emlif
+1emlis
+e1mm.
+e1mm'
+e1mma.
+e1mmar
+e1mme.
+e1mmei
+e1mmer
+e1mmg
+e1mml
+e1mmn
+e1mms
+e1mmt
+e1mmun
+1emni1
+1emo.
+1em1oa
+e1m1od1e
+e1m1odu
+e1moe1
+1emof
+1em1oi
+1em1oj
+1emoka
+1emokra1ty
+1emokratá
+1emokri
+1emon.
+emo1rei
+e1mott
+emou1
+1emov
+e1m1oy
+1emoz
+1em2p
+empic1
+1emr
+1emsk
+1ems2p
+emsv1e
+e1musc
+e1muse
+e1musi
+e1must
+1emv
+1emy
+emz1ug
+e1mäh
+emäng1
+e1mär
+e1mäs
+1emé
+1en'a
+1ena.
+en2a
+1enabb
+1ena1bd
+1enabg
+1ena1bk
+1enabn
+1ena1bw
+1enace
+e1nachr
+1enack
+1enacq
+1enacv
+2enade
+1enadl
+1ena1dry
+1enae
+1enaf
+enag1er
+1enagl
+e1nahm
+1enaho
+1enai
+1enakn
+1enakr
+1enalg
+1enall
+2ename.
+2e1namen1
+1en2an2a
+1enanb
+1enand1
+1enanga
+1enangs
+1enan2o
+1enan1t.
+1enante
+enan1ti1
+2enapol
+ena2p
+1enar.
+1en1ard
+1enare
+1en1ari1
+1en1aro
+1enars
+1en1arz
+1enass
+1enat.
+1ena1ta
+1enate
+1ena1t2r
+1enau'
+1enaufs
+1enausf
+1enaus2p
+1enaut
+1enav
+1enax
+1enay
+1enaz1
+1enb.
+1en1bea
+1enbeo
+1enca
+1ence
+1enci
+enci1er
+1encl
+1encr
+1ency
+1endas
+1endc
+ende1lan
+end1e1ras
+ende1ss
+ende1st
+1endh
+1en1di.
+1endor
+1endsh
+1endst
+1endt
+endv1e
+1endz
+1en1där
+1endü
+1ene'
+enebi1
+e1nece
+1enech
+1ened2
+1enee
+enee1n1
+1enefi
+1eneg
+2e1nehm
+en2eh
+1enei.
+en1ei
+1eneic
+eneig1e
+2e1neigu
+1eneiw
+enela1
+en1el
+e1nelk
+1ene1ll
+ene1lu
+1enemb
+en1em
+ene1mor
+1eneo
+1enera
+en1er
+ene1rau
+1enerel
+1enerfa
+e1nerve
+1enerá
+1enerä
+1enerö
+1enesee
+en1es
+1enesi
+1enes2p
+e1ne1ss.
+ene1st
+1enest2r
+1enete
+en1et
+1eneth
+1eneti
+1enet2r
+1enets
+1enett
+2e1netz
+ene1us
+1enev
+1enew
+enewe1
+1enexe
+en1ex
+1enez
+enezi1
+e1neß
+1eneü
+1eneš
+1enf.
+1en1fam
+1enfec
+1enfer
+1enfes
+1enfet
+1enfis
+1en1fon
+1enfos
+1enfs
+enfun1
+1enfuz1
+1enfö
+1engar
+1engb
+engelun1
+en1gel
+eng1erun
+1engh
+engha1s
+1engt
+1en1gy
+1en1gü
+enha1b1er
+1enhil
+1eni.
+1enia
+1enici
+en2ic
+1enido
+1enieb
+1eni2ee
+1enief
+1en1ieg
+1eniek
+1eniem
+1eni1en1
+1enieo
+1enier
+eni1era
+eni1erg
+eni1erk
+eni1ern
+eni1erv
+1enie1st2r
+enie1st
+1eniesu
+1eniet2r
+1eni1eu
+1eniew
+1eniez
+1enii
+1enik
+1enil
+enimi1
+1enin.
+1enin2a
+1eninc
+1enine
+1ening
+1eninn
+1enio
+1eni1s.
+eni1sc
+1enista
+e1nit2r
+1eniu
+e1niv
+1eniy
+1eniz
+1eniö
+1enje
+1enji
+1enjy
+1enjä
+1enk.
+enklan1
+en1kla
+1enkol
+1enkoo
+1enlit
+1enloh
+1enly
+1enmag1
+1enma2p
+1enmy
+en1ne
+1enne.
+1enn1es
+enne1st
+1ennn
+ennv1e
+1ennw
+1en1ny
+1ennà
+1eno.
+en2o
+1en1oa
+enob1
+1en1obj
+enoe1
+1enog
+1enoh
+1en1oi
+1enol
+1enom.
+1eno1ma
+1eno1me
+1enomf
+1eno1mi
+1enom1mu
+1enom2p
+1enoms
+1enomt
+1enon
+enoo1
+1enope
+en1o2p
+1enopf
+1enopt
+1enora
+1enorc
+2enorm1
+2enoss
+1enot.
+2enoti
+1enoty
+1enou
+1enov
+1enow
+1enoz
+1enoî
+1enoï
+1enps
+en2p
+1enpy
+1enpá
+1enpär
+1enpü
+1enrab
+1ens'
+1ensaf
+ensa1m
+1ensd
+1ensee
+enseg1
+1ensek
+1ensem
+1ensf
+1ensg
+1ensh
+ensi1e.
+1ensk
+1ensl
+1ensm
+1ensn
+1ensolc
+1ensq
+1ensr
+1ens1s
+ens1tate
+ens1test
+1en1stif
+ens1ti2p2p
+ensti2p
+ens1trai1
+enst2r
+ens1trös
+1ensv
+1ensw
+1ensy
+1ensü
+en1t'
+1en1tab
+en1ta1c
+1entb
+1entc
+en1tche
+en1te.
+1en1tea
+1en1tec
+en1t1ee
+en1tel
+ent1ele
+ent1eli
+en1t1en1
+en1te2p
+ent1er
+en1ter.
+en1tera
+en1terbei
+en1terbr
+en1terd
+en1tere
+en1terh
+en1teri
+en1terk
+en1term
+en1tern
+en1ter2p
+en1terr
+en1ters
+en1tert
+en1teru
+en1terv
+en1tes
+ent1e1ss
+ent1est2r
+ente1st
+1entf
+1entg
+enti1en1
+en1ti
+entin1i1
+entins1
+2entj
+1entk
+1entm
+1entn
+1ents
+en1ts.
+1entt
+1entu1m
+en1tu
+1en1ty
+1entz
+1en1tô
+1en1tō
+1enua
+en2u
+1enue
+1enui
+1enumk
+enu1m
+2enumm
+1enumr
+1enumw
+1enun2o
+2enuo
+1enus.
+1enuta
+2e1nutz
+1enuz1
+1envö
+enweb1
+enwe1gg
+1enwh
+1enx
+1eny
+1enz'
+1enzb
+1enzg
+1enzh
+1enzk
+1enzm
+1enz2p
+1enzr
+1enzs
+1enzt
+1enzv
+1enzy
+1enzz
+1enzé
+1enähn
+1enänd
+1enär
+e1nä1rr
+1enät
+1enäu
+1enç
+1enè
+1enê
+1ení
+1enöd1
+1enöf
+1enölh
+1enč
+1en┊
+eob1er
+e1obe
+eoni1s
+eon1i
+eo1n1ni1
+eo1rec
+eo1reg
+eo1rek
+eo1rel
+eo1re2p
+eorgs1
+eo1run
+eoseri1
+eos1s1o
+epagni1
+e2p
+epai1
+1epaj
+epb1
+epe1sc
+epe1ss
+epia1l
+1epid1
+epi1ed
+epi1ga
+epi1ge
+epi1n1es
+epit1
+ep1oi1
+eppe1ru
+ep2p
+eprech1
+eprämi1
+eps1ton
+epun1g1
+1epā
+1epł
+1er'sc
+1era.
+1erac.
+1erace
+1eraci
+1eracr
+1eracs
+1eract
+1eracw
+2erad.
+e1radar1
+1eradm
+1erae
+eragg1
+1eragi
+1er1ahn
+1eraht
+1erai
+erai1ne
+1erako
+erakt1er
+1erakü
+era1leu
+era1lic
+1eralle
+1era1mo
+1eramt
+1erando
+1erandy
+1erani
+erani1e
+1eran2o
+1eransk
+era1n2u
+1er1ard
+1erare
+1er1ari
+1er1aro
+era1rot
+1er1arr
+er1a1ru
+1eras.
+1erasi
+e1ra1tg
+e1ratsb
+e1ratsk
+e1ratsm
+e1rats2p
+e1rats1s
+e1ratsv
+2e1rauc
+1eraud
+2e1rau1m
+e1rausc
+1eraus2p
+eraus1t
+1erav
+1eraz
+1erb.
+1er1ba.
+1erbal.
+er1bal
+1erbald
+1erbale
+1erbalf
+1erbali
+1erbaln
+1erbal2p
+1erbalr
+1erbals
+1erbalt
+1erbani
+1erban2o
+1erb1ari
+1erbas.
+er1bas
+1erbati
+1erbd
+1erbergä
+erb1erg
+1erb1es.
+1erbf
+1erbg
+1er1bi.
+1erbig
+1er1bi1s.
+1erbk
+1erbm
+1erbo.
+1erbs
+1erbu2m.
+erbu1m
+1erbums
+1erbunt
+1erbw
+1er1by
+1erbz
+1erc.
+1ercel
+erche1l
+erche1re
+erci1er
+1ercol
+1ercom
+1ercos
+1ercou1
+1ercu
+1ercy
+1ercz
+1er1da.
+er1da
+1erdab
+1erdad.
+1erdade
+1er1dag
+1erdan2a
+1erdane
+er1dea
+er1deb
+1er1dee
+er1del
+erde1lei
+erde1lo
+erde1ra
+er1der
+1erderv
+erde1ur
+er1deu
+er1dev
+1er1di.
+er1di
+1erdicc
+er1di2en1
+1erdi1er
+1erdig1
+1er1dit
+1erdj
+1erdoli
+er1do
+er1dol
+1erdon2a
+er1don
+1erdone
+1erdroh
+er1dr
+1er1dug
+1erdun.
+1erduns.
+1erdura
+1erdure
+1erdy
+1erdò
+1erdüre
+er1dü
+e1read
+e1reak
+1erebr
+1ere1bü
+e1reche
+e1rechn
+2erecht
+erec1ki.
+e1reco
+1ere1d.
+1ere1di
+1ere1dr
+1erefi
+1er2efr
+1er2efu
+1erefä
+1erefö
+e1rega
+2eregi
+1eregr
+1erehi
+1ereho
+1ere1hu
+1erei.
+1ereia
+e1reibe.
+1ereien1
+1ereir
+1ereis.
+1er1eiv
+1ereiw
+1erej
+1ereka
+1erekh
+1ereki
+1erekn
+2e1reko
+1ereli
+ereli1e
+2e1relig
+ere1los
+ere1lot
+ere1mac
+ere1mal
+ere1men1
+ere1mete
+1eremi
+1ere1mä
+1eremì
+1eremö
+1ere1mü
+ere1n1ei
+1eren1th.
+eren1t
+1er1entz
+1ereo
+1erepe
+ere2p
+1erepl
+1erepr
+ere1ret
+1eresa
+ere1sek
+1eresf
+1eresh
+1ereso
+1eres2p
+e1resso
+ere1st2r
+1ereta
+1erete
+1eret2r
+1erets
+1erety
+1er1eul
+ere1un
+1er1eux
+1ereü
+1erf.
+1erfact
+1erfai1
+1erfeit
+1erfey
+1erfj
+1erfos
+erfrech1
+erft1
+1erfuße
+1erfäu
+1erg.
+1erg'
+1erga.
+1ergav
+1ergb
+1ergc
+1ergd
+1erge.
+erg1ein
+erg1end
+1erg1er.
+1erg1ers
+ergerun1
+1erg1es.
+1ergf
+1ergg
+1ergh
+1ergil.
+1ergili
+1ergils
+1ergine
+1ergin1i
+1ergio
+1ergisi
+1ergj
+1ergk
+1ergm
+1ergn2a
+1ergni
+1ergob
+1ergog
+1ergov
+1erg2p
+1ergq
+1ergs
+1ergt
+1ergv
+1ergw
+1ergz
+1ergå
+1ergè
+1ergé
+1ergþ
+1erhae
+1erhax
+1erhels
+1erhen1
+1erhes
+1erh1eug
+1erhoe
+1erh1ofs
+1erhot
+1erhub1
+1erhuk
+1erhul
+erhun1
+1erhün
+1eria.
+1eri1ali.
+1erian
+erib1
+1erica
+1ericho1
+1erick
+1ericl
+1erico
+1ericu
+1erida
+1erie.
+1eriea
+1eried
+2erief.
+1eriek
+1erie1lo
+1eri1en1
+1er1ie2p
+eri1er.
+eri1erf
+eri1ern
+1eries.
+1erieu
+1eriev
+1eriew
+eri1ewel
+1eri1eä
+eri1ga
+eri1gr
+1erii
+1erij
+erims1
+1erimä1
+1erin2a
+e1rind.
+1erine
+1erin1gm
+1erin1i
+1erin2o
+1eri2nsu
+1erin2u
+1erio
+1eris.
+1erish
+1eriso
+1erit.
+1erith
+1eriti
+1erits
+1eriu
+2eriv
+1eriw
+1eriz
+1erjar
+1erjek
+1erjus
+1erk.
+1erkh
+1erkier
+1erkm
+1erlai1
+1erlb1
+1erlem
+1erln
+1erls
+1erlui
+1erly
+1erma.
+1ermaa
+1ermaché
+1ermae
+ermag1
+ermai1
+1ermee1
+1ermel.
+1ermelh
+1ermen2o
+ermen1
+1erment
+1ermes.
+1ermeu
+1er1mey
+1ermez
+1ermic
+ermi1er
+1ermin.
+1ermin2o
+1ermins
+1ermis.
+1ermol
+1ermot.
+1ermou
+1erm2p
+1erms
+1ermun
+ermunt1
+1ermy
+1ermú
+1erna.
+ern2a
+1ernab
+1ernacc
+1ernak
+1ernal
+1ernas.
+1ernasco
+1ernay
+1ernaz1
+1ernb
+1ernc
+1erned2
+1erneg
+1ernet.
+ern1et1
+2er1neu.
+1ern1eui
+1erney
+1erng
+1ernice
+ern2ic
+1ernier
+1ernl
+1ernm
+1erno.
+ern2o
+1ernod
+1ernol
+1ernon
+1ernos
+1ern2p
+1ernr
+1erny
+1ernz
+1ernö
+1ero.
+1ero'
+1er1oa
+er1ob1i1
+1erocé
+1er1odo
+e1rofo
+1erog
+1er1oj
+1erola
+1er1old
+1er1olf
+1er1olz
+1eron.
+1eron2a
+1eron1i
+1eronk
+1erons
+1eront
+1eroph
+er1o2p
+1eropo
+1eros.
+2erot.
+eroto1
+e1rotz
+e1roul
+1erous
+1eroz
+1erpel
+er2p
+1erpfö
+1erpn
+1erpog
+1erp1oi1
+1erpom
+1erpoo1
+1erprè
+1erpuz
+1erpy
+1erra.
+er1ra
+1erraf
+1errai1
+1erras.
+1errav
+1er1re.
+1er1rer
+1erret.
+er1ret
+1er1rev
+1errey
+1er1ri.
+1errick
+er1ric
+1errier
+er1rie
+1errita
+er1rit
+1erriè
+1erro.
+er1ro
+1errog
+1err1ol.
+1err1ols
+1error
+1erruca
+er1ru
+1errus1o
+1er1ry
+1errè
+1errò
+1ersa.
+1ersace
+1ersal.
+1ersalbu
+1ersale
+1ersali
+1ersam.
+1ersamer
+1ersanf
+1ersang
+1ersati
+1erschen.
+erschen1
+1ersci
+1ersdy
+1erse.
+1ersed
+erseg1
+1ersele
+1erselu
+1ersenda
+ersen1
+1erse2p
+erseri1e
+1erses.
+1ersesc
+1ershä
+1ersib
+1ersier
+1ersifi
+1ersili1
+1ersin.
+1ersio
+1erskin
+1erskli
+1erslä
+1ersmol
+1ersnov
+ersn2o
+1ers1o.
+1ers1oi1
+1ers1ou1
+1ersov
+1erspaa1
+ers2p
+1erspred
+1erssen1
+ers1tag
+ers1takt
+ers1tas
+1er2st1eil1
+erst1ei
+1erstrae
+erst2r
+1erstöh
+1ersus1
+1ersva
+1ersüb
+1erta.
+ert1e1la
+ert1elin
+ert1ella
+ert1elli
+ert1ello
+ert1ellä
+ert1em
+1erterr
+ert1er
+1erthü
+1ertica
+1ertice
+1ertici
+1ertik
+1erto.
+1ertol
+1ertot
+1ertov
+1ertu1m
+1ertu2p
+1ertà
+1ertè
+1erté
+1eru.
+erub1
+eruchs1
+1eruda
+erufs1c
+1eruma
+eru1m
+1erumb
+1erumä
+2e1runde
+erun1de.
+erun1dg
+1erundi
+e1runn
+1erup.
+eru2p
+1erus.
+1erusa
+1erusk
+1erusw
+1eruš
+1erva.
+1ervah
+1erval
+1ervi.
+1ervil
+1ervl
+1erweij
+1erwer.
+1erz.
+1erzas
+1erzb
+1erzed
+erz2e
+erze1le
+1erzes
+1erzon.
+erzun1ge
+erz1ung
+1erzyc
+1erà
+2eräd
+1eräl
+1eräm
+erä1rg1
+e1räuc
+1erå
+1eré
+1erê
+1erí
+1erð
+1erò
+1eró
+1erö.
+2e1röll
+1erø
+2erüc
+e1rüm
+1erþ
+1er┊
+e1sabb1
+1esabe
+1esabg
+1esabl
+1esa1br
+1esabs
+1esa1bw
+e1sach
+1esad1
+1esaf
+esag1
+e1sais
+1esakt
+e1salb
+esa1ll
+e1salo
+1esalt
+esa1mer
+esa1mm
+esa1m1ma
+esa1ms
+esa1mt
+esa1mu
+1esan.
+1esanb
+1esanc
+1esanh
+1esanl
+1esanm
+1esans
+1esanw
+1esanz
+1esanç
+1esar.
+1es1arb
+1es1ari
+esa1rol
+es1aro
+1es1arz
+esatt1
+e1sauc
+1esav1
+1esaz
+1esbau
+1esc.
+1escaf
+1escam
+1esce
+e1sch.
+e1schar
+e1schau
+e1schb
+e1schd
+e1schec
+e1schen1
+e1schk
+e1schl
+e1schm
+e1schn
+e1scho
+e1schs
+e1scht
+eschwer1
+e1schw
+e1schö
+1escod1
+1escu
+esd1em
+e1se'
+e1see1l
+1esef
+ese1hi
+es1ei
+e1seic
+e1s1eil.
+1eseim
+eseki1
+1eseko
+ese1lam
+eselan1
+ese1lat
+ese1leb
+e1selek
+ese1leu
+ese1lis
+ese1lle
+ese1llu
+ese1lot
+ese1ma
+1es1em2p
+ese1nac
+es1en2a
+esen1de1si
+e1sendu
+1es1endü
+esenschaf1
+ese1rab
+ese1ras
+es1e1rat
+1eserb
+ese1reis
+1eserf
+1eserg
+ese1ric
+eseri1e
+1eserk
+1eserm
+1esero
+ese1rot
+1eserr
+ese1run
+ese1se
+e1sesg
+1eseta
+e1sets
+2e1setz
+1esfre
+1eshaf
+1eshee1
+1eshel
+1eshil
+1eshim
+1eshit
+1eshoc
+1eshon
+e1sh1o2p
+1eshos
+1eshot
+1eshu
+1eshy
+1esi.
+1esia
+1es1ic.
+1esidi
+1es1idy
+1esie.
+1esien1
+esi1er.
+esi1eri
+esi1ern
+esi1ers
+1esigh
+1esime
+1esimo
+esin1d
+1esine
+1esinf
+1esinh
+1esio
+e1sitt
+e1sitz
+1esiu
+1esiw
+1esk.
+1eskab
+1eskah
+1eskam
+1eska2p
+1eskar
+1eskf
+1eski.
+1eskil
+1eskin
+1eskri
+1esks
+1eskt
+1eskä
+1eskü
+eslan1
+esleg1
+1esly
+1eslö
+1esme
+1esmi
+1esmä
+1esmö
+1esmü
+1esnä
+1esob1
+es1of
+e1s1ofa
+es1oge
+e1s1oh
+e1s1old
+e1s1olv
+e1s1om
+es1on.
+e1s1ong
+es1ons
+1esora
+es1or
+1esord
+es1ou1
+1es1ouv
+1espaa1
+es2p
+1espak
+1espalm
+1espara
+1espat
+1espau
+1esph
+1espok
+1e2spol
+esporti1
+1espos
+1esprak
+1esprob
+1esprof
+1esprog
+1es2pr1o2p
+1espräm
+1esprüf
+1espub
+1espäs
+e1spü
+e1ss.
+e1ss'
+1essaa1
+1essac
+1essaf
+1essal
+e1ssa1ll
+e1sscl
+e1ssd
+1esseg
+esse1lad
+e1ssenz
+essen1
+esse1rec
+esseri1e
+e1sset
+1esseu
+e1ssex
+essha1b1
+e2s1shi
+1essic
+e1ssig
+e1ssin
+e1ssir
+e1ssj
+e1ssku
+e1ssn
+1ess1om
+e2s1spie
+ess2p
+e2sstä
+e2sstö
+essv1e
+e1ssw
+e1st.
+e1st'
+e1sta.
+1estag.
+e1sta1ll
+e1stalt
+e1stanl
+e1stans
+est1ari1
+e1stas
+1estau1m
+e1staus
+1estaz
+e1stb
+e1stc
+e1std
+e1ste.
+e1st1ea
+1e1steb
+1es1techn
+e1sted
+este1ha
+e1steh
+1e2st1eil1
+est1ei
+e1stein
+e1ste1mm
+e1st1en1
+e1ste2p
+e1ster.
+est1er
+e1sterw
+e1st1eue
+est1eu
+e1stf
+e1stg
+e1stha
+1esthe
+e1stho
+1es1thr
+e1sthö
+esti1en1
+e1stig
+e1stim
+e1stin
+e1stj
+e1stk
+e1stl
+e1stm
+e1stn
+1estod
+e1stof
+e1ston
+1estor.
+1estort
+1estou1
+e1st2p
+e1stq
+1estrag
+est2r
+1estref
+1es1treib
+e1stres
+e1stric
+1estr1o2p
+1estrun1
+1e1stræ
+e1sts
+e1stt
+1es1tunn
+e1stus
+e1stv
+estv1e
+e1stw
+e1stz
+e1stäl
+1es1tänz1
+1estöt
+1es1tüch
+1esua
+1esuma
+esu1m
+1esumf
+1esummi
+e1sum2p
+1esumz
+1esunc
+e1sun1d
+1esunf
+1esuns
+1esunt
+e1su2p
+1esurl
+1esus
+1eswa
+1eswic
+1eswä
+1eswö
+1eswü
+1esy.
+e1sys
+1esza
+1eszei
+esz2e
+1eszi
+1eszk
+1eszo
+1eszw
+1eszy
+1eszä
+1eszü
+e1sät
+1esök
+1esø
+1esù
+1esüb
+etag1er
+e1tags1
+1etall
+eta1llan
+eta1llau
+eta1lleis
+eta1llen1
+eta1llo
+eta1llu
+eta1llö
+eta1llü
+1etalo
+eta1log
+1etappe
+eta2p
+etap2p
+etari1e
+et1ari
+1etat.
+et1ee1
+1eteet
+et1ega
+et1ei
+1etek.
+et1el.
+et1elb
+et1elc
+et1ele
+et1elf
+et1elg
+et1elk
+et1eln
+et1el2p
+et1elr
+et1els
+et1eme
+1eteni
+et1en1
+et1er
+et1esa
+et1ese
+et1esk
+et1esn
+et1es2p
+ete1sse
+et1eu
+ethani1
+ethe1is
+ethi1e
+ethof1
+1ethy
+1eti1en1
+1etie1s
+etife1
+2eting
+1etist
+1etok
+1etra.
+et2r
+etrai1
+1etre.
+1etro.
+1etro'
+et1sc
+etschaf1
+ets1t1em2p
+et1ste
+ets1te2p
+ett1el
+1etui
+etunt1er.
+etutt1
+1etuv
+etz1un
+etzv1e
+1età
+etät1
+1eté
+1etê
+eua1l
+1eub
+eubrin1
+eu1brü1
+1euc
+1eud
+1eue
+eue1lo
+eue1sk
+eue1sn
+1euf.
+1eug
+eug1el
+eug1en
+eug1eri
+euglei1
+eugrun1
+euhol1
+1eui
+1euk
+euko1
+1eul
+eula1s
+2eulk
+eul1l
+e1u2m.
+eu1m
+e1umb
+e2ume
+e1umf
+e1umg
+e1umh
+e1umk
+e1uml
+e1um1m
+e1um2p
+e1umq
+e1umr
+2e1ums
+eums1te
+eums1tü
+e1umt
+e1umv1
+e1umw
+e1umz
+1eunfe
+eun1g
+eunt1er.
+e1unv1
+1eur.
+eurasi1
+1eure
+euri1er.
+e1urlau1
+1eurn
+1euro
+1eurr
+1eurs
+eurti1
+1euré
+1eusa
+eusa1m
+e1usb
+1euse
+1eusn
+e1usz
+eut1ela
+eut1ele
+eut1ell
+1euv
+1euw
+1eux
+1euy
+1euz
+1evak
+evali1e
+eva1ll
+eva1lli1
+evals1
+evang1
+evb1
+evea1
+evee1
+eve1lan
+ev1era
+ev1erb
+ev1erd
+ev1ere
+ev1erf
+ev1erg
+ev1erha
+ev1erhe
+ev2erhä
+ev1eri
+ev1erk
+ev1erl
+ev1erm
+ev1ern
+ev1ero
+ev1er2p
+ev1err
+ev1ers
+ev1ert
+ev1erw
+ev1erz
+ev1erä
+1eveso
+1evf
+evg1
+1evh
+1evj
+1evlu
+evo1nd
+evo1n2p
+ew1ar
+ewa1r.
+1ewb
+ewe1be1i
+eweg1
+1ewern
+1ewf
+1ewg
+ew1ief
+ew1ien1
+1ewj
+1ewk
+1ewl
+1ewm
+1ew2p
+1eww1
+1ewy
+1ewz
+ewä1r
+1exam
+1exem
+exil1
+exi1n1es
+1exku
+1expe
+ex2p
+1expo
+1extra
+ext2r
+1exz
+1ey'
+1eya
+eyb1
+1eyc
+1eyd
+eydi1
+eye1li
+1eyf
+1eyg
+1eyi
+1eyk
+1eyl
+1eym
+1eyn
+1eyoğ
+1eys
+1eyt
+1eyz
+1eyş
+ezei1t1er
+ez2e
+e1zeit
+1ezh.
+ezib1
+ezi1es
+1ezoe
+1ezok
+1ezom
+1ez1oq
+ezott1
+1ezow
+ez1ua
+ez1ue
+ez1ugl
+ez1ui
+ez1un1g
+ez1uo
+ez1upf
+ezu2p
+ez1uq
+ezu1r
+ezv1
+eßha1b1
+eßint1
+eßv1e
+1eć
+1eń
+1eś
+1eż
+1f's
+1fa.
+1fa'
+fa1bz1
+1fach
+fado1
+fae1s
+1fah
+fakt1er
+1fal
+falb1
+f1a1led2
+fali1e
+fa1llib1
+fal1lic
+fal1lis
+falschla1
+falschlä1g
+fals1o
+1fam
+1fand1
+fang1en
+1fanm
+1fans
+1fant
+1fanw
+fanz1
+1fa2p
+farb1ei.
+f1arb
+far1brü2
+1fare
+far1fa1l
+f1arf
+1f1arg
+1f1arh
+farnun1
+f1arn
+farn2u
+f1a1rä
+fa1rü
+1fase
+faub1
+fav1
+favi1e
+favo1r.
+1fbahn.
+fb1ahn
+1f1bas
+1fbec
+1fbed
+f1b1ee
+1fbefe
+fb1ein
+fb1eis
+fb1eiz
+fb1en
+fb1erg
+fb1esen
+fbesti1
+1f1bet2r
+fbit1
+fb1oa1
+1fbod
+1f1bol
+1fboo1
+1fb1oy
+fbrech1
+1fbrem
+fbrich1
+f1brü1
+1fbumm
+fbu1m
+1fbur
+fbänd1
+f1bä
+1f1büc
+1fdau
+1fdeg1
+fd1em
+1fden
+1fder
+1f1dia
+1fdie
+1fdin
+1fdis
+1fd1o2p
+1fdor
+fdritt1
+f1drit
+fdun1
+1fdüs
+feaus1
+fe1b1ea
+fee1h
+fee1is
+fee1l
+f1ee1r.
+fee2rei
+f1ee1re
+fee1s
+feg1el
+feg1en
+fe1g1eri
+1feh
+fe1ha
+fe1hei
+fe1ho
+fe1hü
+1feig
+feilschaf1
+f1eils
+feke1
+1fel
+feldun1g
+f2e1leh
+fe1lie
+fe1ll.
+fe1llb
+fe1lld
+fe1lle.
+fe1llen1
+fe1ller
+fe1llf
+fe1llg
+fe1llh
+fe1llk
+fe1ll1l
+fe1llm
+fe1lln
+fe1ll2p
+fe1llr
+fe1lls
+fe1llt
+f2e1llv
+fe1llw
+fe1llz
+fe1llü
+fe1log
+felschaf1
+fe1mac
+fe1mei
+feme1m
+fe1mer
+fe1mes
+fe1met
+fe1mm
+fe1mus
+fe1mut
+1fenb
+1fene
+1feng
+fen1kau1
+1fenl
+1fenst
+fen1ta
+fen1td
+fen1te
+f1en1tf
+fen1th
+f1en1tn
+1fen1t2r
+fen1tw
+f1en1tz
+1fenz
+fenz1u2p
+1fenä
+1feq
+fera1ll
+ferb1ei
+1ferbu
+ferbänd1
+fer1bä
+ferdrü1
+fer1dr
+1fere
+fe1ref
+1ferh
+ferha1t
+ferich1
+feri1et
+1ferk
+1ferl.
+1ferm
+fe1rol
+fers1o
+1fert.
+fe1ruf
+ferv1e
+1ferz2e
+fe1sc
+fe1sem
+fe1si
+fe1sk
+fe1s2p
+fe1ss
+fe1st
+fe1su
+fe1sy
+fe1sz
+fe1sä
+feti1e
+1feu
+fe1unt
+fev1
+1ffad
+1ffag
+1f1fam
+1ffar
+1ffau
+ffee1
+ffeg1
+1f1feh
+ffe1in.
+ffe1in2a
+ffe1ind
+ffe1ine
+ffe1inf
+ffe1ing
+ffe1in1i
+ff1e1inj
+ffe1inm
+ffe1in2p
+ffe1inr
+ffe1ins
+ffe1int
+ffe1inv
+1f1fel
+ffellau1
+f1fenh
+1f1fes
+1f1feu
+f1fi
+1ffier
+f1fie
+1ffin.
+ffiti1
+1fflä
+1f1fm1
+f1fne
+f1fob1
+ffoli1
+ffon1i1
+f1fon
+f1fr
+1ffrau
+ffre1sc
+ffsa1g
+f1fsta
+f1fs1tag
+ffs1tal
+ffs1tau
+ffs1te2p
+ffs1tic
+ffs1tie
+f1fs1tou1
+ff1s1tut
+ffv2erh
+ffv1e
+ffärb1
+1ffö
+f1fü
+1fgeheg
+f1gehe
+fg1ei
+fg2el.
+fg1en.
+fg1end
+1fgenos
+fgen2o
+fg1enr
+fg1ens
+fgeränd1
+f1gerä
+1fgit
+1fgot
+fgott1
+1fgur
+1fhaf
+1fhah
+1fhand1
+fhau1
+fhea1
+fheb1
+fhe1ll
+1fhem
+1fhir
+1fhof
+1fhos
+fhot1
+fhun1
+1fhäf
+1fhänd1
+1fhäus1
+1fhüh
+fi1a1ri
+fi1a1ro
+fibb1
+1fic
+fide1i
+1fie
+fieb1
+fi1eff
+fi1e1h.
+f1ie1h
+fi1ei
+fi1enk
+fien1
+fi1enn
+fi1ent
+fi1enz
+fi1erb
+fi1erf
+fi1eri
+fi1ern
+fi1err
+f2i1eso
+fie1st
+fi1ett
+fi1ev.
+fift1
+1fig
+fi1gel
+figli1
+fi1gri
+fikt1
+1fil
+fi1l1lo
+1fim
+fineb1
+fing1era
+fing1ere
+fi1niv
+fin1i
+fios1
+1fiq
+1fir
+fire1l
+fi1re
+1fisc
+fischla1g
+fit1ei
+1fjac
+1fjah
+1fjun1
+fka1ll
+1fkan2a
+1fkanä
+1fka2p
+fkape1
+1fkat1
+fkau1
+fke1l
+1fker
+1fket
+1fkid
+1fkir
+1fkis
+fkitt1
+fklan1
+fkla1s
+fkle1b
+1fkne
+1fkol
+1f1kons
+fkora1
+1fkos
+1fkraf
+1fkred
+1fku1m
+1fkus
+1fkäf
+1fküh
+flanschla1
+flau1
+flavi1e
+1fle.
+flee1
+fleg1en.
+1fler
+flib1
+flili1
+flings1
+1flit
+flob1
+1flog
+1fl1oi1
+flos1st2r
+flos1stü
+flou1
+1fluc
+1flug
+flunt1
+1flur
+1flus
+flut1ei
+1flän
+1flär
+1f1lüg
+fmade1
+fmad1
+fmagi1
+1fmah
+fm1ale
+1fmat
+fmee1
+1fmel
+1fmen1
+1fmet
+1fmie
+1fmin
+1fmit
+1fmod
+1fmom
+fmunt1
+1fmäs
+1f1mäß
+1f1mün
+1fnam
+fn2a
+1fnas
+1fn1en1
+fne1st
+fn1es
+fnich1
+fn2ic
+fnungs1
+fn2u
+1fnungsth
+fnäs1
+1fob
+foe1
+f1ogli1
+foi1e
+f1oi
+folg1
+foli1e.
+f1olt1
+1fon
+fonci1
+fonds1
+foni1s
+fon1i
+foo1
+1fopt
+f1o2p
+fo1rad
+fore1m
+forgi1
+form1
+forni1er
+forti1er
+fos1chin
+1fot
+foto1
+fou1
+f1oub1
+fou1chi1
+f1ouc
+fourn1i1
+f1our
+1f1oy
+1fpaa1
+f2p
+1fpat
+1fpen1
+1fper
+1fpfe
+1fpfo
+1fph
+fporti1
+fpre1s
+1fpri
+fprämi1
+1fprü
+1fpäc
+1fra.
+1frad
+frai1
+fr1a1ro
+1fray
+frazi1
+1fraß
+1frea
+free1
+1fref
+1frei.
+1freie
+frei1n2a
+1frek
+freni1
+1fre2p
+fre1sh
+fre1ss
+fre1st
+1fret
+1freu
+1frev
+1frh
+frib1
+fri1en1
+fri1ga
+frika1l
+1fril
+1frin
+1frisi
+frob1
+1fr1obo
+1frod1
+1froh
+1fron
+frons2
+1fros
+1frou
+frun1
+1fräd
+fränd1
+1fsab
+1fsai
+1fsak
+1fsal
+fsa1ll
+fsa1m
+1fsan
+1fsa2p
+1fsar
+1fsatm
+1fsauf
+1fsaut
+1fsb
+1fsce
+1fschan
+fs1chara
+fs1chart
+1fschef
+fs1chor
+fs1chro
+1fsd
+fsd1em
+fseb1
+fseg1
+fseh1
+fs1ei
+1fseinb
+1fseinh
+1fs1einn
+1fsel
+1fsem
+fsen1
+1fsent
+1fseq
+1fser
+fseri1e
+1fseta
+1fsex
+1fsf
+fsfall1
+fs1fal
+1fsg
+1fsh
+1fsid
+1fsig
+1fsinn
+1fsins
+1fsint
+1fsk
+1fsl
+fsleg1
+1fsm
+1fsn
+fsob1
+1fs1oc
+1fs1of
+fs1og
+1fs1oh
+1fs1on
+1fs1o2p
+fs1os
+1fspak
+fs2p
+1fs2pa2p
+1fspas
+1fspau
+1fspf
+1fsph
+1fspit
+1fspla
+1fsplä
+1fspo
+1fsps
+1fspub
+1fspun
+1fsq
+1fsr
+1fs1s
+fsseri1
+fss1o
+1fstag
+1fs1tak
+1fs1tale
+fs1tank
+1fs1tas
+1fstat
+fs1tauc
+1fst1ea
+fs1t1ee
+1f1steg
+f2s1t1eil1
+fst1ei
+f1ste1mm
+1fst1en1
+1fst1er
+fs1term
+fs1terr
+fs1tex
+1fs1th
+fs1tipp.
+fsti2p
+fstip2p
+1fs1tis
+fs1tit
+fs1t1oi
+1fs1ton
+fs1tor.
+fs1tore
+fs1tot
+1fstou1
+fs1trab1
+fst2r
+1fs1trai1
+fs1tra2p
+fs1tre2p
+1fstres
+1fs1tri2p
+1fstro
+fs1trol
+fs1tros
+1fstru
+fs1trub
+f1s1truc
+fs1tru2p
+1fs1träc
+1fstäl
+1fstät1
+fs1täti
+1fstüc
+fs1tüte
+1fsumw
+fsu1m
+1fsun
+1fsu2p
+1fsur
+1fsv
+fsv1e
+1fsw
+1fsys
+1fsz
+1fsäst
+1fsü
+ftai1
+fta1ll
+1ftappe
+fta2p
+ftap2p
+ftau1fst
+f1ted
+ft1efe
+ft1ei
+fteis1
+ft1el.
+fte1len1
+ft1elm
+ft1eln
+ft1els
+ft1elt
+fte1ma
+fte1me
+fte1nam
+ft1en1
+ften2a
+ft1epi
+fte2p
+ft1er
+fte1ref
+fteri1e
+fte1sa
+f1t1esb
+fte1sk
+fte1s2p
+ft1e1ss
+ft1ev
+ft1exa
+ft1ex2p
+ftha1t
+f1ting
+ftit1
+f1tlh
+f1tlim
+1fton
+ftrai1
+ft2r
+f1tre2p
+ftsa1g
+f1tsanm
+f1tsausü
+fts1char
+fts1chef
+ftschm1
+f1tschr
+f1ts1disk
+f1tsehr
+ft1seh1
+f1ts1fam
+f1tsfol
+f1tsgewa
+f1tsidea
+ft1si
+f1tslegi
+ftsleg1
+f1tsphan
+fts2p
+fts1taf
+fts1taus
+fts1t1ee
+ft1ste
+fts1te2p
+fts1tes
+fts1tier
+ft1sti
+fts1tig
+f1tstoc
+ft1sto
+fts1ton
+fts1tor
+fts1trat
+ft1st2r
+fts1treu
+fts1tru
+fts1tur
+ft1s1tut
+fts1tät1
+ft1stä
+f1tstö
+ftsz1ub
+f1twurz.
+ftz1ug
+ftz1un1g
+fug1en
+fulb1
+fumv1
+fu1m
+fun1d.
+fun1db
+fun1de
+fun1dg
+fun1di
+fun1dk
+fun1dl
+fun1do
+fun1dr
+fun1dt
+fun1dw
+funki1e
+fun1ni1
+furg1
+furi1e.
+fus1o
+fuz1
+fvat1
+fv1e
+1fvö
+fw1a
+fweig1
+1fwet
+1fwoc
+1fwun1
+1fwut1
+1fwüt
+fyg1
+1f1zeit
+fz2e
+1fzel
+1fzet
+1fzeu
+1fzon
+fzott1
+fz1ugan
+fz1ugun
+fzu1m1
+fz1un1g
+fz1upfe
+fzu2p
+fzw1
+1fá
+1fäd
+fäg1
+1fäh
+1fäl
+fäng1er
+1färtig.
+1färtige
+fäug1
+1fäul
+fét1
+fög1
+föt1
+füm1
+fü1rz
+f┊e1
+1g'l
+gab1er.
+gab1ert
+1ga1bo
+gabri1
+ga1br
+gadi1e
+gae1s
+gag2en2a
+gag1en
+gagg1
+gai1g
+gai1ne
+ga1lec
+ga1ll'
+ga1lle
+ga1llf
+ga1llg
+ga1llh
+ga1lli
+galli1e
+ga1llm
+ga1lln
+ga1llo
+ga1lls
+ga1llt
+ga1llu
+ga1llw
+ga1llä
+galtun1
+gambi1e
+ga1mb
+gand1
+ga1nerd
+gan1er
+ga1nerv
+gang1en
+gani1e
+ga1niv
+ganti1e
+gan1ti
+gaob1
+gari1e
+g1ari
+garni1er.
+g1arn
+garni1s
+garun1
+g1aru
+ga1rus
+1garv
+1g1ary
+gas1chem
+gas1chro
+gasmus1
+1gasse
+gas1see
+gas1s2p
+gas1st2r
+gas1tur
+gas1tü
+gat1es
+1gatte
+gaub1
+gaug1
+gauli1
+gaulti1
+1gausd
+gauti1e
+1gbad1
+1gbao
+g1b1ee1
+gb1eig
+gb1ein
+gb1eis
+gb1eiz
+gb1enz
+gb1erg
+gb1ert
+gb1ese
+gb1eu
+gb1ey
+gbi1s
+gb1oa1
+gbrich1
+g1brü1
+gbänd1
+g1bä
+1gdal
+gdea1l
+gdeb1
+gde1ss
+1gdis2p
+gdlun1
+gdm1al
+1gdons
+g1don
+1gdram
+1gdy
+gdz1u
+gealb1
+g1ea1re
+g1e1a1ri
+geb1ein
+ge1bei
+geb1en
+geb1ero
+g2ebl
+1gebrec
+gebrech1
+1gedu
+gedun1
+1gedy
+1gedä1
+g1eef
+geehe1
+g1eeks
+gee2m
+g1ee1r.
+g1eert
+g1ee1s
+1gegn
+1g1e1h.
+g1eh'
+gehan1d.
+ge1hand1
+g1eha2p2p
+geha2p
+g1ehauto
+g1ehb
+g1ehd
+1gehe
+g1ehe.
+g1ehen.
+gehen1
+g1ehend
+g1eheng
+g1ehenl
+g1ehens
+g1ehenz
+g1eher.
+g1ehern
+g1eherw
+g1ehes
+g1ehet.
+g1ehf
+g1ehg
+g1ehh
+ge1hi
+g1ehk
+g1ehl
+g1ehm
+g1ehn
+ge1ho
+g1eh2p
+g1ehr
+g1ehs
+g1eht
+g1ehung.
+gehung1
+g1ehungen
+g1ehv
+g1ehw
+g1ehz
+1gehä
+1g1ei.
+g1eia
+g1eib
+g1eic
+g1eie
+g1eif
+1g1eig
+geig1er
+g1eih
+g1eij
+g1eil
+g1eime
+g1ein.
+ge1in1i
+g1einw
+g1eio
+g1ei2p
+g1ei1ra
+g1ei1ri
+g1eis
+g1eit1
+g1eiz
+gekau1
+g1el.
+g1el'
+g1elabl
+gelab1
+ge1lag
+g1elak
+g1ela1mb
+g1elanl
+g1elar
+g1elasi
+g1elasti
+g1elatt
+g1elaufn
+g1elausf
+g1elb
+1gelb.
+1gelbe
+g1elc
+1g1eld
+g1ele.
+g1elef
+g1elel
+g1elem
+1gelen1
+g1elen.
+g1elen2o
+g1elens
+g1eler.
+g1elerf
+g1elerk
+g1elers
+g1eles.
+g1ele1ss
+ge1leu
+g1elex
+g1elf
+g1elg
+gelgeg1
+g1elh
+g1eli.
+g1elib1
+g1elim
+g1elin.
+g1eline
+g1elin1i
+g1elint
+g1elir
+g1eliz1
+g1elj
+g1elk
+g1elleb
+g1ellei
+g1elli2p
+g1ellä
+g1elm
+g1eln
+g1elon
+g1el1o2p
+g1el1osi
+g1elou
+g1el2p
+g1elq
+g1elr
+g1els
+g1elt
+g1elumh
+gelu1m1
+g1elunt
+g1elv
+g1elw
+g1elz
+gelzun1
+ge1mac
+ge1mal
+ge1mas
+g1ema1t2r
+g1emb
+g1emc
+g1eme.
+ge1mes
+ge1met
+g1emin1i
+ge1mod
+g1ems
+ge1mu
+gemunt1
+1gemä
+g1en'
+1genad
+gen2a
+1g1enam
+1ge1naui
+g1enbau1
+g1end.
+g1enden.
+g1ender
+g1endl
+g1endu
+gendun1
+1g1endü
+g1enea
+geneb1
+g1enef
+g1eneie
+gen1ei
+g1eneis
+g1enek
+g1en1el
+g1eneri
+gen1er
+g1enern
+g1enero
+g1eneu
+geng1eni
+1gen1gö
+g1enie.
+g1enies.
+geni1s
+1g1enit
+gen1kau1
+1genke
+g1enoc
+gen2o
+1genpf
+gen2p
+genre1si
+1genrü
+g1ensb
+gens1tag
+1genstet
+g1ensz
+gen1t
+1gen1teu
+1gentä
+1gentö
+genun1g
+gen2u
+1g1enur
+1g1envö
+genz1un1g
+1genäh
+1genö
+g1enöl.
+geob1
+g2e2p
+g1er.
+g1er'
+g1eraa
+g1erab
+g1erak
+g1eral
+g1erans
+g1erant
+g1erar
+g1eratm
+g1erau.
+g1eraue
+g1eraug
+g1erausr
+g1erb
+g1erc
+g1erd
+g1ere.
+ge1rea
+ge1rech
+g1eregg
+g1ereh
+ge1reic
+g1ereig
+g1erel
+g1er1em.
+g1eren.
+g1eren1t
+g1eren2u
+g1ere2p
+g1erer
+gere1ss
+g1eret.
+g1erex
+ge1rez
+g1erf
+g1erg
+g1erh
+g1eri.
+g1eria
+g1erid
+g1erier
+ge1ril
+g1erim
+g1erin.
+g1erins
+g1erinv
+g1erisc
+ge1risi
+g1erism
+g1erist
+g1erj
+g1erk
+g1erl
+gerli1er
+g1erm
+germ1al
+g1ern
+g1er1obs
+g1erof
+ge1rom
+g1eroo
+g1er1o2p
+g1eror
+g1erov
+g1er2p
+g1erq
+g1err
+g1ers
+gersa1m
+gers1o
+g1ert
+ge1ruc
+1gerud
+gerun1d
+g1eruni
+g1erunt
+1geru2p
+g1erur
+g1erv
+gerv1e
+g1erw
+1gerweh
+g1ery
+g1erz
+1gerä
+g1eräh
+gerähn1liche.
+g1erä2p
+g1erär
+1gerö
+g1eröf
+g1erüb
+g2e1rüc
+g1es.
+g1es'
+g1esa.
+ge1sac
+g1esak
+g1esa1ll
+g1esb
+ge1schr
+g1esd
+ge1seil
+ges1ei
+ge1sel.
+g1esele
+g1eserw
+g1esf
+g1esg
+g1eshä
+g1eshö
+g1esis
+ge1sit
+g1esj
+g1eske
+g1eskl
+g1esko
+g1eskr
+g1esku
+g1eskö
+g1esmu
+g1esne
+g1eso.
+ges1on
+g1espf
+ges2p
+g1esq
+g1esr
+g1essc
+ge1sse.
+ge1ssen1
+g1essh
+ge1ss1t.
+g1essti
+g1essä
+ges2t
+g1estale
+g1esth
+ge1stü
+1gesu
+g1esuf
+gesun1
+gesung1
+g1esv
+ge1sy
+g1eszu
+gesz1ug
+ge1sä
+getrich1
+get2r
+getv1e
+1getö
+ge1unt
+ge1url
+ge1urt
+g1eus
+g1evit
+1gew1al
+g1ewen.
+1gewes
+1gewö
+1gewü
+g1ex2p
+g1ext
+1geä
+1geö
+1geü
+gfall1
+g1fal
+gfa1ll2p
+1g1fel
+gfe1ll
+1g1fig
+gfing1
+1gford
+1gforu
+gfug1
+gfun1
+1gfär
+ggab1
+ggb1
+gge1b1ea
+gg1ehen1
+g1gehe
+gg1elet
+gg1ell
+gg1en.
+gg1enb
+gg1end
+gg1ene.
+gg1en1en1
+gg1en1er
+gg1enf
+gg1eng
+gg1enh
+gg1enk
+gg1enl
+gg1enm
+gg1enn
+gg1en2p
+gg1enr
+gg1ens
+gg1en1t
+gg1env
+gg1enw
+1gg1eri.
+ggg1
+ggi1eri
+ggi1ge
+ggi1gu
+ggle1se
+1gglis
+1gglo
+ggregie1
+ggrue1
+1ghans
+gha1ts
+1ghau2p
+gheb1
+ghe1ll
+gh1fa1l
+ghi1en1
+ghi1er
+ghint1
+ghn1e1s
+ghof1
+1ghornbi
+1ghorne
+ghot1
+ghs1c
+ght1ee1
+ghts1
+ghtv1
+ghun1
+1ghu2p
+ghäs1
+1g1hø
+1g1hüg1
+gia1ll
+gi1ele.
+gi1ell
+gi1els
+gi1en.
+gien1
+gi1end
+gien1e1i
+gi1enh
+gi1enk
+gi1enn
+gi1enr
+gi1ens
+gi1eri.
+gi1ersh
+gi1erzy
+gi1esl
+gi1et.
+gi1ev.
+gi1eva
+gi1ewit
+1gift
+gi1gr
+gilb1
+gili1e
+gimi1t
+ginal1le
+gin2a
+ginee1
+gingrun1
+gional1
+gion2a
+gion1i1
+gions1
+gios1
+1giov
+1gipf
+gi2p
+1gips
+girg1
+1gi1rl
+gisb1
+gis1th
+gis1trä
+gist2r
+gital1
+gitt1el
+giu1m1
+giv1
+1giz
+gjea1
+1gjou
+1gju
+1gjö
+gkape1
+gka2p
+gkat1
+gkau1
+gke1l
+gke1s
+1gkin
+1gkis
+gkitt1
+gklan1
+gkla1s
+gkle1b
+gklän1
+1gkomb
+1gkow
+1gkuli
+1gkult
+glab1
+glae1
+glasi1e.
+glas1sa
+gla1s1ta
+glas1tis
+glas1tra
+gla1st2r
+glas1tri
+glau1
+1glaz
+glb1
+gleb1
+gle1b.
+gleg1en
+1gleic
+gle1l
+gle1m
+gle1reis
+gle1sa
+gle1sc
+gle1st
+gli1eri
+gli1ers.
+1glig
+glili1
+gl1l
+1gl1oi
+glori1
+glou1
+1glub
+1gly
+gläs1c
+1glü
+gm1ale
+gm1a1ll
+gm1arg1
+1gmau
+1gmee1
+gme1s
+gmorg1
+gmot1
+gmou1
+1gmusi
+gnatu1
+gn2a
+gne1lek
+gn1el
+gne1me
+gn1em
+gne1st
+gn1es
+1gney
+gnich1
+gn2ic
+gni1ers.
+gni1g
+gno1c
+gn2o
+gnt1er
+gnungs1
+gn2u
+gnv1e
+1go'
+goa1li
+g1oa
+gob1ei
+g1obe
+gob1el
+gobi1e
+g1ob1i
+goeb1
+g1oe1s
+goint1
+g1oi
+golan1
+1g1old1
+1g1olf
+goli1e
+g1ols2
+gommi1
+1gonal
+gon2a
+gondoli1
+gon1dol
+gong1
+goni1er
+gon1i
+goni1g
+1g1o1n2o
+gont1
+gonz1
+1goo1
+goob1
+g1oog1
+go1oi1
+go1rau
+gore1is
+gorgi1
+gorle1
+go1rob1
+go1rot
+go1run
+gos1o
+gos1sc
+1gote
+gotte2
+g1oub1
+1gpa.
+g2p
+gpe1s
+1gpo.
+gporti1
+1gpra
+gpre1s
+1gprob
+1gpr1oj
+1g2pr1o2p
+gprämi1
+1gps
+1grab
+grab1er
+grab1es
+grai1
+gra1ll
+1gram
+grand1
+grangi1
+1graph
+gra2p
+gras1sa
+gras1st
+gra1s1ta
+gra1s1t2r
+grau1
+greb1
+gree1
+1gref
+gregie1rt
+grei1s1c
+greli1e
+greni1
+gre1sh
+gre1ss
+gre1st
+grich1t.
+1grif
+grob1
+groe1
+1grog
+gro1mi1
+grou1
+1groß
+grub1
+grue1n.
+gruen1
+grums1
+gru1m
+1grus
+1g1ruß
+1gry
+1gräb1
+gränd1
+gräs1c
+1grö
+1grün
+gsa1ll
+gsa1mm
+gs1ari1
+gsatt1
+gsauri1
+1gsbor
+gs1chans
+gs1chara
+1gsche.
+gs1chef
+1gscheid.
+g1schei
+gs1chip.
+gschi2p
+g1s1chol
+gs1chor
+gs1chro
+gs1chör
+gsd1em
+gseb1
+gseh1
+gs1ei
+gseis1
+gse1ll
+gsen1
+gseri1e
+gsfall1
+gs1fal
+gsg1en1es
+gsg1eni
+gsgut2
+gsha1t
+gshaus1
+1gsi1re
+gsleg1
+1gsley
+gsnich1
+gsn2ic
+gsob1
+gs1of
+gs1on
+gs1os
+gs1ou1
+1gspek
+gs2p
+gsporti1
+gs1s
+gsseg1
+gsseri1
+gsslan1
+gss1on
+gs1tabe
+gs1tabl
+gs1ta1fel
+gs1tag
+gs1takt
+gs1tal.
+gs1tala
+gs1tale
+g1s1talk
+gs1tank
+gs1tanz.
+gs1tas
+gs1tat.
+gs1tate
+gs1tauc
+gs1tau1m
+gs1tausc
+gs1tax
+gs1t1eam1
+gst1ea
+gst1ed
+gs1t1ee.
+gst1ee
+gs1tee1s
+gs1t1eic
+gst1ei
+g2s1t1eil1
+g1ste1mm
+gs1tempe
+gst1em2p
+gs1tend
+gst1en1
+gs1tenn
+gs1ten2o
+gs1te2p
+gs1term.
+gst1er
+gs1termi
+gs1terras
+gster1ra
+gs1tex
+1gstha
+gs1ther
+gs1tid
+gs1ti2p
+gs1tis
+gs1tit
+gs1t1oa
+gs1t1oi
+gs1t1ole
+1gstons
+gs1too
+gs1tor.
+gs1torg
+gs1tors
+gs1tort
+g2s1tose
+g1stos
+gs1tou1
+gs1tow
+gs1trab1
+gst2r
+gs1trac
+gs1trad
+gs1trag
+gs1trai1
+gs1trak
+gs1t1rau1m
+gs1tren
+gs1tre2p
+gs1treu.
+g1s1tria
+gs1trib
+gstrich1
+gs1trie
+gs1troc
+g1s1tr1oi
+1gstroth
+gs1trub
+1gstru1m
+gs1trun1
+gs1trü
+gs1tul
+gs1tu1m
+gs1turb
+gs1turm
+gs1tus
+gs1täte
+gstät1
+gs1täti
+gs1täts
+gs1törn
+g1stör
+gs1töt
+1gstüb
+gs1tüm
+gs1tü1rc
+gs1türme
+gs1tüte
+gsumz1
+gsu1m
+1g1sun1d
+1gsät
+1gt1ea
+gt1ee1
+gt1ei
+gt1ele
+gt1er
+1gterr
+gt1eu
+gtit1
+gtrai1
+gt2r
+1gtreu
+gtrich1
+gts1s1
+gtun1
+gtv1e
+gtät1
+gual1
+1g1uav
+gub1
+1gud
+gudb1
+1gueri
+gug1
+gugli1
+guiti1
+gulb1
+gum1ma
+gu1m
+gummi1n
+1gun.
+1gun2a
+gun1d.
+gun1de.
+gun1den
+gun1des
+gun1ds
+gungs1c
+1guns
+gunun1
+gun2u
+1gu2p
+gurg1
+1gurk
+gurnt1
+gusb1
+1guse
+gus1o
+guss1
+gus1son
+gu1sso
+gut1ed
+gut1ei
+gut2en2a
+gut1en1
+guti1e
+gvat1
+gv1e
+gve1l
+1gvera
+gvo1r.
+1gvá
+gw1ar
+2gweil
+1gwelt
+gwen1
+1gwied
+gw1ier
+gyg1
+1gym
+1gyn
+gzab1
+1gzn
+gz1uges
+gz1un1g
+gz1upf
+gzu2p
+gzu1r
+gzuz1
+gzw1
+1gäg
+gä1gg1
+1gäng
+gäng1er
+gäns1
+gänt1
+1gäu
+gä1u1m1
+gång1
+göta1
+1gø
+1güe1
+gügg1
+1güm
+günt1
+1gō
+haa1
+hab1arb1
+ha1bar
+habb1
+hab1ei
+ha1b1ek
+hab1eli
+ha1bel
+hab1er
+ha1bl1iche.
+ha1bz1
+ha1cha1c
+hachg1en
+hackspie1
+hacks2p
+hade1la
+hae1m
+hae1n1
+hae1ro
+hae1s
+haf1tstiefe
+haft1sti
+hagb1
+hag2ei
+hag1eli
+hag1er
+hagg1
+hai1c
+hai1g
+hai1n
+hakt1er
+haktg1
+ha1lau2n
+halb1el
+halb1er
+ha1ll
+ha2l1loc
+haluti1
+halv1
+ha1lä
+ha1m1a
+hami1t
+1hamn
+hanaa1
+han2a
+hand1
+handeli1
+hang1en
+hanglan1
+hanglei1
+hangsa1
+hangz1
+hani1g
+han2o1
+hantun1
+han1tu
+ha1nume
+han2u
+hanu1m
+haos1
+happi1er
+ha2p
+hap2p
+h1a1rei
+ha1rez
+hari1er
+h1ari
+hartun1
+h1artu
+h1a1rä
+hasb1
+has1to
+hata1c
+ha1ta
+ha1te
+hat1ea
+hat1el
+hat1er
+ha1tl
+ha1tm
+ha1tsa
+ha1tsc
+ha1ts2p
+ha1tst
+ha1tsu
+ha1tsä
+hatterhan1
+ha1tt1er
+ha1tu
+ha1tz
+hau1fli
+1haug.
+haus1ta
+haus1t1ei
+hau1ste
+haus1tis
+haus1tru
+haust2r
+hav1
+havo1n
+hazi1
+hb1ein
+hb1eite
+hb1eiz
+hb2eleg1
+hb1enz
+hb1erg
+hb1erl
+hb1erv
+hb1esen
+hbi1s
+hblä1s
+hb1oa1
+hbrech1
+hbrich1
+h1brü1
+hbub1
+hbänd1
+h1bä
+hdea1
+hd2em.
+hden1ti1
+hden1t
+hde1ss
+hdie1
+hdrun1
+h1dru
+hdös1
+hea1c
+h1ea1le
+hea1li
+h1ea1ls
+hea1rs
+hea1rt.
+heat1
+hebb1
+hebe1in
+he1bei
+heb1eis
+he1b1ell
+heb1en
+hed1e
+hee1h
+hee1id
+hee1lem
+hee1len1
+hee1ne
+heen1
+h1ee1nh
+h1ee1r.
+heerz1
+hee1s
+hefe1m
+he1fe1re
+hefe1ri
+1heft.
+1heftc
+1hefts
+heg1emo
+heg1en.
+heg1end
+heg1ene
+heg1enh
+hegg1
+he1hal
+he1hau
+he1heck
+hehe1l
+he1hers
+he1hi
+he1hy
+he1hä
+he1hö
+he1hü
+heide1l.
+heil1
+heim1
+heit1el
+hei1t1er
+hei1ti
+hei1tk
+hei1t2r
+hei1tskal
+1heiz
+heks1
+he1lau2n
+he1law1
+1held.
+heleg1en
+he1leine
+he1leu
+he1lief
+he1list
+he1ll.
+he1ll'
+he1llb
+he1llc
+he1lld
+he1lle.
+he1lleb
+he1llem
+he1llen1
+he1ller
+he1lles
+he1llf
+he1llg
+he1llh
+he1llig
+he1llis
+he1llk
+he1ll1l
+he1llm
+he1lln
+he1ll2p
+he1llr
+he1lls
+he1llt
+he1llu
+h2e1llv
+he1llw
+he1lly
+he1loc
+he1log
+helpers1
+hel2p
+hels1e1i
+hel1se
+helv1
+he1mac
+he1mara
+hemb1
+1h1emd1
+hemi1en1
+he1mm
+he1mod
+he1mom
+he1mont
+hemo1re
+he1mun
+hen1
+h1enah
+hen2a
+he1naß
+heneb1
+h1e1nez
+heng1en
+henkrü1
+henleg1
+he1nul
+hen2u
+herab1
+he1rade
+herb1eam
+her1bea
+herbi1er
+herbänd1
+her1bä
+he1rech
+heree1
+he1reg
+here1ss
+he1rest
+herg1eni
+herma1l.
+hermi1t.
+herni1e.
+h1ero
+hersle1b
+hers1o
+h1eru
+he1ruf
+1heru1m1
+herv1e
+herzu1r
+h2e1rüc
+he1sac
+he1sak
+he1sam
+he1sch
+heseg1
+he1s1ei
+he1sem
+he1serv
+he1se1ss
+he1sex
+he1shi
+he1skal
+he1sku
+hes1o
+he1s1or
+he1spa
+hes2p
+he1spr
+he1ss
+he1st
+he1suc
+he1sy
+he1sz
+he1sä
+het1el
+hetto1
+1hetz
+he1unf
+he1un1g
+he1unte
+he1urk
+hevo1n
+h1eyg1
+hezi1e.
+hez1ube
+hezug1
+hfeg1
+hfe1ll
+h1fel
+hfoli1
+hgame1
+hg1ehen1
+h1gehe
+hg1eher
+hg1en.
+hg1enb
+hg1end
+hg1en1en1
+hg1eng
+hg1enh
+hg1enk
+hg1enl
+hg1enm
+hg1ens
+hg1en1t
+hg1enw
+hgerun1
+hg2es
+hgetunt1
+hglas1
+h1grab1
+hha1b.
+hha1bi
+hheb1
+hheits1
+hhe1ll
+hherni1
+hhint1
+1hhm
+hhof1
+hhot1
+hhun1
+hhäs1
+hiai1
+hial1
+hi1chä
+hi1e1h.
+h1ie1h
+hi1ekk
+hi1eko
+hi1elb
+hi1e1ll
+hi1en1er
+hien1
+hi1enf
+hi1enk
+hi1enl
+hi1enn
+hi1en2p
+hi1env
+hi1enz
+hi1erat
+hie1ren
+hie1rsc
+hie1rst
+hie1rt
+hie1st
+hi1esta
+hi1eta
+hi1ett
+hi1ewü
+hi1geb
+higli1
+hiha1b
+hikt1
+hilau1
+hilb1
+hilg1
+hili1g
+himi1t
+hina1c
+hin2a
+hina1la
+hina1rin
+hin1ari
+h1ink
+hinm1a
+hiree1
+hi1re
+hi1schi1e
+hiss1
+his1son
+hi1sso
+hitti1er
+hiun1g
+hiv1
+hiw1
+hiz1
+hjea1
+1hjø
+hkab1
+hkau1
+hkitt1
+hklan1
+hkla1s
+hkle1b
+hklän1
+hkora1
+hkot1
+hlab1
+hlabb1
+hlachs1
+hlae1
+hlag1er
+hlan1gs
+hlan1gt
+hlat1
+hlau1fs
+hlau1ft
+h1lbart
+h1lebi
+hlee1n1
+hleg1en
+hle1ha
+h1lei.
+h1leib
+hleich1t.
+hleich1ts
+hle1la
+hle1li
+hle1ma
+hle1mik
+hle1min
+hlenschlä1
+hlen1
+hle1reg
+hle1ro
+hlerv1
+hle1sa
+hle1sc
+hle1see
+hle1so
+hle1s2p
+hle1ss
+hle1st
+hletz1t.
+h1lfar
+hlie2
+hli1e.
+hlii1
+hlint1
+hlitt1
+hl1l
+hllau1
+hlob1
+h1lrab
+hls1tag
+hl1st
+hls1ton
+hltau1
+hltrich1
+hlt2r
+h1lts
+hlug1
+hlungs1
+hlwei1t
+h1lwen1
+h1ma
+h1m1alen1
+hma1lle
+hm1all
+hme1la
+hme1le
+hme1me
+hme1rec
+hm1ere
+hme1reg
+hme1rit
+hm1eri
+hme1se
+hme1si
+hme1st2r
+hme1stü
+hmi1el.
+hmi1en.
+hmien1
+hmi1r
+hmi1tz
+hmke1
+hm1m
+hmne1
+hmob1
+hmugg1
+hmug1
+hmv1e
+hnab1
+hn2a
+hnachts1t
+hna1ll
+hnams1
+hn1dru1
+h1neb1el
+hnegedan1
+hnege1da
+hne1he
+hn2eh
+hne1lec
+hn1el
+hne1llan
+hne1lö
+hne1man
+hn1em
+hne1mi
+hne1mo
+hne1nas
+hn1en1
+hnen2a
+hnera1l
+hn1er
+hne1ric
+hne1rol
+hne1sa
+hn1es
+hne1se
+hne1so
+hne1spr
+hnes2p
+hnev1
+hn1geg1
+hnhof1
+hnimi1
+hn1i2smu
+hnob1
+hn2o
+hnsa1m
+hnsv1
+hn2t.
+hn1ta
+hnt1el
+hnte1la
+hnt1er
+hntv1
+hnu1r
+hn2u
+ho1a1rd
+h1oa
+hoa1re
+hob1
+hobb1
+hoe1m
+hoe1nd
+h1oen1
+h1oe1s
+hog1er
+hohn1
+hoko1r
+hollwe1
+homas1s1o
+ho1ma
+homb1
+home1la
+ho1me
+honi1s
+hon1i
+h1ool1
+hope1l
+h1o2p
+horal1
+horbi1
+ho1re2p
+horgi1
+ho1ries
+horv1
+hosende1
+hosen1
+hos1o.
+hos1sc
+hoss1e1i
+hoto1
+1h1oug1
+houlli1
+howe1g
+hp1oi1
+h2p
+hporti1
+hpotatoe1
+hpota1to
+hpreis1
+hprämi1
+hrai1
+hra1ll
+h1raub1
+h1raul
+h1rdad
+hr1da
+hre1lan
+hreli1e
+hre1ma
+hre1mo
+h1renba
+h1renbr
+h1renka
+h1renscho
+h1re2p
+h1rett
+hre1un
+hrg2eh
+h1ria
+hrib1
+h1ric
+hrich1tk
+hrich1ts
+hrich1tt
+hrich1tv
+hri1en1
+h1ring
+hri1s1so
+h1rland1
+h1rna.
+hrn2a
+h1rnaz1
+hrnb1
+h1rners
+hrn1er
+hrn1e1s
+h1rni.
+h1rnl
+h1rn2o
+hrob1
+h1roh
+h1rol
+hrom1
+h1rot
+hrset1
+hrs1o
+hrs1s
+hrs1taf
+hrs1tag
+hr2s1t1eil1
+hrst1ei
+h1rstor
+hrtv1
+h1ruh
+hrun1d
+hrungs1
+hrv1e
+h1rw1an
+h1rzad
+hrze1l
+hrz2e
+hränd1
+hrös1c
+hsa1mm
+hsa1mt
+hschlä1g1er
+hschm1
+hseb1
+hsee1i
+hseg1
+hs1ei
+hsen1
+hseri1e
+hsia1
+hsi1e.
+hs1o.
+hsob1
+hs1od
+hs1of
+hs1on
+hs1os
+hs1ou
+hs1s
+hsseri1
+hss1o
+hs1tafe
+hs1tag
+hs1tak
+hs1tal.
+hs1tale
+hs1t1arta
+h1start
+hs1tas
+hs1ta1ta
+hs1ta1to
+hs1t1eam1
+hst1ea
+h2s1t1eil1
+hst1ei
+hste1ma
+h1ste1mm
+hs1term
+hst1er
+hs1terr
+hs1te1st.
+hs1tex
+hs1tiere
+hs1tiers
+hs1tilg
+h1stil
+hs1tis
+hs1ton.
+hs1tor.
+hs1tou1
+hs1trak
+hst2r
+hs1tranc
+hs1treu.
+hs1tr1eue
+hs1trub
+hs1tru2p
+hs1tu2m.
+hstu1m
+hstv1
+hs1täte
+hstät1
+hs1täu
+hs1töt
+h1t'.
+h1t's
+h1ta1bf
+htale1i
+hta1ll
+ht1ari1
+h1t1arn
+htat1
+htaus1s
+h1tbehä
+htb1eil
+h1tchen1
+ht1ea.
+h1tech
+ht1echt
+ht1eck
+hte1ha
+htehe1
+ht1ei
+h1teim
+hteis1
+ht1el.
+ht1el'
+ht1elar
+ht1elb
+ht1elc
+ht1eld
+ht1ele
+ht1elf
+ht1elg
+ht1elh
+ht1elin
+ht1elit
+ht1elj
+ht1elk
+ht1ella
+ht1elli
+ht1ello
+ht1ellä
+ht1elm
+ht1eln
+ht1el2p
+ht1elq
+ht1elr
+ht1els
+ht1elt
+ht1elu
+ht1elv
+ht1elw
+ht1elz
+hte1mac
+ht1eman
+ht1emit
+h1t1em2p
+h1tenhu
+ht1en1
+h1tenro
+ht1eo
+ht1er
+ht2eraf
+h1terar
+h1terbo
+h1terbr
+h1terc
+ht1e1rec
+ht2erest
+h1terfe
+h1terfö
+h1terhu
+h1terkra
+h1terlin
+h1termü
+h1tersk
+h1t1ersw
+h1terwo
+hte1sc
+ht1e1ss
+ht1eth
+ht1ex2p
+htfall1
+ht1fal
+h1t1fon
+h1tga
+htg1eni
+h1thauf
+h1thea1
+hthi1er
+h1thofe
+h1ti.
+h1tie
+h1tik
+h1ting
+h1tins
+htit1
+h1tkar
+h1tl.
+htob1
+h1toc
+h1ton
+h1tow
+htrai1
+ht2r
+htrich1t1er
+ht1richte
+htrot1
+h1tsack
+ht1sac
+ht1sc
+hts1cham
+hts1chem
+hts1chor
+hts1chro
+h1tsgas
+h1tsmei
+hts1tal
+hts1t1ee
+ht1ste
+hts1tem
+hts1te2p
+hts1test
+hts1ton
+ht1sto
+hts1tor
+h1t1stras
+ht1st2r
+hts1trau
+h1t1straß
+hts1tr1eue
+hts1trun1
+hts1träu
+hts1tur
+hts1tür
+hts1tüt
+h1tsäc
+htt1el
+httrich1
+htt2r
+h1tu2p
+h1tw1ag
+h1twerk
+h1twö
+htz1un1g
+htz1u2p
+htzu1r
+h1tüt
+hua1ll
+huan2a1
+hub1
+hubrin1
+hueb1
+hue1le
+hue1nk
+huen1
+hue1rm
+hu1fe1l
+hug1en
+huggs1
+huhlau1
+huis1
+hulan1
+hule1s
+huli1g
+hul1lan
+hul1la1s
+hul1lau1
+hul1leb
+hul1lei
+hul1lern
+hul1lie
+hul1liga
+hun1d.
+hun1da
+hun1db
+hun1de.
+hunde1l
+hun1den
+hun1des
+hunde1s2p
+hun1dfi
+hun1dh
+hun1di
+hun1dk
+hun1dl
+hun1dm
+hun1d2p
+hun1ds
+hunds1ta
+hun1dt
+hun1du
+hun1dw
+hung1
+hun1ga
+hungs1
+hurb1
+hurich1
+husa1m
+hus1o
+hus1sch
+husse1in
+huss1ei
+hus1ti
+husz1
+huz1
+hvat1
+hv1e
+hv2erhä
+hvo1n
+hw1a
+hw1ag1
+hwai1
+hwalb1
+hw1al
+hwa1r.
+hwe1gl
+hwei1ss
+hwer1de.
+hw1ien1
+hwi1llt
+hwo1ll.
+hwo1lln
+hwul1
+hwäg1
+hwä1r
+hyb1
+hyg1
+hylb1
+1hyä
+hzeits1t
+hz2e
+h1zeit
+hze1ll
+hzott1
+hz1ugla
+hz1un1g
+hzw1
+hä1gg1
+häls1c
+händ1
+hän1i1
+häns1che
+häs1chen1
+häs1sc
+häti1e
+häug1
+häus1
+hä1us2p
+1häut
+héb1
+hég1
+héni1
+hög1
+1höhe
+1höhl
+1höj
+hös1che
+1hø
+høg1
+hús1
+1hüg1
+hüls1c
+hüng1
+iabe1re
+iabet1
+ia1brü1
+ia1br
+ia1che.
+iae1n1
+iahi1e
+iakt1er
+ia1leu
+ialgeg1
+ia1lls
+ia1lu2p
+iams1
+iand1e
+ia1neg
+ia1nü
+ia1rac
+ia1reg
+i1a1rei
+ia1rev
+ia1rif
+i1ari
+iarni1
+i1arn
+ias1son
+iass1o
+ias1st
+ias1tag
+ia1sta
+ias1tit
+iat1er
+ia1tv1
+iaub1
+ia1u2n
+ia1ur.
+ia1url
+iaus1s
+ibakt1
+ibats1
+ibaudi1
+ibb1el
+i1b1ee
+ib2eg
+ibe1h
+ib1eig
+ib1ein
+ib1eir
+ib1eis
+i1bel
+ib1eli
+ibelun1g
+ib1elun
+ibe1m
+ib1en
+ib2en2u
+i1benzi
+ib1er.
+ib1era
+ib1erb
+ib1erc
+ib1erd
+ibe1rec
+ib1ereh
+ib1erf
+ib1erg
+ib1erh
+i1berha
+ib1erin
+ib1eris
+ib1erk
+ib1erl
+ib1erm
+ib1ern
+ib1er2p
+ib1err
+ib1ers
+ib1ert
+ib1erun
+ib1erv
+ib1erw
+ib1erz
+ib1erä
+i1b1es.
+ib1esen
+i1b1esh
+ib1esl
+ib1ess
+ibe1st
+ib1esw
+ib1eu
+ib1ey
+ibg1en
+ibhaus1
+ibhau1
+i1bib2
+ibi1en1
+ibi1s
+ible1me
+iboe1
+ibre1m
+i1brü1
+ibs1o
+i1bst1ei
+ibub1
+ibungs1
+i1burg1
+ibänd1
+i1bä
+1ic.
+icai1
+ice1h
+ice1la
+ice1me
+ice1mi
+ice1ne
+icen1
+ice1sc
+ic1haf
+i1chak
+i1change
+i1cha2p
+i1chenb
+ichen1
+ichenschaf1
+i1cherr
+ichi1el
+ichi1er.
+ichori1
+icht1emi
+ichtschaf1
+icht1sc
+ici1ers
+ic1kat1
+icki1er
+ickv1e
+icus1
+1i1dae
+i1dam
+ideal1
+1id1ee.
+i1dee
+i1def
+ide1h
+ide1lad
+ide1lag
+ide1lan
+ide1las
+ide1lau
+ide1lei
+ide1let
+ide1lie
+ide1lin
+ide1lo
+i1de1lä
+id1e1ma
+id1eme
+ide1mit
+i1d1emi
+i1de1mu
+i1denk
+ide1rec
+id1e1reg
+ide1rest
+ide1rie
+iderm1
+ide1rö
+iderös1
+ide1sa
+ide1sc
+ide1se
+i1de1si
+ide1so
+ide1s2p
+ide1sse
+ide1st
+idev1e
+id1i1e1h
+1i1dio
+idni1s
+i1dr
+idre1so
+idritt1
+i1drit
+idsd1
+ids1tub1
+ids1tur
+i1du
+idungs1
+idv1e
+1idy
+i1dü
+1ie'
+i1ea.
+iealb1
+iea1ll
+ieb1ein
+ie1bei
+ieb1en
+ieb1ess
+ieb1esta
+ieb1estä
+i1e1bi.
+i1ec.
+i1eci
+i1ect
+1ie1d.
+1ie1da
+1iedeh
+1iede1m
+1ieden
+1iederh1old
+1iedermay
+1iederste
+1iedes
+i1e1dit
+ie1di
+1iedl
+1iedm1
+i2ee.
+ieeb1
+1ie1fel
+1iefä
+1ieg
+i1e1ga.
+i1egas
+i1egat
+ieg1ell
+ieg1elo
+ieg1en
+ieg1erin
+ie1geri
+ieg1ero
+ieg1esh
+ieg1ess
+ieg1est2r
+ieges2t
+i1egi1e
+iegs1c
+iegs1ta
+iegs1t2r
+1ie1h
+iehdun1
+i1ei.
+i1einb
+i1einr
+i1eis
+i1eki.
+i1ekå
+ie1lberge
+ielb1erg
+iellau1
+i1e1lls
+i1e1lly
+iel1lä
+ie1lman.
+i1elon
+ielv1e
+ie1mal
+i1emn
+i1e1my
+ien1
+i1enag
+ien2a
+i1enal
+i1enar
+i1enau
+i1enbl
+i1enbr
+i1enbu
+i1enbü
+i1endr
+i1enef
+i1en1ex
+i1enfr
+i1enfä
+i1enfü
+i1engl
+i1engu
+i1enhe
+i1enhu
+i1enhy
+i1enhä
+i1enj
+i1enka
+ien1kau1
+i1enke
+i1enkl
+i1enkr
+i1enku
+i1en1kü
+i1enla
+i1enlo
+i1enme
+i1enmi
+i1enmo
+i1enmü
+i1en1n2a
+i1en1ni
+i1enof
+ien2o
+i1enph
+ien2p
+i1enpl
+i1enpo
+i1enpr
+i1enpä
+i1enq
+i1ensa
+i1ensi
+ienslan1
+i1ensl
+i1enstel
+i1e2nsu
+i1ensz
+i1ensä
+i1en1ti
+i1ent2r
+i1en1tu
+i1enur
+ien2u
+i1enus
+i1envi
+i1envo
+i1enwa
+i1enwe
+i1enwi
+i1enwä
+i1enzi
+i1enzo
+i1enzu
+i1enzw
+i1enzä
+i1enü
+ieob1
+1ie2p
+ie1rac
+iera1ll
+ie1rbac
+ierbänd1
+ier1bä
+ierdun1
+i1erea
+i1eree
+i1ere1is.
+iere1sc
+iere1ss
+iere1st
+i1erew
+i1er1feu
+ierg1eni
+i2ergs
+ierhof1
+i1eria
+i1erib1
+i1erif
+ie1ring
+i1erkac
+ierkau1
+i1erlog
+i1eron
+i1erot
+i1erou
+iersa1me
+ierschaf1
+ierseh1
+ie1rsem
+iers1o
+iers1ton
+iers1tres
+ierst2r
+iertrich1
+iert2r
+i1erus
+ierzun1
+ie1s'
+ie1sa2p
+ie1sbe
+ie1sbl
+ie1sch
+i1esco
+ie1scr
+ie1sec
+2ieseh
+ie1sel
+ie1seng
+ie1serl
+ie1serz
+ie1sfa
+ie1sfe
+ie1sfi
+ie1sfl
+ie1sg
+ie1sh
+ie1sig
+ie1sin
+ie1sj
+ie1skö
+ie1sle
+ie1sli
+ie1smu
+ie1sn
+2ieso
+ie1s2p
+ies1see
+ie1ssi
+ies1s1or
+ies1sta
+ies1tal
+ie1ste
+ie1sti
+i1e1stin
+ie1st2r
+ie1stü
+ie1sv
+ie1sw
+ie1sz
+ie1sä
+i1eta.
+ietal1
+i1etar
+i1etat
+ieteg1
+i1eti.
+i1eto.
+i1etoo
+i1etraf
+iet2r
+i1etral
+i1etram
+i1etra2p
+i1etros
+i1etti
+i1ety.
+i1etät1
+i1eu.
+i1eus
+iev1e
+i1evi.
+i1evo.
+i1ew.
+i1ewic
+i1ews
+ifall1
+i1fal
+ifalls1
+ifeg1
+ife1la
+i1fel
+ife1li
+ifen1
+ifi1er.
+i1fie
+1ifik
+ifing1
+ifoli1
+iftee1
+ift1ele
+igali1
+ig1a1ru
+ige1b1ea
+ig1eck
+i1gefl
+i1gefü
+ig1ehen1
+i1gehe
+ig1eher
+ige1hu
+ige1los
+i1gelä
+ige1ma
+i1geme
+i1gemi
+i1gemü
+ig1en
+i1gendr
+ig2eneg
+i1genfo
+igeni1e
+ig2enom
+igen2o
+i1geor
+ige1ras
+ig1erem
+ig1eren
+ig1eres
+i1geric
+ig1erin
+ig1erun
+i1gesc
+i1gese
+ige1si
+ige1ss
+ige1s2t
+igev1e
+ig1g1ehe
+igg1en2a
+ig1g1erud
+iggs1
+iglas1t
+i1glei
+igli1e.
+igli1er
+igob1
+i1graf
+igs1t1ee
+igs1tig
+igs1tor
+igs1treu
+igst2r
+2igt
+igungs1
+ihe1h
+iheits1
+ihe1ma
+ihi1er
+ihint1
+ihke1
+ih1ne.
+ihot1
+ih1ra
+ih1rg
+ih1rin
+ih1ro
+ih1rs
+ih1rz
+ih1rü
+ihun1d
+ihäs1
+ihös1
+iib1
+iichau1
+iie1
+ii1e.
+i1i1e1h
+ii1gi
+1iii
+iii1e1
+1i1iii1
+ii1n2a
+ii1ne
+ijea1
+1ijsb
+ika1lak
+ika1los
+i1kans
+ikape1
+ika2p
+ik1a1rei
+ikari1e
+ik1ari
+ika1rot
+ik1aro1
+ike1sh
+ike1st
+iki1en1
+iking1
+iklan1
+ikla1s
+ikleg1
+iklän1
+ikm1al1
+1ikone
+ikrü1
+iksb1
+ikschaf1t
+ikt1eb
+ikt1er
+iktrich1
+ikt2r
+iktv1
+iku1m1
+ikv1e
+ilan1ge
+ilat1es
+ilau1f.
+ilau1fb
+ilau1ff
+ilau1f2p
+ilaus1
+ilbrech1
+ileb1
+ilee1
+ileg1en
+ile1ha
+ile1her
+ile1i.
+ile1li
+ile1ll
+ile1ma
+ile1mm
+ile1nam
+ilen1
+ilen2a
+ile1sh
+ile1st
+ile1us
+ilfe1i
+ilfe1m
+ili1eri
+ili2n
+i1lla
+il1lam2p
+illau1
+illd1
+i1lleb
+i1llef
+il1lege.
+il1leg1en
+il1legs
+i1llem
+i1lle1nac
+illen1
+illen2a
+i1llenb
+i1llend
+i1lleni
+i1ller
+i1lles
+ille1sc
+i1llet
+i1llh
+i1llib1
+i1llic
+i1llie
+i1lli1er.
+i1llif
+i1llin
+i1llis
+il1liste.
+i1llit
+i1llke
+i1llm
+i1lln
+i1llo
+i1llr
+i1ll1so
+i1llstä
+ill1st
+i1llt'
+i1llu
+i1llw
+i1lly
+i2l1län
+il1löc
+i1llü
+ilon2a1
+ilon1i1
+ilse1l
+il1se
+ils1tag
+il1st
+ilungs1
+ilv1e
+ilz1ug
+1imagin
+im1ale
+im1als
+imee1
+ime1lin
+ime1ll
+ime1rat
+im1era
+ime1sh
+ime1st
+imeta1
+im1g1ehe
+imi1el
+imi1r
+imi1t.
+imi1tat
+i1mi1tb
+imi1te
+imi1ti
+imi1t2r
+imi1ts
+imob1
+im1oi1
+1impor
+im2p
+ims1tal
+imv1e
+imä1
+imös1
+1inabh
+in2a
+i1nahe
+i1nahm
+inakt1
+inal1li
+inaus1
+inavi1
+inazisti1
+inaz1
+1ince
+in1da
+in1db
+in1de
+inde1sc
+1index
+in1dh
+in1di
+1in1div1
+in1dl
+1in1dok
+in1dr
+in1du
+1indust
+in1dus
+in1dy
+ine1igel
+in1ei
+ine1i1sc
+ine1lab1
+in1el
+ine1lan
+ine1lec
+ine1lei
+ine1lin
+ine1ll
+ine1man
+in1em
+ine1mar
+ine1me
+ine1mi
+ine1mo
+ine1nabe
+in1en1
+inen2a
+ine1nac
+ine1nas
+in1e1rasi
+in1er
+inere1u
+ine1rol
+ine1ros
+ine1rot
+ine1s1ei
+in1es
+ine1sek
+ine1ska
+ine1sl
+ine1so
+ine1s2p
+ine1ssk
+ine1sth
+ine1st2r
+ine1su
+i1netz
+in1et
+ine1uf
+ine1unt
+ine1us
+i1neut
+infall1s
+in1fal
+1inf1ark
+1infek
+1infiz
+1info1rc
+1infusi
+ing1eck
+in1gec
+ing1ell
+in1gel
+ing1eman.
+in1gema
+ing1emans
+ing1enie
+in1gh
+in1gi
+ingi1er.
+in1gm
+in1go
+ingsa1m
+ingstref1
+ingst2r
+ings1tric
+1inhaltes
+1inhaltete
+in1i
+ini1e.
+ini1el
+ini1eri
+ini1ern
+ini1ers.
+ini1erv
+ini1ew
+inigg1
+ini1gr
+i1nimm1
+inings1
+i1ni2p2p
+ini2p
+ini1sc
+1initi
+1ink1arn
+in1kau1
+i1nly
+in1m1alen1
+1innere
+inn1er
+1inseln
+ins1og
+ins1tis
+ins1trai1
+inst2r
+ins1tät1
+1in1tab
+i1n1tai1
+intb1
+1integ1
+int1er.
+int1era
+int1erb
+int1erc
+int1erd
+int1ere.
+int1erei
+int1erf
+int1erg
+int1erh
+int1eri
+int1erk
+int1erl
+int1erm
+1int1ern
+int1ero
+int1er2p
+int1erq
+int1err
+int1ers
+int1ert
+int1eru
+1int1erv
+int1erw
+int1erz
+int1e1ss
+inti1e.
+in1ti
+1intol
+in1to
+i1ntoo
+intrich1
+int2r
+1introd
+intv1
+intwei1
+i1nud
+in2u
+i1numm
+inu1m
+i1nunc
+inungs1
+inv1e
+1invent
+inven1
+1inves
+inzu1r
+i1näh1m
+inöl1
+i1obs1
+io1chi1
+ioint1
+i1oi
+iole1m
+i1ole
+ionag2
+ion2a
+iopi1er
+i1o2p
+io1rea
+io1rez
+i1o1ros
+io1rä
+io1rö
+ioseri1
+ios1o.
+ip1ari1
+i2p
+ipe1li
+ipi1ei
+ipi1e1l
+ipi1ge
+ipi1ne
+iplom1
+ippe1i
+ip2p
+i2ps1t1o2p
+ips1tre
+ipst2r
+i1ra
+irai1
+ira1lag
+irande1
+irani1
+i1rb
+i1rc
+irchschla1
+i1re
+ire1la
+ire1ma
+ire1sa
+ire1sch
+ire1sen
+ire1ses
+ire1ss
+ire1st
+ire1uf
+i1rf
+irg1el
+irgg1
+irgs1c
+irgs1te
+i1rh
+irha1b
+i1ri
+iri1en1
+iri1er.
+iri1eri
+iri1ern
+iri1ez
+iris1st
+i1rj
+irks1c
+i1rl
+i1rm
+irma1l
+i1rn
+irni1s
+i1ro
+i1r2p
+i1rr
+1irrb
+1irre
+1irrs
+1irrt
+i1rsa
+irsb1
+i1rsc
+i1rse.
+i1rsi
+i1rsk
+i1rso
+i1rst2r
+i1rt.
+i1rta
+i1rtb
+i1rtd
+i1rte
+irt1ee1
+i1rth
+i1rti
+i1rtl
+i1rts.
+i1rtsa
+i1rtsb
+i1rtse
+i1rtsf
+i1rtsg
+i1rtsh
+i1rtsk
+i1rtsl
+i1rtsm
+i1rt1so
+i1rts2p
+i1rtsr
+i1rts1s
+i1rtst
+irt1s1ti
+i1rtsv
+i1rtsw
+i1rtsz
+i1rtu
+irtv1
+i1rtz
+i1ru
+irun1d
+i1rv
+irv1e
+i1rw
+i1ry
+i1rz
+i1rá
+i1rä
+i1rò
+i1ró
+irös1
+i1rü
+i1s'
+i1sa.
+i1sag
+isa1g.
+isa1ge
+i1sai
+isa1los
+isa1mm
+isa1ms1
+isa1mt
+i1sce
+ischaf1
+is1chia.
+ischrif1t2r
+i1s1chy
+i1scl
+i1scr
+i1see
+ise1ha
+ise1ho
+ise1hu
+is1ei
+i1se1id
+ise1ik
+is1e1inf
+i1sek
+i1sel.
+ise1lan
+ise1leb
+ise1lei
+i1seler
+i1self
+ise1lis
+ise1lit
+ise1lle
+ise1lls
+i1seln
+ise1lot
+iselv1
+i1selw
+i1selz
+ise1mas
+i1seme
+ise1mei
+ise1men1
+ise1mis
+ise1nat
+is1en2a
+isen1t
+ise1rec
+ise1reg
+ise1reig
+ise1re2p
+ise1rest
+ise1rü
+ise1sa
+ise1se
+ise1s2p
+i1sfle
+i1sgal
+isg1eni
+ishof1
+i1si.
+i1sie
+i1si1ec
+1isier
+isi1eri
+i1sim
+i1sio
+i1siq
+i1sit
+i1sjä
+i1sker
+i1skä
+i1skö
+islam1
+isleg1
+1i1sm.
+ism1al
+i1smans
+i1sme.
+i1smá
+is1o.
+is1ob1
+is1og
+i1s1ol
+i1s1on
+i1s1os
+is1ou
+is1ow2
+i1spu
+is2p
+i1spä
+i1srö
+is1saa1
+i1ssal
+is1salo
+i1ssan
+i1ssar
+i1ssau
+i1ssber
+i1ssbo
+isschaf1
+is1scho
+i1sscl
+i1ssd
+i1ssek
+i1ssel
+is1senke
+issen1
+is1senku
+i1ssf
+i1ssg
+i1ssho
+i1ssig
+i1ssin
+i1ssj
+i1sske
+i1sskl
+i1sskn
+i1ssko
+i1sskr
+i1ssku
+i1sskä
+i1sskö
+i1sslo
+i1ssm
+i1ssne
+i1sso
+is1sp1ark
+iss2p
+is1spen1
+i1sspf
+i1ssph
+i1ssq
+i1ssr
+i1sste.
+i1sst1en1
+i1sst1er
+i1sstes
+i1ssto
+i2s1stol
+is1stäu
+i1ssu1m
+i1ssun
+i1ssv
+i1ssw
+i1ssä
+is1sän
+i1sta.
+is1take
+i1stan
+i1star
+is1tasc
+is1tauc
+i1st1ea
+is1t1eam1
+is1t1ee
+i2s1t1eil1
+ist1ei
+iste1ll.
+is1teller
+iste1me
+i1ste1mm
+i1st1en1
+istenfall1
+isten1fal
+i1stet
+i1stg
+isti1en1
+i1stig
+i1stim
+i1stin
+is1ti2p
+i1stk
+i1stm
+is1t1oa
+i1stoc
+i1stof
+is1too
+i1st2p
+is1trai1
+ist2r
+is1treu
+is1trut
+istv1e
+i1stw
+i1sty
+i1stz
+i1stän
+i1stö
+i1stüc
+is1tüm
+is1tüte
+i2su1m
+i1sy
+i1sö
+i1sł
+i1t'r
+i1ta.
+i1ta1bz
+i1tai1
+i1taka
+itakt1
+i1tan.
+i1tane
+i1tani
+i1tar.
+itari1e
+it1ari
+i1t1arm
+i1t1aro
+i1tas.
+i1tasc
+i1tat.
+i1tate
+i1ta1to
+i1tats
+i1tatt
+i1tau.
+i1tauc
+i1taug
+i1tav
+i1tax
+i1tblö
+i1t1bö
+i1tche
+i1tchu
+itd1e
+i1t1dom
+i1tea
+i1tec
+i1ted
+i1tee
+it1eet
+i1teh
+i1t1eil
+it1eis
+i1t1el.
+it1elau
+it1elb
+it1ele.
+it1elf
+it1elh
+it1elk
+it1elm
+it1eln
+it1elo
+it1el2p
+it1elr
+i1t1els
+it1elt
+it1elu
+it1elv
+it1elw
+it1elz
+it1elü
+i1tema
+it2enim
+it1en1
+it1er
+itere1ss
+iteri1e1l
+i2terl
+iterm1al
+i1t1esm
+ite1ss
+itetra1
+itet2r
+it1even1
+i1t1exk
+it1ex2p
+itfall1
+it1fal
+i1t1fam
+i1tfar
+i1tford
+i1t1glü
+i1tgü
+i1th.
+i1thaa1
+i1thöc
+i1ti.
+i1tic
+i1tide
+iti1el
+iti1en1
+iti1ern
+iti1ga
+i1til
+i1ti2p
+i1tis.
+i1tit1
+i1tiv1
+i1tiw
+i1tić
+i1tja.
+i1tjan
+i1tjas
+i1tjü
+i1tka.
+i1tklü
+i1tlek
+i1tlet
+i1tli.
+i1tlig
+i1tlm1
+i1t1mäc
+i1to.
+itob1
+i1t1obe
+i1toc
+itoe1
+i1toh
+i1tol
+i1tom
+i1ton
+i1tor.
+i1tors
+i1tose
+i1tot
+i1t1our
+i1tpal
+it2p
+i1tra.
+it2r
+i1trac
+i1tradi
+i1trai
+i1tral
+i1tren.
+i1tret
+i1trick
+itri1e.
+itri1ew
+i1tro.
+i1trog
+i1tr1o2p
+i1trov
+i1trow
+i1try
+itsa1g
+it1ski1
+its1taf
+its1t1ea
+it1ste
+its1t1ee
+its1tes
+its1tol
+it1sto
+its1ton
+its1träu
+it1st2r
+its1tur
+i1t1sym
+it1sy
+i1tt.
+i1tt'
+i1tta2p
+it1ta
+i1tte.
+i1ttee
+i1tt1en1
+i1tte2p
+i1tterm
+itt1er
+i1ttet
+i1tteu
+i1tt1ev1
+i1ttin
+i1ttis
+i1tts
+i1ttäg1
+i1tuna.
+itun2a1
+itungs1
+ituri1e
+i1turm
+i1turn
+i1tus
+itus1t
+itut2s1
+itv1e
+i1twaf
+i1tw1ag
+i1twic
+1ity.
+itzi1en1
+it1zman
+i1tzwas
+i1tzwo
+i1tã
+i1täg1
+i1täl
+itäts1c
+i1täu
+i1té
+i1tür
+iug1
+iumv1
+iu1m
+iungs1
+iurg1
+iusa1
+ius1o
+ius1sc
+ius1st
+ius1ta
+iv1e
+ive1ll
+ive1nac
+iven1
+iven2a
+ive1n1es
+ive1se
+ivial1
+ivi1en1
+ivo1n
+ivo1r.
+iw1a
+iwa1r.
+iwei1s.
+iwäg1
+izei1ne
+iz2e
+ize1ll
+ize1ma
+ize1mi
+ize1sh
+izi1e1ll
+izi1en1
+izi1erg
+izi1ern
+izi1err
+izob1
+izt1er
+izv1e
+izwei2
+izz1ut
+izöl1
+ißint1
+iäs1
+ièt1
+jaa1n
+jab1er
+jade1l
+jade1ri
+jae1n1
+jagi1
+jahrs1
+j2ahr
+jai1
+ja1ll
+ja1m1a
+ja1mb1
+jami1t
+jand1
+janvi1
+ja1nü
+ja1reg
+ja1ruf
+j1aru
+jas1th
+jau1
+jaub1
+jauche1r
+jav1
+javi1
+jb1
+jci1
+jea1l
+jea1n'
+jea1nie
+j1eani
+jea1ns
+jee1
+jeg1
+je1hab
+je1hun
+je1hö
+je1lac
+je1lad
+je1las
+je1ler
+je1lit
+je1ll
+jelo1
+je1lä
+je1mac
+je1mals
+je1mei
+je1mes
+je1mm
+je1mü
+je1nau
+jen2a
+je1nie
+je1nom
+jen2o
+je1nos
+jen1t
+je1nus
+jen2u
+je1rad
+je1rau
+je1rec
+je1ret
+je1richt
+jeroe1
+je1ruf
+je1rä
+je1sac
+je1sam
+je1sch
+je1seh
+je1se1l
+j1e1shu
+je1sic
+je1s1of
+je1spen1
+jes2p
+je1ss
+je1ste
+je1sti
+je1sto
+je1stä
+jev1
+jevo1
+jewe1g1
+jeword1
+jg1er
+jhof1
+jib1
+jibb1
+ji1e.
+ji1ef
+jing1
+jm1
+jmeg1
+jmi1
+jners1
+jn1er
+jne1st
+jn1es
+joa1ne
+j1oa
+joa1ns
+joa1r
+j1oe1r
+j1oe1s
+joi1n
+j1oi
+jojo1
+j1oj
+jons1t
+jophi1
+j1o2p
+josb1
+j1oub1
+jouti1
+js1o
+jstet1
+jtb1
+jt1es
+jub1
+judo1
+jue1n1
+jue1r
+jug1
+juli1er
+juli1n
+ju1m1
+jun1
+jung1en
+jura1
+jurab1
+jura1ssi1
+juri1e.
+jus1o
+jwi1
+jyl1la
+jz1
+jäg1
+jät1er
+jæg1
+jæl1
+jörg1
+jørg1
+jüne1
+jürg1
+kaa1ns
+kabb1
+kabi1e
+kade1l
+kae1li
+kae1m
+kae1n1
+kai1g
+kai1n2o
+1kaj
+ka1leu
+ka1lic
+kali1e.
+ka1lle
+ka1llh
+ka1llm
+ka1lln
+ka1lls
+ka1llt
+ka1llu
+kalmani1
+ka1lö
+ka1m1a
+ka1mb1
+kameli1e
+ka1mel
+kam1mac
+ka1mma
+kanal1
+kan2a
+kand1
+kanit1
+ka1ref
+ka1re2p
+karg1er
+k1arg
+kari1e.
+k1ari
+kari1es
+k1aro1
+karri1
+k1arr
+kas1e1i
+ka1ssi1e.
+ka1ssi
+kaste1ll
+ka1stel
+kat1er
+katm1
+katri2
+ka1t2r
+kau1f.
+kau1fh
+kau1fku
+kau1fle
+kau1fli
+kau1fm
+kau1f2p
+kaufreun1
+kau1freu
+kau1frä
+kau1fsa
+kau1fs2p
+kaufs1tem
+ka1und
+kau2n
+kazi1e
+kaz1u
+k1b1ee
+kb1ein
+kb1enz
+kb1erg
+kb1err
+kb1ert
+kb1eu
+kb1oa1
+k1brü1
+kbänd1
+k1bä
+kd1e
+kdea1
+kdeg1
+kdun1
+kdös1
+kea1l
+k1ea1ne
+keaus1
+ke1b1ei
+keb1en
+kedg1
+kee1l
+keelun1
+kee1lu
+kee1n1
+kee1r
+kee1s
+ke1ha
+ke1hea
+ke1hel
+ke1her
+ke1ho
+kehrich1
+keh1ric
+kehrsat1
+ke1hu
+ke1hä
+ke1hö
+ke1hü
+keis1s
+keit1
+kei1ta
+kei1to
+keits1
+kei1tu
+keks1
+ke1land1
+1keldey
+ke1lev
+ke1lief
+ke1lis
+ke1ll.
+kellau1
+ke1llb
+ke1lle
+ke2llenk
+kellen1
+ke1lln
+ke1lls
+kellun1
+ke1lly
+ke1loc
+ke1los
+ke1lot
+kelv1e
+ke1mac
+ke1man
+ke1mas
+ke1mat
+kemb1
+ke1mei
+ke1mes
+ke1mm
+ke1mol
+ke1mun
+ke1mä
+ke1möl1
+ken1
+1kendri
+k1e1new
+kenhaus1
+kens1tag
+kens1tat.
+kens1t1rau1m
+kenst2r
+kenw1a
+kera1ll
+ke1rea
+ke1reg
+ke1reic
+ke1renn
+kere1ss
+ke1rest
+kerg1en
+kermi1t
+kerob1
+1kersh
+kersle1b
+kers1o
+ke1run1d
+kerv1e
+ke1sag1
+ke1sau
+ke1sc
+ke1see
+ke1ser
+ke1she
+ke1shi
+ke1si
+ke1s1oc
+ke1s1or
+ke1spi
+kes2p
+ke1spr
+ke1ssa
+ke1sse
+ke1ssh
+ke1ssi
+ke1ssl
+ke1st1ei
+ke1stem
+ke1st1er
+ke1stes
+ke1st1eu
+ke1st2r
+ke1stä
+ke1stü
+ke1su
+kesv1
+ke1sä
+ketv1
+ke1u1m
+ke1u2p
+ke1us.
+kev1e
+kfall1
+k1fal
+kfe1ll
+k1fel
+kfoli1
+kfun1
+kge1b1ea
+kg1ehen1
+k1gehe
+kg1ei
+kg1eni
+kg1enr
+kg1eu
+kglas1
+kha1ts
+khau1
+khaus1
+khee1
+kheits1
+khe1ll
+khi1er
+khint1
+khof1
+kh1ofs1
+khot1
+khun1
+khäs1c
+kia1l
+kibb1
+kibun1
+ki1ego
+k1ieg
+kie1ll
+ki1ella
+kiel1li
+ki1erf
+ki1ers.
+ki1ersa
+ki1ersb
+ki1ersf
+ki1ersg
+ki1ersk
+ki1ers2p
+ki1erss
+ki1ersv
+ki1erv
+kie1s
+kies1sa
+kies1st
+ki1et.
+ki1ety
+ki1ev
+1kiew
+ki1ewer
+ki1ewi
+ki1ex
+ki1gel
+ki1glä
+ki1gr
+ki1gä
+1kij
+kilau1
+kilb1
+kilo1
+kimb1
+ki1nat
+kin2a
+kinde1le
+kin1de
+kindv1
+kinni1e
+kin1ni
+1kin1n2o
+kin2o1
+kirg1
+k1irre1
+ki1rr
+kis1st
+kitt1el
+kiwi1
+kiz1
+kka1re
+kkau1
+kkitt1
+kkla1s
+kkle1b
+kklän1
+kko1re
+kkrü1
+klaa1
+klae1
+klan1gs
+klasse1r
+klas1s1o
+klau1
+klaub1
+klb1
+kle1b.
+kle1bb
+kle1bl
+kle1br
+kle1bs
+kle1bt
+kle1bu
+klecks1c
+klee1
+kleg1en
+kleri1e
+kle1us
+klili1
+klima1
+klin1g1el
+klivi1
+klän1g.
+kläus1
+klüb1
+kmal1
+kmani1
+km1arg1
+kmus1tes
+kmu1ste
+knabb1
+kn2a
+knag1
+kna1l
+knau1
+kneb1
+kne1ll
+kn1el
+kne1n2a
+kn1en1
+kne1st
+kn1es
+knev1
+kni1sc
+kni1s2p
+kni1st
+knob1
+kn2o
+knoe1
+koda1c
+k1od1e
+kode1n
+kodil1
+k1odi
+koffe1i
+k1olb1
+k2omi1t
+ko1mi
+1kons
+kont1er
+kopb1
+k1o2p
+korb1
+ko1ref
+ko1rev
+ko1rez
+korgi1
+korm1
+korsa1g
+korv1
+kos1e1n2a
+kosen1
+kos1sc
+kos1se
+kos1sh
+kos1st
+kos1te2p
+k1ost
+1k1ova
+koz1un
+kpe1s
+k2p
+kpit1
+kp1oi1
+kpri2
+kprämi1
+krabb1
+kra1ll
+krang1
+kre1bs1c
+kreg1
+kr1e1ier
+kreli1e
+kre1ss
+kre1st
+krich1t.
+kri1ens
+krien1
+krift1
+kri1ga
+krin1g1el
+kritt1
+kro1
+kr1oe1s
+krole1in
+kr1ole
+krue1
+krun1
+kränd1
+ksal1s1t
+ksa1mt
+ksatt1
+ksauri1
+kseb1
+kseh1
+ks1ei
+kse1ll
+ksen1
+kseri1e
+ksfall1
+ks1fal
+ksg1ene
+kski1e
+1kskrant
+ksleg1
+ksm1al
+ks1o.
+ksob1
+ks1od
+ks1of
+ks1on
+ks1os
+ks1ou
+ks1oz
+ks1s
+ksseri1
+ks1tabl
+ks1taf
+ks1tale
+ks1tanz
+ks1tat.
+ks1tau1m
+ks1tausc
+ks1tax
+ks1t1eam1
+kst1ea
+ks1t1ee
+k2s1t1eil1
+kst1ei
+ks1tend
+kst1en1
+ks1term
+kst1er
+ks1terr
+ks1tis
+ks1tit
+ks1t1oa
+ks1tod
+ks1tor.
+ks1tot
+ks1tow
+ks1trad
+kst2r
+ks1tres
+ks1trib
+ks1tril
+ks1tul
+ks1tus
+ks1töl
+ks1tüm
+ks1tüte
+ksäng1
+ktae1
+k1tags1
+ktail1
+kta1ll
+ktd1e
+kt1e1di
+kt1eet
+kt1ef
+kte1h
+kt1ei
+kt1ele
+kt1eln
+kt1elo
+kt1elt
+kt1ema
+kte1mac
+kt1erc
+kt1erem
+kt1erer.
+kt1eres
+kte1ric
+kt1eri1e
+kterie1l
+kt1ersu
+kterz1
+kte1sa
+kte1sc
+kte1s2p
+kte1st
+kt1eu
+ktev1
+ktfall1
+kt1fal
+kthi1e
+kti1e.
+kti1en1
+ktob1
+ktral1
+kt2r
+ktro1
+ktsa1m
+kts1trun1
+kt1st2r
+ktt1el
+k1tus
+kubun1
+kug1
+kulec1
+kun1d
+kun1ga
+kuni1g
+kunt1er.
+kuri1e.
+kurs1tu
+kurv1
+kuseri1
+kus1sc
+kus1sek
+kus1sens
+ku1ssen1
+ku1s1set
+kus1son
+ku1sso
+kus1t1ee
+ku1ste
+kus1tor
+kut1ei
+kuwei1
+kvee1
+kv1erb
+kv1erd
+kv1ere
+kv1erf
+kv1erg
+kv1erha
+kv1erk
+kv1erl
+kv1erm
+kv1ern
+kv1er2p
+kv1err
+kv1ers
+kv1ert
+kv1erw
+kv1erz
+kv1erä
+kw1ar
+kw1ie
+kwä1
+kyfa1
+kylb1
+1ky2p
+kyri1
+kyrie1
+kz1uges
+1ká
+käi1
+kä1rg1
+käs1chen1
+käse1l
+käs1st
+käs1tu
+köt1
+kött1
+küg1
+kümb1
+küre1i
+kütt1
+laa1c
+laa1rt
+lab1ela
+la1bel
+lab1er
+1labor.
+la1bo
+1labors
+la1brü1
+la1br
+labs1o
+la1chi2p
+lade1re
+1ladew
+ladi1er
+1ladu
+1lady
+lae1nd
+laen1
+lae1s.
+lafe2
+lag1erei
+lag1eres
+la1gerin
+lag1erun
+lag1erän
+la1gerä
+lage1sc
+lage1s2t
+la1gsdo
+la1gst2r
+laha1t
+lai1
+1laib1
+laig1
+lain1i2
+la1la1l
+la1lau
+la1law1
+la1ll
+la1los
+la1lö
+la1me1l
+lami1g
+lami1t.
+la1mts1
+land1
+1lan1dai
+1landau
+1landf
+1lan2dh
+landi1e
+1landrä
+1landsc
+1landu
+lang1ebe
+lan1geb
+lan1ge1h
+1langem
+langenma1l
+lan1g1enm
+1langw
+la1nov
+lan2o
+lanti1e.
+lan1ti
+lanti1g
+lan1z1u
+lappschaf1
+la2p
+lap2p
+la1reu
+la1riv
+l1ari
+2l1arm
+la1rob1
+l1aro
+las1see
+lassisti1
+la1ssi
+la1ssis
+las1sto
+las1st2r
+las1tas
+la1sta
+la2s1t1eil1
+last1ei
+la1s1tel
+las1t1em2p
+1last1er
+las1tier
+la1stie
+las1tor
+las1tub1
+las1tur
+latal1
+la1ta
+lat1eau
+lat1el
+lat1em
+lat1er
+latsa1m
+la1tv1
+1laub.
+lau1fa
+lau1fm
+lau1fpl
+lauf2p
+lau1fs.
+laulun1
+1laura
+1laute
+1laut2s
+lav1a1ro
+lavo1r.
+law1
+laz1u
+lbb1ei
+lb1eat
+l1bea
+lbeb1
+lb1ebe
+lb1eer
+l1bee
+lb2eerd
+lb1ei.
+lb1eia
+lb1eib
+lb1eic
+lb1eid
+lb1eif
+lb1eig
+lb1ein
+lb1ei2p
+lb1eita
+lb1eite
+lb1eito
+lb1eiz
+l1be1ll
+lb1enb
+lb1enf
+lb1eng
+lb1enh
+lb1enk
+lb1enm
+lb1enn
+lb1en2p
+lb1enr
+lb1ens
+lb1en1t
+lb1env
+lb1enw
+lb1enz
+lb1enä
+lb1er.
+lb1eran
+lb1erb
+lb1erc
+lb1erd
+lb1ere.
+lb1eres
+lb1erf
+lb1erg
+lb1erh
+lb1eris
+lb1erk
+lb1erl
+lb1erm
+lb1ern
+lb1ero
+lb1er2p
+lb1err
+lb1ers
+lberschaf1
+lb1ert
+lb1erun
+lb1erw
+lb1erz
+lb1esel
+lb1esen
+lb1etag
+lb1eta2p
+lb1ex
+lbing1
+lbi1s
+lbla1s
+lblei1b.
+lb1oa1
+lbrech1t.
+l1brü1
+lbub1
+lbänd1
+l1bä
+lcat1
+lce1l
+l1cheri
+l1chm
+lchschaf1
+lchtrich1
+lcht2r
+lda1ll
+ldau1f.
+ldbeg1
+ldche2
+lde1leu
+lde1lis
+lde1mac
+ld1ema
+lde1mas
+lde1min
+l1d1emi
+ld1e1mod
+lde1nam
+l1den2a
+ldensle1
+ld1ensl
+lde1rec
+ld1e1reg
+lderm1al
+lde1sat
+lde1sc
+lde1ser
+lde1sk
+lde1st
+ldi1er.
+ldi1ers
+ldm1al
+ldossi1
+l1dos
+ldritt1
+l1drit
+ldrös1
+l1drö
+lds1tag
+ldweb1
+ldz1ug
+ldös1
+lea1l
+lea1nin
+l1eani
+l1ea1ns.
+lea1nse
+lea1ns2p
+1l1e1arn
+le1b's
+leb1enb
+le1b1ene
+leb1eng
+lebens1t
+leb1enz
+leberech1
+le1berec
+le1bes
+lebrech1
+le1bsa1
+led2
+lee1ne
+leen1
+lee1ns.
+leere1ss
+l1ee1re
+lee1s
+legan1
+leg1enb
+leg1end
+leg1enf
+leg1enk
+leg1en2p
+leg1enr
+leg1ens.
+leg1env
+leg1enw
+1legn
+1legt
+1legun
+le1haa1
+le1hal
+le1ham
+le1har
+le1hau
+le1hea
+le1herd
+le1hil
+1lehn
+le1ho
+le1hy
+le1hä
+le1hö
+le1hü
+lei1br
+1leid.
+1leide
+1leids
+l2eim1m
+lei1nam
+lein2a
+le1in1du
+1lein1en1
+lei1nie
+lein1i
+leinsa1m
+leischla1
+lei1sc
+lei1s1st2r
+1leit
+leiti1e
+1lektü
+le1lac
+le1lade
+le1lag1
+le1lam
+le1lau
+l2e1leh
+le1lese
+le1lim
+le1li2p
+lellau1
+le1loc
+le1lot
+le1lou
+le1luk
+le1lä
+le1mac
+le1m1arc
+le1med
+le1mei
+le1m1erl
+le1mes
+le1mme
+le1mmi
+le1mmo
+le1mor.
+le1mors
+le1mus
+lemv1e
+l1emv
+lemä1
+len1
+1l1endc
+le1nerd
+len1er
+le1n1euv
+len1geg1
+lenleg1
+le1note
+len2o
+l1e1nov
+lenslan1
+l1ensl
+lensle1b
+lens1o
+lenti1e.
+len1ti
+l1e1nua
+len2u
+lenw1a
+lenzun1
+l1enzv1
+lepra1
+le2p
+l2e1rad.
+le1rank
+lereb1
+le1rese
+le1rest
+le1rev
+le1rez
+lerg1eni
+le1rid
+le1ring
+l2e1riv
+lerob1
+lersle1b
+lers1on
+le1run1d
+lerv1ord
+le1rän
+leränd1
+l2e1rüc
+le1saa
+le1sac
+le1sah
+le1sal
+le1sa1m
+lesbi1er
+le1scha
+le1sche
+le1schr
+1leseb
+lese1h
+lese1la
+lese1le
+lese1m
+lese1ni
+lese1ring
+le1serv
+le1sex
+lesgi1
+le1shi
+le1sho
+le1sid
+lesi1e
+le1sig
+le1sil
+le1sir
+l1e1skin
+le1s1or
+le1spa
+les2p
+le1spe
+1le1ss.
+le1ssb
+le1sse.
+le1ssen1
+le1ssh
+le1ssi
+le1ssl
+1le1ssn
+le1sso
+le1ste
+le1sti
+le1stra
+lest2r
+le1stre
+le1stru
+le1stu
+le1stä
+le1stü
+1lesun
+lesv1
+le1sä
+leti1ers.
+l1eue2
+le1uf
+le1uma
+leu1m
+le1umö
+le1un1g
+1leutn
+lev1e
+levo1n
+1lexik
+1leß
+lfakt1
+lfall1
+l1fal
+lfe1la
+l1fel
+lfe1le
+lfe1ll
+lfe1ma
+lfe1rat
+lfe1rec
+l1fere
+lfe1se
+lfi1er
+l1fie
+lfleg1
+lfoli1
+lfsa1g
+lfs1tau
+l1fs1t1ea
+lfs1tri
+lfst2r
+l1fs1tru
+l1fs1tät1
+lfts1t
+lfun1d
+lfäng1
+l1ga
+lgeg1end
+lg1ehen1
+l1gehe
+lg1eher
+lg1ei
+lge1in
+lge1la
+lge1li
+lgelun1
+lge1lä
+lge1m
+1lgemuth.
+lge1mu
+lg1en.
+lg1enb
+lg1enc
+lg1end
+lg1en1en1
+lg1en1er
+lg1enf
+lg1eng
+lg1enh
+lg1eni
+lg1enk
+lg1enl
+lg1enm
+lg1enn
+lg1en2p
+lg1enr
+lg1ens
+l1g1ensb
+lg1en1t
+lg1env
+lg1enw
+lg1enz
+lge1rec
+lge1reg
+lg1eren
+lge1rfi
+lg1erf
+lg1eri1e
+lg1erin
+lg1eris
+lgers1s
+lg1ers
+lgeränd1
+l1gerä
+lge1sen
+lge1s2p
+lge1s2t
+lge1sz
+lg1eu
+lgi1en1
+lgi1erg
+lgi1ern
+lgla1s
+lglas1t
+lgras1
+lgs1tra
+lgst2r
+lgs1tre
+lgs1tru
+l1gó
+lhaus1t
+lhea1
+lheb1
+lhee1
+lhe1ll
+lhi1era
+lhint1
+lhun1
+lhäs1
+lhös1
+liab1
+liai1
+libb1
+lib1er
+libi1
+1libre
+lici1er
+lic1ki.
+lic1ky
+lidea1
+1lieb
+lieb1elei
+lieb1er
+lie1b1esc
+lieb1est2r
+1liede
+li1ee
+li1efa
+li1efb
+li1efg
+li1efh
+li1efk
+li1efl
+li1efo
+li1efsc
+li1efw
+1l1ieg
+li1egl
+li1egr
+li1eha
+l1ie1h
+li1ei
+li1eku
+li1el
+li1en1
+li1epi
+l1ie2p
+li1erad
+li1erec
+li1eres
+li1eri.
+li1erli
+li1ers'
+li1ersi
+li1ersl
+li1erti
+li1ertü
+1liesc
+lies1che
+lie1sch
+1liese
+li1eth
+li1ett
+li1eu
+1lieut
+li1ewi
+li1ez.
+1lift
+1ligac
+li1gart
+1ligas
+1ligav
+ligen1fal1
+lig1en
+li1gera
+li1gew
+ligi1er.
+1ligis
+li1git
+ligni1s
+liguri1
+likai1
+1likö
+lila1r
+lili1e.
+lime1l
+lime2s
+limi1t
+limm1
+limunt1
+li1na1t2r
+lin2a
+line1u
+ling1eli
+lin1gel
+ling1en
+ling1ere
+ling1eri
+lingrun1
+1lingu
+1lini1e.
+lin1i
+1lini1en1
+1linse.
+1linsen1
+1lippi
+li2p
+lip2p
+liqui1
+lisa1m
+lischau1fsä
+lis1tag
+lis1th
+li1t2ea
+lit1eli
+litz1
+liu1m1
+lius1t
+livi1er
+1livr
+liz1
+li1zei1t
+liz2e
+ljea1
+ljoe1
+l1kac
+lkai1
+2lkal
+l1kam
+lkani1e
+lkape1
+lka2p
+l1kart
+lkeb1
+l1ken1
+l1kers.
+lke1st
+l1ket
+lkg1en
+l1kh
+lkitt1
+lkke1
+lklan1
+lkla1s
+lkle1b
+l1kli
+lklän1
+l1km
+l1ko
+lkora1
+l1kru
+lks1tag
+lks1ton.
+lks1tra
+lkst2r
+lks1tu1m
+lksv1e
+lkt1er
+lku1m1
+lkurs1
+lkv1
+1ll'a
+1ll'e
+1ll'i
+1ll'o1
+1ll'u
+1lla.
+1lla'
+1llaa
+1llaba
+1lla1bd
+1llabh
+1llabl
+1lla1br
+1lla1bsa
+1llabsc
+1llabs2p
+1lla1bsä
+1lla1bz
+1llaci
+1llacy
+1llada
+1lladi
+1lladl
+1llads
+1llae
+llag1er
+l1lags
+1llain
+llai1
+1llaio
+1llaks
+1llam.
+1llamar
+lla1ma
+1llamm
+1lla1mo
+1llan.
+1llane
+1llanh
+1llani
+1llanj
+1llank
+1llanli
+1llanm
+1llan2o
+1llan2p
+1llans.
+1llansa
+1llansw
+1llansä
+1llan1t.
+1llante
+1llan1tu
+1llantw
+1llan2u
+1llanv
+1llanw
+1llanä
+1llanü
+1llao
+1llapa
+lla2p
+l1lappe
+lla2p2p
+1llappl
+1llapr
+1ll1ari
+llari1e
+1l2l1arm
+lla1ros
+ll1aro
+lla1s
+1llas.
+1llasz
+1llat.
+1lla1ta
+2l1lat1ern
+llat1er
+1llativ1
+1llatm
+1llaun.
+llau2n
+1llauß
+1llav
+1llawe
+llaw1
+1llaz
+1llaí
+llbrech1
+1llcl
+1llcr
+lld1em
+1llds
+lldun1
+1lldä
+1lldö
+1llea.
+1lle1b.
+1lle1ba
+1lle1bo
+1lleg.
+1llega
+lleg1en
+1llegh
+1ll1e1gia
+1llego
+1llegr
+1lle1ha
+lle1her
+2l1lehr
+1llei.
+2l1leib
+1lleil
+lle1i1sc
+l1leist
+2l1leit
+1llej
+1llel.
+1lleli
+1llelo
+1llelu
+1llemag
+lle1mal
+1lleman
+lle1mar
+lle1mau
+1llemb
+1llemo
+1ll1em2p
+1llemä1
+1ll1ena.
+llen1
+llen2a
+1llenac
+1llenbos
+1llen1by
+1llendl
+1ll1enzy
+1llenä
+1lleo
+1lle2p
+1ller'
+1ll1era.
+1llerben
+1llerg1en.
+1llergene
+1llerg1eng
+1llerg1enm
+1llerg1ens
+1llergy
+1lleri.
+1lleria
+1llermai1
+lle1rose
+1llersb
+1llerset
+1llersl
+1llersons
+llers1on
+1llert.
+1llerton
+1lleru2m.
+lleru1m
+1llery
+1ll1erø
+lle1sa
+lle1s1ei
+lle1sek
+1llesh
+lle1sha
+lle1spr
+lles2p
+1lle1sta
+1lleti
+lleti1er.
+1lleto
+1lletti
+1lletu
+l1l1euc
+lle1un
+1lleus
+l1leut
+l1lexi
+1lley
+1llez.
+llfeg1
+1llfö
+1llfüe
+1llg.
+1llg1elb
+1llgrü
+1llgy
+1llgä
+1llgö
+1llh1ard
+1llheim1
+1lli.
+1llia
+llib1
+1llibi1
+1llibl
+1ll1ic.
+1llica
+1llicb
+1llicf
+1llicg
+1lliche
+1llici
+1llicl
+1llics
+1llict
+1llicu
+1llie.
+2l1lieb
+l1lief
+1lli1en1
+1llier.
+lli1er'
+1lliers
+lli1ers.
+lli1et
+l1li1eu
+1lli1ev
+2lliga.
+l1ligam
+1lligå
+1llii
+1llike
+1lliko
+1llimi
+1llin.
+1llin2a
+lli1nan
+1llinc
+1lling
+1llini.
+llin1i
+l1linie
+1llinn
+1llin2o
+2l1linse.
+1llinst
+1llint
+1llin2u
+1llio
+1llips
+lli2p
+1llis.
+1llisa
+1llisc
+1llish
+1llisi
+1llism
+1llisé
+1llit.
+1lliti
+1llits
+1lliu
+1lliv
+1lliw
+1lliè
+1llié
+1llka.
+llkau1
+1llkitteln
+llkitt1
+llkitt1el
+llkrü1
+ll1l
+lllau1
+l1lloo1
+1lllö
+1llman.
+1llmar.
+1llmars
+1llmer
+1llmy
+1llnasho
+lln2a
+1llners
+lln1er
+1llnh
+1llny
+1llnä
+1llo.
+1llo'
+1ll1oa
+llob1
+1ll1obl
+1llof
+l1l1ogo
+1llogr
+l1lohn1
+1llohr
+1ll1oi
+2lloks
+1llom
+1llon.
+1llone
+1llons
+1ll1oo.
+lloo1
+1llopr
+ll1o2p
+lloqui1
+ll1oq
+1llor.
+1llor'
+1llora
+1llorc
+1llore
+1llorg
+1llori
+llo1rit
+1llorn
+1llorq
+1ll1ory
+l1losen1
+l1l1osi
+1llot.
+1llout
+1llow
+1ll1ox
+1ll1oy
+1lloz
+1lloè
+1lloù
+1lloń
+1llpü
+ll2p
+1llr1osa
+1lls'
+llsa1m
+ll1sa
+1llsid
+ll1si
+ll1so
+lls1tag
+ll1st
+1llston
+lls1tor
+1ll1tags1
+llt1ei
+lltrich1
+llt2r
+1llu.
+1lluc
+1lluh
+1llul
+1llumg
+llu1m
+1llumr
+1llunf
+llungs1
+1llurg
+1llurn
+1llus.
+llus1c
+1lluv
+1lluz
+1llvei
+1llvä
+1llvö
+1llwö
+1lly'
+llye1r
+1llyg
+1llyk
+1llyn
+1llyr
+1llys
+llzun1
+1llzw
+1llá
+1llâ
+l1läc
+l1läd
+1llähn
+2llän
+l1läs
+1lläug
+1llè
+1llé
+1llë
+1llí
+1lló
+1llô
+l1löh
+1llø
+1llù
+l1lüc
+1llür
+l1lüs
+1llā
+1ll┊
+lmai1
+lm1ale
+lmati1e
+lmeb1
+lmee1
+lmerg1
+lme1sc
+lme1st
+lmeta1
+lmeti1
+lmi1er.
+lmi1eri
+lmi1ers
+lmint1
+lmi1r
+lmi1to
+lmleg1
+lm1m
+lms1o
+lmus1s
+lmv1e
+lnag1
+ln2a
+lneg1
+lne1ss
+ln1es
+lne1st
+lnirg1
+lni1sc
+lnsa1
+1load
+l1oa
+lobb1
+lob1el
+l1obe
+lob1ese
+1lobos
+l1obo
+1lochk
+1lo1chs
+1lochä
+1locki
+l1odb1
+lo1di1en1
+l1odi
+loe1m
+1logik
+l1ogi
+lohn1
+loi1c
+l1oi
+1lokal1
+lolau1
+lol1lan
+lomg1
+l2omi1t
+lo1mi
+lommi1
+lomä1
+1londo
+1longu
+loni1er.
+lon1i
+loo1
+lo1oi1
+1l1ook
+lo1rei
+lo1rez
+lorgi1
+1lorgn
+lo1rol
+lo1rom
+l1o1rou
+lorv1
+lorz2e1
+lose1h
+1loser
+1loses
+losi1e.
+l1osi
+1losig
+los1o
+los1sag
+los1sch
+los1seg
+los1s1ei
+los1spr
+loss2p
+los1sta
+los1tag
+l1ost
+los1tanz
+los1tic
+los1tob1
+los1tro
+lost2r
+1losun
+l1osu
+lotos1
+1lo1ttl
+lotus1
+1loun1g
+lours1
+l1our
+1loye
+l1oy
+lpe1ll
+l2p
+lpe1ros
+lp1oi1
+lpri2
+lprämi1
+lputt1
+lrai1
+lra1l
+lrei1s1c
+lreli1e
+lre1ss
+lre1st
+lrou1
+lrun1
+lränd1
+lrös1c
+l1sa
+lsaa1
+lsabb1
+lsa1le
+lsa1mm
+lsa1m2p
+lsa1mt
+lsaus1
+l1sb
+ls1chak
+ls1chor.
+ls1chör
+l1sco
+l1sd
+l1se
+ls1ei
+lse1ma
+lsen1
+lseri1e
+l1sf
+lsfall1
+ls1fal
+l1sg
+lsg1ene
+l1sh
+lshof1
+l1si
+l1sj
+l1sk
+lski1e
+l1sl
+lsleg1
+l1sm
+l1sn
+lsob1
+ls1of
+ls1oge
+ls1ol
+ls1on
+ls1os
+ls1ou1
+l1soz
+l1s2p
+l1sr
+l1s1s
+ls2sl
+l1st
+ls1tabl
+ls1tage
+ls1tal.
+ls1tanz.
+ls1tas
+ls1tat.
+ls1tate
+ls1tau1m
+ls1t1eic
+lst1ei
+l2s1t1eil1
+l1ste1mm
+ls1tend
+lst1en1
+ls1tex
+ls1tha
+ls1tho
+ls1tier
+ls1tir
+ls1tis
+ls1tor.
+ls1tor2p
+ls1tot
+ls1tou1
+ls1trac
+lst2r
+ls1tre2p
+ls1trib
+ls1tril
+ls1turme
+ls1täte
+lstät1
+ls1täti
+ls1täu
+ls1türl
+l1su
+l1sun1d
+lsun1ge
+l1sv
+lsv1e
+lsv2erh
+l1sw
+l1sy
+l1sz
+l1sä
+lsäng1
+l1sü
+l1tags1
+lta1ll
+ltati1e
+ltau1flö
+ltaus1s
+lt1eck
+lt1edl
+lte1ha
+lt1el.
+lt1eln
+lt1els
+lt1elt
+lt1elu
+lt1elv
+lt2enas
+lt1en1
+lten2a
+lt1er
+lt2eresi
+lt2er1ieg
+lt2eriem
+lt2ering
+lterma1l
+lters1tic
+lters1toc
+lte1sc
+lt1eser
+lt1esk
+lte1st
+lt1eva
+lt1exa
+l1t1exk
+ltfall1
+lt1fal
+1lth.
+ltha1t
+1lth2p
+lti1eri
+lti1go
+lti1gr
+ltmeta1
+ltoe1
+ltra1l
+lt2r
+ltra1u2n
+lts1tab
+lts1t1ea
+lt1ste
+lts1ton
+lt1sto
+lts1tri
+lt1st2r
+lts1tüt
+ltsv1e
+ltt1el
+ltungs1
+ltät1
+ltäts1
+ltätsau1
+1luc.
+lue1l
+lue1se
+lue1sm
+lues1se
+lue1ss
+1luft
+luga1l
+lug1eb
+lugrun1
+lu1grö1
+lugsa1m
+1luis1
+lumbi1e
+lu1m
+lumgeg1
+lum1ma
+lumni1s
+1lum2p
+1lunc
+lun1d
+1lundv
+lun1ga
+lung1en
+lun1g1enm
+lun1gg
+lun1gl
+lun1gm
+lunke1l
+lun1ti1
+lunv1
+lusi1e
+lus1o
+lus1tin
+lus1tor
+lut1eb
+lut1eg
+luteti1
+luthan1
+luthi1
+luu1
+luvi1
+1luxl
+1luxs
+1luxu
+lvai1
+lvee1
+lv1era
+lv1erb
+lv1erd
+lv1ere
+lv1erf
+lv1erg
+lv1erha
+lv1erhü
+lv1erj
+lv1erk
+lv1erl
+lv1erm
+lv1ern
+lv1ero
+lv1er2p
+lv1err
+lv1ers
+lv1ert
+lv1eru
+lv1erv
+lv1erw
+lv1erz
+lv1erä
+lv1erö
+lvis1t
+lv1ore
+lw1ar
+lwa1r.
+lw1at1
+lweb1
+lwe1ger
+lweib1
+lweide1r
+lwen1
+lyb1
+lyfe1
+1lyh
+lympi1
+lym2p
+1lynn1
+lyv1
+lyäs1
+lza1ll
+lzeb1
+lz2e
+lze1lei
+lze1ll
+lze1st
+lzher1r.
+lzimi1
+lzob1
+lzt1ee
+lz1ugl
+lz1urr
+lzv1e
+lzz1ub
+1läch
+1läde
+1lähm
+läi1
+1läm2p
+länd1
+lände1l
+län1e1m
+länt1
+1lä2p2p
+lä2p
+1läss
+1läuf
+läums1
+läu1m1
+1läut
+1læ
+léb1
+lég1
+1löcher
+lödi2
+löd1
+1löffe
+1lösu
+1löw
+1lüf
+1lüg
+1lüm
+lüme1l
+lüng1
+m'g1
+ma1a1rte
+ma1brü1
+ma1br
+mabänd1
+ma1bä
+1machd
+1mache.
+ma1chem
+1machen1
+1machf
+1machst
+1macht
+1machu
+mac1kenz
+macken1
+mad1
+madelun1
+ma1delu
+maeg1
+mae1n.
+maen1
+1maga
+1magd
+mag1elu
+magelun1
+magg1
+magi1er.
+magi1eri
+magi1ers
+magi1ert
+maha1t
+1mahl
+mai1c
+1maid1
+mai1g
+mai1n.
+mai1nb
+mai1ne
+mai1nf
+mai1nk
+mai1nl
+mai1n2p
+mai1ns.
+mai1nta
+mai1nw
+mai1nz
+1make
+makt1er
+m1ala
+ma1la1bo
+m1alb
+m1alc
+m1ald
+malee1
+m1alei
+m1alem
+1malen1
+m1alent
+1m1aler
+m1alf
+m1alg
+m1alh
+mali1er
+mali1es
+m1alk
+m1all
+ma1ll.
+ma1ll'
+ma1llam
+ma1llan
+mal1la2p
+ma1llar
+ma1llb
+ma1lle.
+mal1lei
+ma1llem
+ma1ller
+ma1lles
+ma1llet
+ma1llg
+malli2
+mal1lic
+ma1llm
+mal1log
+ma1ll2p
+ma1lls
+ma1llt
+ma1llv
+m1alm
+m1aln
+m1alo
+m1al2p
+m1alq
+m1alr
+m1al1sa
+m1alsc
+m1al1se
+m1also
+m1al1s2p
+m1al1st
+m1alt
+m1alv
+malv1e
+m1alw
+m1alz
+ma1m1a
+1man'
+1manag
+man2a
+1manch
+manci1e
+mand1e
+ma1neb
+mane1se
+man1es
+ma1neu
+mangfal1l.
+mangfall1
+mang1fal
+1manik
+1mani2p
+1mann.
+1mannat
+man1n2a
+1mann1es
+1manns
+mant1ello
+manti1g
+man1ti
+1manus
+man2u
+1manö
+maob1
+1mappe
+ma2p
+map2p
+1marci
+m1arc
+ma1ref
+ma1re1st
+m1ares
+marg1er
+m1arg
+1markf
+m1ark
+1marki
+1mark2p
+1markt
+1marku
+marma1l
+m1arm
+marni1er
+m1arn
+marni1s
+1marí
+ma1rü
+mas1ch1era.
+mas1chere
+1mask
+1massa
+1mast.
+1mastb
+mas1tor
+1masts
+mat1ela
+1mater
+mat1eri1e.
+mathe1rs'
+ma1th
+1matra
+ma1t2r
+1matz
+maub1
+1mauer
+1maul1
+ma1umr
+mau1m
+ma1unt
+mau2n
+mauri1e
+maus1t2r
+ma1uta
+mav2erh
+mav1e
+1maxi
+1mayr
+1maß
+mba1ras
+mb1eac
+m1bea
+mb2ed
+m1b1ee1
+mb1ei.
+mb1eig
+mb1ein
+mb1eli
+mb1elo
+mb1enc
+mb1eni
+mb1enk
+mb1enm
+mb1ens
+mb1en1t
+mb1env
+mb1enz
+mb1er.
+mb1erb
+mb1erd
+mb1erf
+mb1erg
+mb1erh
+mb1erj
+mb1erk
+mb1erl
+mb1erm
+mb1ern
+mb1ero
+mb1er2p
+mb1err
+mb1ers
+mb1ert
+mb1erw
+mb1erz
+mb1eu
+mb1eut1
+mb1ey
+mbi1erd
+mbi1eri
+mbi1s
+mb1oi1
+m1bol1
+mbrech1
+mbrich1
+m1brü1
+m1burg1
+mbusb1
+m1bus
+mbu1s1so
+mbus1s2p
+mbus1st
+mbänd1
+m1bä
+mc1ka
+mc1ku
+mdea1
+md1em
+mde1st
+mdg1eh
+mdidi1
+mdie1
+mdritt1
+m1drit
+mdzug1
+mdös1c
+1mead
+m1ea1ls
+m1ea1ni
+mea1ns
+mea1n1t.
+mea1ra
+mea1re
+meat1
+meaus1
+meb1en
+me1de1ll
+me1di1en1
+me1di
+mee1h
+mee1int
+mee1l
+m1ee1r.
+mee1rd
+mee1rh
+mee1rs.
+mee1s
+1meet
+meg1en.
+megg1
+me1haa1
+me1hal
+me1han
+me1hau
+me1hef
+me1hei
+me1hem
+me1hi
+1mehl
+me1hou
+1mehr
+me1hu
+me1hä
+me1hü
+meini1e
+mein1i
+me1iso
+1meiss
+melde1i
+melde1s
+me1leb
+1melget2r
+me1lic
+me1list
+me1ll.
+me1llar
+mellau1
+me1llb
+me1lld
+mellde1
+me1lle.
+me1llem
+me1llen1
+me1ller
+me1lles
+me1llf
+me1llg
+me1llh
+me1llk
+me1ll1l
+me1llm
+me1ll2p
+me1llr
+me1lls
+me1llt
+me1llw
+me1lly
+me1llz
+me1llü
+mels1tem
+mel1st
+meltrich1
+melt2r
+melz1u
+me1län
+me1mac
+me1mad1
+me1ma2p
+me1mar
+me1mas
+me1mat
+me1mau
+memb1
+me1mie
+me1misc
+me1mm
+me1mod
+me1mom
+me1mu
+me1mä
+men1
+menco1
+m1enee1
+1menge.
+menge1rech1
+men1kau1
+menrech1t1en1
+mensa2u1fg
+mens1tag
+mens1tanz
+mens1tor
+mens1trun1
+menst2r
+menz1un1g
+menzu1r
+1menö
+1menü
+m1er.
+m1era
+mera1c
+mera1la
+mera1ll
+merasi1e
+m1erasi
+mera1ut
+m1erb
+m1erc
+m1erdu
+m1ere
+me1reic
+me1resi
+mere1ss
+me1rest
+me1rez
+mergeg1
+m1eri
+me1rif
+m1erk
+1m1erkm
+m1erl
+m1erma
+m1ern
+m1ero
+me1roh
+m1er2p
+m1err
+m1ers
+m2ersel
+mers1o
+mers1s
+m1ert
+m1eru
+me1ru1m
+m1erv
+me1rän
+meränd1
+me1rät
+m1erö
+me1röh
+m1erü
+m2e1rüc
+me1saa
+me1sam
+m1e1sce
+me1schr
+me1scr
+me1see
+me1seh
+me1send
+me1senk
+me1sens
+me1seq
+me1ser
+mes1fah1
+me1sig
+mes1on
+me1sond
+me1spi
+mes2p
+me1spu
+me1ss
+me2ssc
+1messer
+messerschaf1
+1messg
+messi1er
+1mess1s
+1messu
+1me1ssw
+me2ssä
+me1ste
+mesti1
+me1stro
+mest2r
+me1stu
+me1suc
+me1sy
+me1sän
+meta1c
+meta1lla
+m1etall
+1meteo
+1metho
+meti1er
+mett2el
+1metzg
+me1u.
+me1u1m
+meuni1
+me1unt
+me1us.
+mev1e
+1mey
+1meß
+meßun1
+mfall1
+m1fal
+mfe1ll
+m1fel
+mfoli1
+mfun1
+mgab1
+mgangs1
+mg1ehen1
+m1gehe
+mg1ehun
+mg1enr
+mgla1s
+mgwer1
+mhang1
+1mhar
+mheb1
+mheg1
+mhe1ll
+mhint1
+mhof1
+mhot1
+mhun1
+mhus1s
+mia1ll
+mibi1
+1midd
+1mief.
+1miek.
+mi1en2a
+mien1
+mi1enb
+mi1end
+mi1enf
+mi1eng
+mi1enh
+mi1eni
+mi1enk
+mi1enl
+mi1enm
+mi1enn
+mi1en2p
+mi1enr
+mi1ens
+mi1ent
+mi1env
+mi1enw
+mi1enz
+mie1s
+mi1gam
+mi1geb
+mi1gef
+mi1gei
+mi1genr
+mig1en
+mi1geru
+mi1ge1s2t
+mi1gew
+migg1
+mi1git
+mi1gla
+mi1glä
+mi1gor
+mi1grav
+mi1grin
+mi1gur
+mi1gut
+miher1
+mihi1
+mih1r
+mikle1b
+milag1
+1milb1
+1milc
+1milk
+milka1
+minde1st
+min1de
+mindsi1
+1min1er
+mini1g
+min1i
+1minut
+min2u
+1minz
+mi1näc
+miob1
+mion1i1
+mira1ns
+mi1ra
+mi1rd
+mi1rg
+mi1rk
+mi1rt
+mirü1c
+mi1rü
+mi1s1chie
+miseri1
+misslun1
+mi1tac
+mi1tad
+mi1tag
+1mitar
+1mitb