add lisp packages
This commit is contained in:
25
lisp/pdf-tools/build/server/.gitignore
vendored
Normal file
25
lisp/pdf-tools/build/server/.gitignore
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
*.o
|
||||
.deps/
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
configure
|
||||
depcomp
|
||||
epdfinfo
|
||||
install-sh
|
||||
libsynctex.a
|
||||
missing
|
||||
stamp-h1
|
||||
ar-lib
|
||||
compile
|
||||
config.h.in~
|
||||
.clang_complete
|
||||
callgrind.out.*
|
||||
config.guess
|
||||
config.sub
|
||||
TAGS
|
||||
44
lisp/pdf-tools/build/server/Makefile.am
Normal file
44
lisp/pdf-tools/build/server/Makefile.am
Normal file
@@ -0,0 +1,44 @@
|
||||
bin_PROGRAMS = epdfinfo
|
||||
epdfinfo_CFLAGS = -Wall $(glib_CFLAGS) $(poppler_glib_CFLAGS) $(poppler_CFLAGS) \
|
||||
$(png_CFLAGS)
|
||||
epdfinfo_CXXFLAGS = -Wall $(epdfinfo_CFLAGS)
|
||||
epdfinfo_LDADD = $(glib_LIBS) $(poppler_glib_LIBS) $(poppler_LIBS) \
|
||||
$(png_LIBS) libsynctex.a $(zlib_LIBS)
|
||||
epdfinfo_SOURCES = epdfinfo.c epdfinfo.h poppler-hack.cc
|
||||
|
||||
noinst_LIBRARIES = libsynctex.a
|
||||
libsynctex_a_SOURCES = synctex_parser.c synctex_parser_utils.c synctex_parser.h \
|
||||
synctex_parser_local.h synctex_parser_utils.h
|
||||
libsynctex_a_CFLAGS = -w $(zlib_CFLAGS) -DSYNCTEX_USE_LOCAL_HEADER
|
||||
|
||||
if HAVE_W32
|
||||
epdfinfo_LDADD += -lshlwapi
|
||||
endif
|
||||
|
||||
SYNCTEX_UPSTREAM = svn://tug.org/texlive/trunk/Build/source/texk/web2c/synctexdir
|
||||
SYNCTEX_FILES = synctex_parser.c \
|
||||
synctex_parser.h \
|
||||
synctex_parser_readme.txt \
|
||||
synctex_parser_utils.c \
|
||||
synctex_parser_utils.h \
|
||||
synctex_parser_version.txt \
|
||||
synctex_version.h \
|
||||
synctex_parser_advanced.h
|
||||
|
||||
|
||||
check-local:
|
||||
@if $(MAKE) --version 2>&1 | grep -q GNU; then \
|
||||
cd test && $(MAKE) $(AM_MAKEFLAGS); \
|
||||
else \
|
||||
echo "Skipping tests in server/test (requires GNU make)"; \
|
||||
fi
|
||||
|
||||
synctex-pull:
|
||||
@if [ -n "$$(git status --porcelain)" ]; then \
|
||||
git status; \
|
||||
echo "Not checking-out files into a dirty work-directory"; \
|
||||
false; \
|
||||
fi
|
||||
for file in $(SYNCTEX_FILES); do \
|
||||
svn export --force $(SYNCTEX_UPSTREAM)/$$file; \
|
||||
done
|
||||
545
lisp/pdf-tools/build/server/autobuild
Executable file
545
lisp/pdf-tools/build/server/autobuild
Executable file
@@ -0,0 +1,545 @@
|
||||
#!/bin/sh
|
||||
|
||||
##
|
||||
## Installs package dependencies and builds the application.
|
||||
##
|
||||
|
||||
# Don't exit if some command fails.
|
||||
set +e
|
||||
# Disable file globbing.
|
||||
set -f
|
||||
|
||||
# Boolean variables are true if non-empty and false otherwise.
|
||||
|
||||
# Command to install packages.
|
||||
PKGCMD=
|
||||
# Args to pass to $PKGCMD.
|
||||
PKGARGS=
|
||||
# Required packages.
|
||||
PACKAGES=
|
||||
# Whether package installation requires root permissions.
|
||||
PKG_INSTALL_AS_ROOT=true
|
||||
# Whether to skip package installation altogether.
|
||||
PKG_INSTALL_SKIP=
|
||||
# Whether to force package installation, even if it does not seem
|
||||
# necessary.
|
||||
PKG_INSTALL_FORCE=
|
||||
# Only test if the OS is handled by this script.
|
||||
DRY_RUN=
|
||||
# If and where to install the program.
|
||||
INSTALL_DIR=
|
||||
# Whether we can install packages.
|
||||
OS_IS_HANDLED=true
|
||||
# Which OSs installer to use
|
||||
OS=
|
||||
|
||||
## +-----------------------------------------------------------+
|
||||
## * Utility Functions
|
||||
## +-----------------------------------------------------------+
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
usage:$(basename "$0") [--help|-n|-i DIR|[-d -D]|[--os OS]]
|
||||
|
||||
-n Don't do anything, but check if this OS is handled.
|
||||
|
||||
-i DIR Install the program in the given directory.
|
||||
|
||||
-d Force dependency installattion.
|
||||
|
||||
-D Skip dependency installattion.
|
||||
|
||||
--os OS Use the given OS's installer
|
||||
|
||||
--help Display this message.
|
||||
|
||||
EOF
|
||||
exit "$1"
|
||||
}
|
||||
|
||||
# Search for command $1 in PATH. Print its absolute filename.
|
||||
which()
|
||||
{
|
||||
if [ -z "$1" ]; then
|
||||
return 1
|
||||
fi
|
||||
IFS=:
|
||||
for dir in $PATH; do
|
||||
if [ -x "$dir/$1" ]; then
|
||||
printf "%s" "$dir/$1"
|
||||
unset IFS
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
unset IFS
|
||||
return 1
|
||||
}
|
||||
|
||||
# Quote $@ for the shell.
|
||||
quote()
|
||||
{
|
||||
quoted=
|
||||
for arg; do
|
||||
qarg=$(printf "%s" "$arg" | sed -e 's/[|&;<>()$\`"'\'' ]/\\&/g')
|
||||
if [ -z "$quoted" ]; then
|
||||
quoted=$qarg
|
||||
else
|
||||
quoted="$quoted $qarg"
|
||||
fi
|
||||
done
|
||||
printf "%s" "$quoted"
|
||||
}
|
||||
|
||||
# Attempt to exec $@ as root.
|
||||
exec_privileged() {
|
||||
if [ -z "$1" ]; then
|
||||
echo "internal error: command is empty"
|
||||
exit 2
|
||||
fi
|
||||
if [ -w / ]; then
|
||||
"$@"
|
||||
elif which sudo >/dev/null 2>&1; then
|
||||
sudo -- "$@"
|
||||
retval=$?
|
||||
sudo -k
|
||||
return $retval
|
||||
elif which su >/dev/null 2>&1; then
|
||||
su -c "$(quote "$@")"
|
||||
else
|
||||
echo "No such program: sudo or su"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Test if $1 is in PATH or exit with a failure status.
|
||||
assert_program()
|
||||
{
|
||||
if ! which "$1" >/dev/null 2>&1; then
|
||||
echo "No such program: $1"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Source filename $1 and echo variable $2.
|
||||
source_var()
|
||||
{
|
||||
if ! [ -f "$1" ] || ! [ -r "$1" ] || [ -z "$2" ]; then
|
||||
return 1
|
||||
fi
|
||||
# shellcheck source=/dev/null
|
||||
. "$1"
|
||||
eval "printf '%s\n' \$$2"
|
||||
return 0
|
||||
}
|
||||
|
||||
exit_success()
|
||||
{
|
||||
echo "==========================="
|
||||
echo " Build succeeded. :O) "
|
||||
echo "==========================="
|
||||
exit 0
|
||||
}
|
||||
|
||||
exit_fail()
|
||||
{
|
||||
echo "==========================="
|
||||
echo " Build failed. ;o( "
|
||||
echo "==========================="
|
||||
if [ -z "$PKG_INSTALL_FORCE" ]; then
|
||||
echo "Note: maybe try the '-d' option."
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Return 0, if all required packages seem to be installed.
|
||||
have_packages_installed()
|
||||
{
|
||||
{
|
||||
which pkg-config || return 1
|
||||
if ! [ -f configure ];then
|
||||
which autoreconf || return 1
|
||||
which automake || return 1
|
||||
fi
|
||||
for lib in libpng glib-2.0 poppler poppler-glib zlib; do
|
||||
pkg-config --exists $lib || return 1
|
||||
done
|
||||
which make || return 1
|
||||
which gcc || which cc || return 1
|
||||
which g++ || which c++ || return 1
|
||||
cc $(pkg-config --cflags poppler) -o /dev/null -E - 2>/dev/null <<EOF
|
||||
#include <PDFDocEncoding.h>
|
||||
EOF
|
||||
[ $? -eq 0 ] || return 1
|
||||
return 0
|
||||
} >/dev/null 2>&1
|
||||
}
|
||||
|
||||
handle_options()
|
||||
{
|
||||
while [ $# -gt 0 ]; do
|
||||
case $1 in
|
||||
--help) usage 0;;
|
||||
-n) DRY_RUN=true;;
|
||||
-d) PKG_INSTALL_FORCE=true ;;
|
||||
-D) PKG_INSTALL_SKIP=true ;;
|
||||
-i)
|
||||
shift
|
||||
[ $# -gt 0 ] || usage 1
|
||||
if [ "${1%%/}" != "${PWD%%/}" ]; then
|
||||
INSTALL_DIR=$1
|
||||
fi ;;
|
||||
--os)
|
||||
shift
|
||||
[ $# -gt 0 ] || usage 1
|
||||
OS="$1"
|
||||
;;
|
||||
*) usage 1 ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
if [ -n "$PKG_INSTALL_SKIP" ] && [ -n "$PKG_INSTALL_FORCE" ]; then
|
||||
usage 1
|
||||
fi
|
||||
}
|
||||
|
||||
## +-----------------------------------------------------------+
|
||||
## * OS Functions
|
||||
## +-----------------------------------------------------------+
|
||||
|
||||
# Archlinux
|
||||
os_arch() {
|
||||
if ! [ -e "/etc/arch-release" ]; then
|
||||
return 1;
|
||||
fi
|
||||
PKGCMD=pacman
|
||||
PKGARGS="-S --needed"
|
||||
PACKAGES="base-devel libpng zlib poppler-glib"
|
||||
return 0;
|
||||
}
|
||||
|
||||
# CentOS
|
||||
os_centos() {
|
||||
if ! [ -e "/etc/centos-release" ]; then
|
||||
return 1
|
||||
fi
|
||||
PKGCMD=yum
|
||||
if yum help install-n >/dev/null 2>&1; then
|
||||
PKGARGS=install-n
|
||||
else
|
||||
PKGARGS=install
|
||||
fi
|
||||
PACKAGES="autoconf
|
||||
automake
|
||||
gcc
|
||||
gcc-c++
|
||||
libpng-devel
|
||||
make
|
||||
pkgconfig
|
||||
poppler-devel
|
||||
poppler-glib-devel
|
||||
zlib-devel"
|
||||
return 0
|
||||
}
|
||||
|
||||
# FreeBSD
|
||||
os_freebsd() {
|
||||
if ! which uname >/dev/null 2>&1 || [ "$(uname -s)" != "FreeBSD" ]; then
|
||||
return 1
|
||||
fi
|
||||
PKGCMD=pkg
|
||||
PKGARGS=install
|
||||
PACKAGES="autotools poppler-glib png pkgconf"
|
||||
return 0
|
||||
}
|
||||
|
||||
# OpenBSD
|
||||
os_openbsd() {
|
||||
if ! which uname >/dev/null 2>&1 || [ "$(uname -s)" != "OpenBSD" ]; then
|
||||
return 1
|
||||
fi
|
||||
PKGCMD=pkg_add
|
||||
PKGARGS="-uU"
|
||||
PACKAGES="autoconf-2.69p2 automake-1.15.1 poppler poppler-utils png"
|
||||
export AUTOCONF_VERSION=2.69
|
||||
export AUTOMAKE_VERSION=1.15
|
||||
if whereis clang++ ;then
|
||||
export CXX=clang++
|
||||
elif whereis eg++ ;then
|
||||
export CXX=eg++
|
||||
else
|
||||
export CXX=eg++
|
||||
PACKAGES="${PACKAGES} g++"
|
||||
fi
|
||||
export CXXFLAGS="-std=c++11 -I/usr/local/include/poppler -I/usr/local/include"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Fedora
|
||||
os_fedora() {
|
||||
if ! [ -e "/etc/fedora-release" ]; then
|
||||
return 1
|
||||
fi
|
||||
PKGCMD=dnf
|
||||
PKGARGS=install
|
||||
PACKAGES="autoconf
|
||||
automake
|
||||
gcc
|
||||
gcc-c++
|
||||
libpng-devel
|
||||
make
|
||||
poppler-devel
|
||||
poppler-glib-devel
|
||||
zlib-devel"
|
||||
VERSION=$(source_var /etc/os-release VERSION_ID)
|
||||
if [ -n "$VERSION" ] && [ "$VERSION" -ge 26 ]; then
|
||||
PACKAGES="$PACKAGES pkgconf"
|
||||
else
|
||||
PACKAGES="$PACKAGES pkgconfig"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Debian/Ubuntu
|
||||
os_debian() {
|
||||
if ! [ -e "/etc/debian_version" ]; then
|
||||
return 1
|
||||
fi
|
||||
PACKAGES="autoconf
|
||||
automake
|
||||
g++
|
||||
gcc
|
||||
libpng-dev
|
||||
libpoppler-dev
|
||||
libpoppler-glib-dev
|
||||
libpoppler-private-dev
|
||||
libz-dev
|
||||
make
|
||||
pkg-config"
|
||||
PKGCMD=apt-get
|
||||
PKGARGS=install
|
||||
return 0
|
||||
}
|
||||
|
||||
# Msys2
|
||||
os_msys2() {
|
||||
if [ -z "$MSYSTEM" ] || ! [ -r "/etc/profile" ]; then
|
||||
return 1
|
||||
fi
|
||||
case $MSYSTEM in
|
||||
MINGW64)
|
||||
PACKAGES="base-devel
|
||||
mingw-w64-x86_64-libpng
|
||||
mingw-w64-x86_64-poppler
|
||||
mingw-w64-x86_64-toolchain
|
||||
mingw-w64-x86_64-zlib" ;;
|
||||
MINGW32)
|
||||
PACKAGES="base-devel
|
||||
mingw-w64-i686-libpng
|
||||
mingw-w64-i686-poppler
|
||||
mingw-w64-i686-toolchain
|
||||
mingw-w64-i686-zlib" ;;
|
||||
MSYS)
|
||||
case $(uname -m) in
|
||||
x86_64)
|
||||
MSYSTEM=MINGW64 ;;
|
||||
*)
|
||||
MSYSTEM=MINGW32 ;;
|
||||
esac
|
||||
export MSYSTEM
|
||||
# shellcheck source=/dev/null
|
||||
. /etc/profile
|
||||
eval "exec $(quote "$0" "$@")" ;;
|
||||
*)
|
||||
echo "Unrecognized MSYSTEM value: $MSYSTEM"
|
||||
exit 1 ;;
|
||||
esac
|
||||
PKGCMD=pacman
|
||||
PKGARGS="-S --needed"
|
||||
PKG_INSTALL_AS_ROOT=
|
||||
return 0
|
||||
}
|
||||
|
||||
# MacOS
|
||||
os_macos() {
|
||||
if ! which uname >/dev/null 2>&1 || [ "$(uname -s)" != "Darwin" ]; then
|
||||
return 1
|
||||
elif which brew >/dev/null 2>&1; then
|
||||
PKGCMD=brew
|
||||
PKGARGS=install
|
||||
PACKAGES="pkg-config poppler automake"
|
||||
PKG_INSTALL_AS_ROOT=
|
||||
# homebrew install libffi as keg-only, meaning we need to set
|
||||
# PKG_CONFIG_PATH manually so configure can find it
|
||||
export PKG_CONFIG_PATH="$(brew --prefix libffi)/lib/pkgconfig/"
|
||||
elif which port >/dev/null 2>&1; then
|
||||
PKGCMD=port
|
||||
PKGARGS=install
|
||||
PACKAGES="pkgconfig poppler automake libpng"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# NixOS
|
||||
os_nixos() {
|
||||
# Already in the nix-shell.
|
||||
if [ -n "$AUTOBUILD_NIX_SHELL" ]; then
|
||||
return 0
|
||||
fi
|
||||
if ! which nix-shell >/dev/null 2>&1; then
|
||||
return 1
|
||||
fi
|
||||
if [ -n "$DRY_RUN" ]; then
|
||||
return 0
|
||||
fi
|
||||
command="AUTOBUILD_NIX_SHELL=true"
|
||||
command="$command;export AUTOBUILD_NIX_SHELL"
|
||||
command="$command;$(quote "$0" "$@")"
|
||||
exec nix-shell --pure --command "$command" \
|
||||
-p gcc gnumake automake autoconf pkgconfig libpng zlib poppler
|
||||
}
|
||||
|
||||
# Gentoo
|
||||
os_gentoo() {
|
||||
if ! [ -e "/etc/gentoo-release" ]; then
|
||||
return 1
|
||||
fi
|
||||
PKGCMD=emerge
|
||||
PKGARGS=--noreplace
|
||||
PACKAGES="app-text/poppler
|
||||
dev-util/pkgconfig
|
||||
media-libs/libpng
|
||||
sys-devel/autoconf
|
||||
sys-devel/automake
|
||||
sys-devel/gcc
|
||||
sys-devel/make
|
||||
sys-libs/zlib"
|
||||
return 0
|
||||
}
|
||||
|
||||
# By Parameter --os
|
||||
os_argument() {
|
||||
[ -z "$OS" ] && return 1
|
||||
case $OS in
|
||||
macos) os_macos "$@";;
|
||||
freebsd) os_freebsd "$@";;
|
||||
arch) os_arch "$@";;
|
||||
centos) os_centos "$@";;
|
||||
openbsd) os_openbsd "$@";;
|
||||
fedora) os_fedora "$@";;
|
||||
debian) os_debian "$@";;
|
||||
gentoo) os_gentoo "$@";;
|
||||
msys2) os_msys2 "$@";;
|
||||
nixos) os_nixos "$@";;
|
||||
*) echo "Invalid --os argument: $OS"
|
||||
exit 1
|
||||
esac || {
|
||||
echo "Unable to install on this system as $OS"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
## +-----------------------------------------------------------+
|
||||
## * Figure out were we are, install deps and build the program
|
||||
## +-----------------------------------------------------------+
|
||||
|
||||
handle_options "$@"
|
||||
|
||||
os_argument "$@" || \
|
||||
os_macos "$@" || \
|
||||
os_freebsd "$@" || \
|
||||
os_arch "$@" || \
|
||||
os_centos "$@" || \
|
||||
os_openbsd "$@" || \
|
||||
os_fedora "$@" || \
|
||||
os_debian "$@" || \
|
||||
os_gentoo "$@" || \
|
||||
os_msys2 "$@" || \
|
||||
os_nixos "$@" || \
|
||||
{
|
||||
OS_IS_HANDLED=
|
||||
if [ -z "$DRY_RUN" ]; then
|
||||
echo "Failed to recognize this system, trying to continue."
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -n "$DRY_RUN" ]; then
|
||||
[ -n "$OS_IS_HANDLED" ]
|
||||
exit $?
|
||||
fi
|
||||
|
||||
if [ -n "$PKGCMD" ];then
|
||||
echo "---------------------------"
|
||||
echo " Installing packages "
|
||||
echo "---------------------------"
|
||||
if [ -n "$PKG_INSTALL_SKIP" ]; then
|
||||
echo "Skipping package installation (as requested)"
|
||||
elif [ -z "$PKG_INSTALL_FORCE" ] && have_packages_installed; then
|
||||
echo "Skipping package installation (already installed)"
|
||||
else
|
||||
assert_program "$PKGCMD"
|
||||
echo "$PKGCMD $PKGARGS $PACKAGES"
|
||||
if [ -n "$PKG_INSTALL_AS_ROOT" ]; then
|
||||
exec_privileged $PKGCMD $PKGARGS $PACKAGES
|
||||
else
|
||||
$PKGCMD $PKGARGS $PACKAGES
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
fi
|
||||
|
||||
echo "---------------------------"
|
||||
echo " Configuring and compiling "
|
||||
echo "---------------------------"
|
||||
|
||||
# Try to be in the correct directory.
|
||||
if which dirname >/dev/null 2>&1; then
|
||||
cd "$(dirname "$0")" || {
|
||||
echo "Failed to change into the source directory"
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
# Create the configure script.
|
||||
if ! [ -f ./configure ]; then
|
||||
assert_program autoreconf
|
||||
echo "autoreconf -i"
|
||||
autoreconf -i
|
||||
[ -f ./configure ] || exit_fail
|
||||
fi
|
||||
|
||||
# Build the program.
|
||||
if [ -n "$INSTALL_DIR" ]; then
|
||||
prefix=--bindir=$INSTALL_DIR
|
||||
fi
|
||||
|
||||
echo "./configure -q $prefix && make -s"
|
||||
eval "./configure -q $(quote "$prefix") && make -s || exit_fail"
|
||||
echo
|
||||
if [ -n "$INSTALL_DIR" ]; then
|
||||
echo "---------------------------"
|
||||
echo " Installing "
|
||||
echo "---------------------------"
|
||||
echo make -s install
|
||||
if mkdir -p -- "$INSTALL_DIR" && [ -w "$INSTALL_DIR" ]; then
|
||||
make install || exit_fail
|
||||
else
|
||||
exec_privileged make install || exit_fail
|
||||
fi
|
||||
# Copy dynamic libraries on windows.
|
||||
if [ -f epdfinfo.exe ]; then
|
||||
assert_program awk
|
||||
assert_program ldd
|
||||
for dll in $(ldd epdfinfo.exe | awk '/\/mingw/ {print $3}'); do
|
||||
cp -u "$dll" "$INSTALL_DIR"
|
||||
done
|
||||
fi
|
||||
echo
|
||||
fi
|
||||
exit_success
|
||||
|
||||
# Local Variables:
|
||||
# compile-command: "shellcheck autobuild"
|
||||
# End:
|
||||
5
lisp/pdf-tools/build/server/autogen.sh
Executable file
5
lisp/pdf-tools/build/server/autogen.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "Running autoreconf..."
|
||||
|
||||
autoreconf -i
|
||||
113
lisp/pdf-tools/build/server/configure.ac
Normal file
113
lisp/pdf-tools/build/server/configure.ac
Normal file
@@ -0,0 +1,113 @@
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.67])
|
||||
AC_INIT([epdfinfo], 1.0, [politza@fh-trier.de])
|
||||
AM_INIT_AUTOMAKE([-Wall -Wno-override foreign silent-rules])
|
||||
AC_CONFIG_SRCDIR([epdfinfo.h])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_CXX
|
||||
AC_PROG_RANLIB
|
||||
AM_PROG_AR
|
||||
|
||||
# Checks for libraries.
|
||||
HAVE_POPPLER_FIND_OPTS="no (requires poppler-glib >= 0.22)"
|
||||
HAVE_POPPLER_ANNOT_WRITE="no (requires poppler-glib >= 0.19.4)"
|
||||
HAVE_POPPLER_ANNOT_MARKUP="no (requires poppler-glib >= 0.26)"
|
||||
|
||||
PKG_CHECK_MODULES([png], [libpng])
|
||||
PKG_CHECK_MODULES([glib], [glib-2.0])
|
||||
PKG_CHECK_MODULES([poppler], [poppler])
|
||||
PKG_CHECK_MODULES([poppler_glib], [poppler-glib >= 0.16.0])
|
||||
PKG_CHECK_EXISTS([poppler-glib >= 0.19.4], [HAVE_POPPLER_ANNOT_WRITE=yes])
|
||||
PKG_CHECK_EXISTS([poppler-glib >= 0.22], [HAVE_POPPLER_FIND_OPTS=yes])
|
||||
PKG_CHECK_EXISTS([poppler-glib >= 0.26], [HAVE_POPPLER_ANNOT_MARKUP=yes])
|
||||
PKG_CHECK_MODULES([zlib], [zlib])
|
||||
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[
|
||||
#ifndef _WIN32
|
||||
error
|
||||
#endif
|
||||
]])], [have_w32=true], [have_w32=false])
|
||||
AM_CONDITIONAL(HAVE_W32, [test "$have_w32" = true])
|
||||
|
||||
if test "$have_w32" = true; then
|
||||
if test "$MSYSTEM" = MINGW32 -o "$MSYSTEM" = MINGW64; then
|
||||
# glib won't work properly on msys2 without it.
|
||||
CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CFLAGS"
|
||||
fi
|
||||
fi
|
||||
|
||||
SAVED_CPPFLAGS=$CPPFLAGS
|
||||
CPPFLAGS=$poppler_CFLAGS
|
||||
AC_LANG_PUSH([C++])
|
||||
# Check if we can use the -std=c++11 option.
|
||||
m4_include([m4/ax_check_compile_flag.m4])
|
||||
AX_CHECK_COMPILE_FLAG([-std=c++11], [HAVE_STD_CXX11=yes])
|
||||
|
||||
if test "$HAVE_STD_CXX11" = yes; then
|
||||
CXXFLAGS="-std=c++11 $CXXFLAGS"
|
||||
fi
|
||||
# Check for private poppler header.
|
||||
AC_CHECK_HEADERS([Annot.h PDFDocEncoding.h], [],
|
||||
AC_MSG_ERROR([cannot find necessary poppler-private header (see README.org)]))
|
||||
AC_LANG_POP([C++])
|
||||
CPPFLAGS=$SAVED_CPPFLAGS
|
||||
|
||||
# Setup compile time features.
|
||||
if test "$HAVE_POPPLER_FIND_OPTS" = yes; then
|
||||
AC_DEFINE([HAVE_POPPLER_FIND_OPTS],1,
|
||||
[Define to 1 to enable case sensitive searching (requires poppler-glib >= 0.22).])
|
||||
fi
|
||||
|
||||
if test "$HAVE_POPPLER_ANNOT_WRITE" = yes; then
|
||||
AC_DEFINE([HAVE_POPPLER_ANNOT_WRITE],1,
|
||||
[Define to 1 to enable writing of annotations (requires poppler-glib >= 0.19.4).])
|
||||
fi
|
||||
|
||||
if test "$HAVE_POPPLER_ANNOT_MARKUP" = yes; then
|
||||
AC_DEFINE([HAVE_POPPLER_ANNOT_MARKUP],1,
|
||||
[Define to 1 to enable adding of markup annotations (requires poppler-glib >= 0.26).])
|
||||
fi
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([stdlib.h string.h strings.h err.h])
|
||||
|
||||
AC_MSG_CHECKING([for error.h])
|
||||
SAVED_CFLAGS=$CFLAGS
|
||||
CFLAGS="$poppler_CFLAGS $poppler_glib_CFLAGS"
|
||||
AC_LANG_PUSH([C])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
|
||||
#include <error.h>
|
||||
],[error (0, 0, "");])],
|
||||
[AC_DEFINE([HAVE_ERROR_H],1, [Define to 1 if error.h is usable.])
|
||||
AC_MSG_RESULT([yes])],
|
||||
AC_MSG_RESULT([no]))
|
||||
AC_LANG_POP([C])
|
||||
CFLAGS=$SAVED_CFLAGS
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_SSIZE_T
|
||||
AC_CHECK_TYPES([ptrdiff_t])
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_ERROR_AT_LINE
|
||||
AC_FUNC_STRTOD
|
||||
AC_CHECK_FUNCS([strcspn strtol getline])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
echo
|
||||
echo "Is case-sensitive searching enabled ? ${HAVE_POPPLER_FIND_OPTS}"
|
||||
echo "Is modifying text annotations enabled ? ${HAVE_POPPLER_ANNOT_WRITE}"
|
||||
echo "Is modifying markup annotations enabled ? ${HAVE_POPPLER_ANNOT_MARKUP}"
|
||||
echo
|
||||
3718
lisp/pdf-tools/build/server/epdfinfo.c
Normal file
3718
lisp/pdf-tools/build/server/epdfinfo.c
Normal file
File diff suppressed because it is too large
Load Diff
252
lisp/pdf-tools/build/server/epdfinfo.h
Normal file
252
lisp/pdf-tools/build/server/epdfinfo.h
Normal file
@@ -0,0 +1,252 @@
|
||||
// Copyright (C) 2013, 2014 Andreas Politz
|
||||
|
||||
// Author: Andreas Politz <politza@fh-trier.de>
|
||||
|
||||
// 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/>.
|
||||
|
||||
#ifndef _EPDF_H_
|
||||
#define _EPDF_H_ _EPDF_H_
|
||||
#include "config.h"
|
||||
#include <glib.h>
|
||||
#include <poppler.h>
|
||||
#include <png.h>
|
||||
|
||||
/* Some library functions print warnings to stdout, inhibit it. */
|
||||
#define DISCARD_STDOUT(saved_fd) \
|
||||
do { \
|
||||
int __fd; \
|
||||
fflush(stdout); \
|
||||
saved_fd = dup(1); \
|
||||
__fd = open("/dev/null", O_WRONLY); \
|
||||
dup2(__fd, 1); \
|
||||
close(__fd); \
|
||||
} while (0)
|
||||
|
||||
#define UNDISCARD_STDOUT(saved_fd) \
|
||||
do { \
|
||||
fflush(stdout); \
|
||||
dup2(saved_fd, 1); \
|
||||
close(saved_fd); \
|
||||
} while (0)
|
||||
|
||||
/* Writing responses */
|
||||
#define OK_BEGIN() \
|
||||
do { \
|
||||
puts("OK"); \
|
||||
} while (0)
|
||||
|
||||
#define OK_END() \
|
||||
do { \
|
||||
puts("."); \
|
||||
fflush (stdout); \
|
||||
} while (0)
|
||||
|
||||
#define OK() \
|
||||
do { \
|
||||
puts ("OK\n."); \
|
||||
fflush (stdout); \
|
||||
} while (0)
|
||||
|
||||
/* Dealing with image data. */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define ARGB_TO_RGB(rgb, argb) \
|
||||
do { \
|
||||
rgb[0] = argb[1]; \
|
||||
rgb[1] = argb[2]; \
|
||||
rgb[2] = argb[3]; \
|
||||
} while (0)
|
||||
|
||||
#define ARGB_EQUAL(argb1, argb2) \
|
||||
(argb1[1] == argb2[1] \
|
||||
&& argb1[2] == argb2[2] \
|
||||
&& argb1[3] == argb2[3])
|
||||
|
||||
#else
|
||||
#define ARGB_TO_RGB(rgb, argb) \
|
||||
do { \
|
||||
rgb[0] = argb[2]; \
|
||||
rgb[1] = argb[1]; \
|
||||
rgb[2] = argb[0]; \
|
||||
} while (0)
|
||||
|
||||
#define ARGB_EQUAL(argb1, argb2) \
|
||||
(argb1[0] == argb2[0] \
|
||||
&& argb1[1] == argb2[1] \
|
||||
&& argb1[2] == argb2[2])
|
||||
#endif
|
||||
|
||||
#define NORMALIZE_PAGE_ARG(doc, first, last) \
|
||||
*first = MAX(1, *first); \
|
||||
if (*last <= 0) \
|
||||
*last = poppler_document_get_n_pages (doc); \
|
||||
else \
|
||||
*last = MIN(*last, poppler_document_get_n_pages (doc));
|
||||
|
||||
/* png_jmpbuf is supposed to be not available in older versions of
|
||||
libpng. */
|
||||
#ifndef png_jmpbuf
|
||||
# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ERROR_H
|
||||
# define error(status, errno, fmt, args...) \
|
||||
do { \
|
||||
int error = (errno); \
|
||||
fflush (stdout); \
|
||||
fprintf (stderr, "%s: " fmt, PACKAGE_NAME, ## args); \
|
||||
if (error) \
|
||||
fprintf (stderr, ": %s", strerror (error)); \
|
||||
fprintf (stderr, "\n"); \
|
||||
exit (status); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define internal_error(fmt, args...) \
|
||||
error (2, 0, "internal error in %s: " fmt, __func__, ## args)
|
||||
|
||||
#define error_if_not(expr) \
|
||||
if (! (expr)) goto error;
|
||||
|
||||
#define perror_if_not(expr, fmt, args...) \
|
||||
do { \
|
||||
if (! (expr)) \
|
||||
{ \
|
||||
printf_error_response ((fmt), ## args); \
|
||||
goto error; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define cerror_if_not(expr, error_msg, fmt, args...) \
|
||||
do { \
|
||||
if (! (expr)) \
|
||||
{ \
|
||||
if (error_msg) \
|
||||
*(error_msg) = g_strdup_printf((fmt), ## args); \
|
||||
goto error; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Declare commands */
|
||||
#define DEC_CMD(name) \
|
||||
{#name, cmd_ ## name, cmd_ ## name ## _spec, \
|
||||
G_N_ELEMENTS (cmd_ ## name ## _spec)}
|
||||
|
||||
#define DEC_CMD2(command, name) \
|
||||
{name, cmd_ ## command, cmd_ ## command ## _spec, \
|
||||
G_N_ELEMENTS (cmd_ ## command ## _spec)}
|
||||
|
||||
/* Declare option */
|
||||
#define DEC_DOPT(name, type, sname) \
|
||||
{name, type, offsetof (document_options_t, sname)}
|
||||
|
||||
enum suffix_char { NONE, COLON, NEWLINE};
|
||||
|
||||
enum image_type { PPM, PNG };
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PopplerAnnotMapping *amap;
|
||||
gchar *key;
|
||||
} annotation_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ARG_INVALID = 0,
|
||||
ARG_DOC,
|
||||
ARG_BOOL,
|
||||
ARG_STRING,
|
||||
ARG_NONEMPTY_STRING,
|
||||
ARG_NATNUM,
|
||||
ARG_EDGE,
|
||||
ARG_EDGE_OR_NEGATIVE,
|
||||
ARG_EDGES,
|
||||
ARG_EDGES_OR_POSITION,
|
||||
ARG_COLOR,
|
||||
ARG_REST
|
||||
} command_arg_type_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
command_arg_type_t type;
|
||||
size_t offset;
|
||||
} document_option_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PopplerColor bg, fg;
|
||||
gboolean usecolors;
|
||||
gboolean printed;
|
||||
} render_options_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
render_options_t render;
|
||||
} document_options_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PopplerDocument *pdf;
|
||||
char *filename;
|
||||
char *passwd;
|
||||
struct
|
||||
{
|
||||
GHashTable *keys; /* key => page */
|
||||
GList **pages; /* page array */
|
||||
} annotations;
|
||||
document_options_t options;
|
||||
} document_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
command_arg_type_t type;
|
||||
union
|
||||
{
|
||||
gboolean flag;
|
||||
const char *string;
|
||||
long natnum;
|
||||
document_t *doc;
|
||||
gdouble edge;
|
||||
PopplerColor color;
|
||||
PopplerRectangle rectangle;
|
||||
#ifdef HAVE_POPPLER_ANNOT_MARKUP
|
||||
PopplerQuadrilateral quadrilateral;
|
||||
#endif
|
||||
struct
|
||||
{
|
||||
char * const *args;
|
||||
int nargs;
|
||||
} rest;
|
||||
} value;
|
||||
} command_arg_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GHashTable *documents;
|
||||
} epdfinfo_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
void (* execute) (const epdfinfo_t *ctxt, const command_arg_t *args);
|
||||
const command_arg_type_t *args_spec;
|
||||
int nargs;
|
||||
} command_t;
|
||||
|
||||
/* Defined in poppler-hack.cc */
|
||||
#ifdef HAVE_POPPLER_ANNOT_WRITE
|
||||
extern void xpoppler_annot_set_rectangle (PopplerAnnot*, PopplerRectangle*);
|
||||
#endif
|
||||
extern gchar *xpoppler_annot_markup_get_created (PopplerAnnotMarkup*);
|
||||
#endif /* _EPDF_H_ */
|
||||
74
lisp/pdf-tools/build/server/m4/ax_check_compile_flag.m4
Normal file
74
lisp/pdf-tools/build/server/m4/ax_check_compile_flag.m4
Normal file
@@ -0,0 +1,74 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check whether the given FLAG works with the current language's compiler
|
||||
# or gives an error. (Warnings, however, are ignored)
|
||||
#
|
||||
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
|
||||
# success/failure.
|
||||
#
|
||||
# If EXTRA-FLAGS is defined, it is added to the current language's default
|
||||
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
|
||||
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
|
||||
# force the compiler to issue an error when a bad flag is given.
|
||||
#
|
||||
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
|
||||
#
|
||||
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
|
||||
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 5
|
||||
|
||||
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
|
||||
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
|
||||
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
|
||||
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
|
||||
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
|
||||
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
|
||||
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
|
||||
[AS_VAR_SET(CACHEVAR,[yes])],
|
||||
[AS_VAR_SET(CACHEVAR,[no])])
|
||||
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
|
||||
AS_VAR_IF(CACHEVAR,yes,
|
||||
[m4_default([$2], :)],
|
||||
[m4_default([$3], :)])
|
||||
AS_VAR_POPDEF([CACHEVAR])dnl
|
||||
])dnl AX_CHECK_COMPILE_FLAGS
|
||||
122
lisp/pdf-tools/build/server/poppler-hack.cc
Normal file
122
lisp/pdf-tools/build/server/poppler-hack.cc
Normal file
@@ -0,0 +1,122 @@
|
||||
// Copyright (C) 2013, 2014 Andreas Politz
|
||||
|
||||
// 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/>.
|
||||
|
||||
#include <config.h>
|
||||
#include <PDFDocEncoding.h>
|
||||
#include <Annot.h>
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <poppler-features.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
GType poppler_annot_get_type (void) G_GNUC_CONST;
|
||||
GType poppler_annot_markup_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#define POPPLER_TYPE_ANNOT (poppler_annot_get_type ())
|
||||
#define POPPLER_ANNOT(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ANNOT, PopplerAnnot))
|
||||
#define POPPLER_IS_ANNOT_MARKUP(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ANNOT_MARKUP))
|
||||
#define POPPLER_TYPE_ANNOT_MARKUP (poppler_annot_markup_get_type ())
|
||||
|
||||
#if POPPLER_CHECK_VERSION(0,72,0)
|
||||
#define GET_CSTR c_str
|
||||
#else
|
||||
#define GET_CSTR getCString
|
||||
#endif
|
||||
|
||||
struct PopplerAnnot
|
||||
{
|
||||
GObject parent_instance;
|
||||
Annot *annot;
|
||||
};
|
||||
|
||||
struct PopplerAnnotMarkup
|
||||
{
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
struct PopplerRectangle
|
||||
{
|
||||
double x1;
|
||||
double y1;
|
||||
double x2;
|
||||
double y2;
|
||||
};
|
||||
|
||||
// This function does not modify its argument s, but for
|
||||
// compatibility reasons (e.g. getLength in GooString.h before 2015)
|
||||
// with older poppler code, it can't be declared as such.
|
||||
char *_xpoppler_goo_string_to_utf8(/* const */ GooString *s)
|
||||
{
|
||||
char *result;
|
||||
|
||||
if (! s)
|
||||
return NULL;
|
||||
|
||||
if (s->hasUnicodeMarker()) {
|
||||
result = g_convert (s->GET_CSTR () + 2,
|
||||
s->getLength () - 2,
|
||||
"UTF-8", "UTF-16BE", NULL, NULL, NULL);
|
||||
} else {
|
||||
int len;
|
||||
gunichar *ucs4_temp;
|
||||
int i;
|
||||
|
||||
len = s->getLength ();
|
||||
ucs4_temp = g_new (gunichar, len + 1);
|
||||
for (i = 0; i < len; ++i) {
|
||||
ucs4_temp[i] = pdfDocEncoding[(unsigned char)s->getChar(i)];
|
||||
}
|
||||
ucs4_temp[i] = 0;
|
||||
|
||||
result = g_ucs4_to_utf8 (ucs4_temp, -1, NULL, NULL, NULL);
|
||||
|
||||
g_free (ucs4_temp);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#ifdef HAVE_POPPLER_ANNOT_WRITE
|
||||
// Set the rectangle of an annotation. It was first added in v0.26.
|
||||
void xpoppler_annot_set_rectangle (PopplerAnnot *a, PopplerRectangle *rectangle)
|
||||
{
|
||||
GooString *state = (GooString*) a->annot->getAppearState ();
|
||||
char *ustate = _xpoppler_goo_string_to_utf8 (state);
|
||||
|
||||
a->annot->setRect (rectangle->x1, rectangle->y1,
|
||||
rectangle->x2, rectangle->y2);
|
||||
a->annot->setAppearanceState (ustate);
|
||||
g_free (ustate);
|
||||
}
|
||||
#endif
|
||||
// This function is in the library, but the enforced date parsing is
|
||||
// incomplete (at least in some versions), because it ignores the
|
||||
// timezone.
|
||||
gchar *xpoppler_annot_markup_get_created (PopplerAnnotMarkup *poppler_annot)
|
||||
{
|
||||
AnnotMarkup *annot;
|
||||
GooString *text;
|
||||
|
||||
g_return_val_if_fail (POPPLER_IS_ANNOT_MARKUP (poppler_annot), NULL);
|
||||
|
||||
annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);
|
||||
text = (GooString*) annot->getDate ();
|
||||
|
||||
return text ? _xpoppler_goo_string_to_utf8 (text) : NULL;
|
||||
}
|
||||
}
|
||||
12
lisp/pdf-tools/build/server/poppler-versions
Normal file
12
lisp/pdf-tools/build/server/poppler-versions
Normal file
@@ -0,0 +1,12 @@
|
||||
HAVE_POPPLER_ANNOT_WRITE
|
||||
0.19.4 solves bug 49080, which potentially corrupts PDF files.
|
||||
|
||||
HAVE_POPPLER_FIND_OPTS
|
||||
0.22 PopplerFindFlags
|
||||
0.22 poppler_page_find_text_with_options
|
||||
|
||||
HAVE_POPPLER_ANNOT_SET_RECT
|
||||
0.26 Adds function poppler_annot_set_rectangle
|
||||
|
||||
HAVE_POPPLER_ANNOT_MARKUP
|
||||
0.26 poppler_annot_text_markup_new_{highlight,squiggly,strikeout,underline}
|
||||
8924
lisp/pdf-tools/build/server/synctex_parser.c
Normal file
8924
lisp/pdf-tools/build/server/synctex_parser.c
Normal file
File diff suppressed because it is too large
Load Diff
429
lisp/pdf-tools/build/server/synctex_parser.h
Normal file
429
lisp/pdf-tools/build/server/synctex_parser.h
Normal file
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
Copyright (c) 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr
|
||||
|
||||
This file is part of the __SyncTeX__ package.
|
||||
|
||||
[//]: # (Latest Revision: Fri Jul 14 16:20:41 UTC 2017)
|
||||
[//]: # (Version: 1.21)
|
||||
|
||||
See `synctex_parser_readme.md` for more details
|
||||
|
||||
## License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE
|
||||
|
||||
Except as contained in this notice, the name of the copyright holder
|
||||
shall not be used in advertising or otherwise to promote the sale,
|
||||
use or other dealings in this Software without prior written
|
||||
authorization from the copyright holder.
|
||||
|
||||
## Acknowledgments:
|
||||
|
||||
The author received useful remarks from the __pdfTeX__ developers, especially Hahn The Thanh,
|
||||
and significant help from __XeTeX__ developer Jonathan Kew.
|
||||
|
||||
## Nota Bene:
|
||||
|
||||
If you include or use a significant part of the __SyncTeX__ package into a software,
|
||||
I would appreciate to be listed as contributor and see "__SyncTeX__" highlighted.
|
||||
*/
|
||||
|
||||
#ifndef __SYNCTEX_PARSER__
|
||||
# define __SYNCTEX_PARSER__
|
||||
|
||||
#include "synctex_version.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* The main synctex object is a scanner.
|
||||
* Its implementation is considered private.
|
||||
* The basic workflow is
|
||||
* - create a "synctex scanner" with the contents of a file
|
||||
* - perform actions on that scanner like
|
||||
synctex_display_query or synctex_edit_query below.
|
||||
* - perform actions on nodes returned by the scanner
|
||||
* - free the scanner when the work is done
|
||||
*/
|
||||
typedef struct synctex_scanner_t synctex_scanner_s;
|
||||
typedef synctex_scanner_s * synctex_scanner_p;
|
||||
|
||||
/**
|
||||
* This is the designated method to create
|
||||
* a new synctex scanner object.
|
||||
* - argument output: the pdf/dvi/xdv file associated
|
||||
* to the synctex file.
|
||||
* If necessary, it can be the tex file that
|
||||
* originated the synctex file but this might cause
|
||||
* problems if the \jobname has a custom value.
|
||||
* Despite this method can accept a relative path
|
||||
* in practice, you should only pass full paths.
|
||||
* The path should be encoded by the underlying
|
||||
* file system, assuming that it is based on
|
||||
* 8 bits characters, including UTF8,
|
||||
* not 16 bits nor 32 bits.
|
||||
* The last file extension is removed and
|
||||
* replaced by the proper extension,
|
||||
* either synctex or synctex.gz.
|
||||
* - argument build_directory: It is the directory where
|
||||
* all the auxiliary stuff is created.
|
||||
* If no synctex file is found in the same directory
|
||||
* as the output file, then we try to find one in
|
||||
* this build directory.
|
||||
* It is the directory where all the auxiliary
|
||||
* stuff is created. Sometimes, the synctex output
|
||||
* file and the pdf, dvi or xdv files are not
|
||||
* created in the same location. See MikTeX.
|
||||
* This directory path can be NULL,
|
||||
* it will be ignored then.
|
||||
* It can be either absolute or relative to the
|
||||
* directory of the output pdf (dvi or xdv) file.
|
||||
* Please note that this new argument is provided
|
||||
* as a convenience but should not be used.
|
||||
* Available since version 1.5.
|
||||
* - argument parse: In general, use 1.
|
||||
* Use 0 only if you do not want to parse the
|
||||
* content but just check for existence.
|
||||
* Available since version 1.5
|
||||
* - return: a scanner. NULL is returned in case
|
||||
* of an error or non existent file.
|
||||
*/
|
||||
synctex_scanner_p synctex_scanner_new_with_output_file(const char * output, const char * build_directory, int parse);
|
||||
|
||||
/**
|
||||
* Designated method to delete a synctex scanner object,
|
||||
* including all its internal resources.
|
||||
* Frees all the memory, you must call it when you are finished with the scanner.
|
||||
* - argument scanner: a scanner.
|
||||
* - returns: an integer used for testing purposes.
|
||||
*/
|
||||
int synctex_scanner_free(synctex_scanner_p scanner);
|
||||
|
||||
/**
|
||||
* Send this message to force the scanner to
|
||||
* parse the contents of the synctex output file.
|
||||
* Nothing is performed if the file was already parsed.
|
||||
* In each query below, this message is sent,
|
||||
* but if you need to access information more directly,
|
||||
* you must ensure that the parsing did occur.
|
||||
* Usage:
|
||||
* if((my_scanner = synctex_scanner_parse(my_scanner))) {
|
||||
* continue with my_scanner...
|
||||
* } else {
|
||||
* there was a problem
|
||||
* }
|
||||
* - returns: the argument on success.
|
||||
* On failure, frees scanner and returns NULL.
|
||||
*/
|
||||
synctex_scanner_p synctex_scanner_parse(synctex_scanner_p scanner);
|
||||
|
||||
/* synctex_node_p is the type for all synctex nodes.
|
||||
* Its implementation is considered private.
|
||||
* The synctex file is parsed into a tree of nodes, either sheet, form, boxes, math nodes... */
|
||||
|
||||
typedef struct synctex_node_t synctex_node_s;
|
||||
typedef synctex_node_s * synctex_node_p;
|
||||
|
||||
/* The main entry points.
|
||||
* Given the file name, a line and a column number, synctex_display_query returns the number of nodes
|
||||
* satisfying the contrain. Use code like
|
||||
*
|
||||
* if(synctex_display_query(scanner,name,line,column,page_hint)>0) {
|
||||
* synctex_node_p node;
|
||||
* while((node = synctex_scanner_next_result(scanner))) {
|
||||
* // do something with node
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* Please notice that since version 1.19,
|
||||
* there is a new argument page_hint.
|
||||
* The results in pages closer to page_hint are given first.
|
||||
* For example, one can
|
||||
* - highlight each resulting node in the output, using synctex_node_visible_h and synctex_node_visible_v
|
||||
* - highlight all the rectangles enclosing those nodes, using synctex_node_box_visible_... functions
|
||||
* - highlight just the character using that information
|
||||
*
|
||||
* Given the page and the position in the page, synctex_edit_query returns the number of nodes
|
||||
* satisfying the contrain. Use code like
|
||||
*
|
||||
* if(synctex_edit_query(scanner,page,h,v)>0) {
|
||||
* synctex_node_p node;
|
||||
* while(node = synctex_scanner_next_result(scanner)) {
|
||||
* // do something with node
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* For example, one can
|
||||
* - highlight each resulting line in the input,
|
||||
* - highlight just the character using that information
|
||||
*
|
||||
* page is 1 based
|
||||
* h and v are coordinates in 72 dpi unit, relative to the top left corner of the page.
|
||||
* If you make a new query, the result of the previous one is discarded. If you need to make more than one query
|
||||
* in parallel, use the iterator API exposed in
|
||||
* the synctex_parser_private.h header.
|
||||
* If one of this function returns a negative integer,
|
||||
* it means that an error occurred.
|
||||
*
|
||||
* Both methods are conservative, in the sense that matching is weak.
|
||||
* If the exact column number is not found, there will be an answer with the whole line.
|
||||
*
|
||||
* Sumatra-PDF, Skim, iTeXMac2, TeXShop and Texworks are examples of open source software that use this library.
|
||||
* You can browse their code for a concrete implementation.
|
||||
*/
|
||||
typedef long synctex_status_t;
|
||||
/* The page_hint argument is used to resolve ambiguities.
|
||||
* Whenever, different matches occur, the ones closest
|
||||
* to the page will be given first. Pass a negative number
|
||||
* when in doubt. Using pdf forms may lead to ambiguities.
|
||||
*/
|
||||
synctex_status_t synctex_display_query(synctex_scanner_p scanner,const char * name,int line,int column, int page_hint);
|
||||
synctex_status_t synctex_edit_query(synctex_scanner_p scanner,int page,float h,float v);
|
||||
synctex_node_p synctex_scanner_next_result(synctex_scanner_p scanner);
|
||||
synctex_status_t synctex_scanner_reset_result(synctex_scanner_p scanner);
|
||||
|
||||
/**
|
||||
* The horizontal and vertical location,
|
||||
* the width, height and depth of a box enclosing node.
|
||||
* All dimensions are given in page coordinates
|
||||
* as opposite to TeX coordinates.
|
||||
* The origin is at the top left corner of the page.
|
||||
* Code example for Qt5:
|
||||
* (from TeXworks source TWSynchronize.cpp)
|
||||
* QRectF nodeRect(synctex_node_box_visible_h(node),
|
||||
* synctex_node_box_visible_v(node) -
|
||||
* synctex_node_box_visible_height(node),
|
||||
* synctex_node_box_visible_width(node),
|
||||
* synctex_node_box_visible_height(node) +
|
||||
* synctex_node_box_visible_depth(node));
|
||||
* Code example for Cocoa:
|
||||
* NSRect bounds = [pdfPage
|
||||
* boundsForBox:kPDFDisplayBoxMediaBox];
|
||||
* NSRect nodeRect = NSMakeRect(
|
||||
* synctex_node_box_visible_h(node),
|
||||
* NSMaxY(bounds)-synctex_node_box_visible_v(node) +
|
||||
* synctex_node_box_visible_height(node),
|
||||
* synctex_node_box_visible_width(node),
|
||||
* synctex_node_box_visible_height(node) +
|
||||
* synctex_node_box_visible_depth(node)
|
||||
* );
|
||||
* The visible dimensions are bigger than real ones
|
||||
* to compensate 0 width boxes or nodes intentionnaly
|
||||
* put outside the box (using \kern for example).
|
||||
* - parameter node: a node.
|
||||
* - returns: a float.
|
||||
* - author: JL
|
||||
*/
|
||||
float synctex_node_box_visible_h(synctex_node_p node);
|
||||
float synctex_node_box_visible_v(synctex_node_p node);
|
||||
float synctex_node_box_visible_width(synctex_node_p node);
|
||||
float synctex_node_box_visible_height(synctex_node_p node);
|
||||
float synctex_node_box_visible_depth(synctex_node_p node);
|
||||
|
||||
/**
|
||||
* For quite all nodes, horizontal and vertical coordinates, and width.
|
||||
* All dimensions are given in page coordinates
|
||||
* as opposite to TeX coordinates.
|
||||
* The origin is at the top left corner of the page.
|
||||
* The visible dimensions are bigger than real ones
|
||||
* to compensate 0 width boxes or nodes intentionnaly
|
||||
* put outside the box (using \kern for example).
|
||||
* All nodes have coordinates, but all nodes don't
|
||||
* have non null size. For example, math nodes
|
||||
* have no width according to TeX, and in that case
|
||||
* synctex_node_visible_width simply returns 0.
|
||||
* The same holds for kern nodes that do not have
|
||||
* height nor depth, etc...
|
||||
*/
|
||||
float synctex_node_visible_h(synctex_node_p node);
|
||||
float synctex_node_visible_v(synctex_node_p node);
|
||||
float synctex_node_visible_width(synctex_node_p node);
|
||||
float synctex_node_visible_height(synctex_node_p node);
|
||||
float synctex_node_visible_depth(synctex_node_p node);
|
||||
|
||||
/**
|
||||
* Given a node, access to its tag, line and column.
|
||||
* The line and column numbers are 1 based.
|
||||
* The latter is not yet fully supported in TeX,
|
||||
* the default implementation returns 0
|
||||
* which means the whole line.
|
||||
* synctex_node_get_name returns the path of the
|
||||
* TeX source file that was used to create the node.
|
||||
* When the tag is known, the scanner of the node
|
||||
* will also give that same file name, see
|
||||
* synctex_scanner_get_name below.
|
||||
* For an hbox node, the mean line is the mean
|
||||
* of all the lines of the child nodes.
|
||||
* Sometimes, when synchronization form pdf to source
|
||||
* fails with the line, one should try with the
|
||||
* mean line.
|
||||
*/
|
||||
int synctex_node_tag(synctex_node_p node);
|
||||
int synctex_node_line(synctex_node_p node);
|
||||
int synctex_node_mean_line(synctex_node_p node);
|
||||
int synctex_node_column(synctex_node_p node);
|
||||
const char * synctex_node_get_name(synctex_node_p node);
|
||||
|
||||
/**
|
||||
This is the page where the node appears.
|
||||
* This is a 1 based index as given by TeX.
|
||||
*/
|
||||
int synctex_node_page(synctex_node_p node);
|
||||
|
||||
/**
|
||||
* Display all the information contained in the scanner.
|
||||
* If the records are too numerous, only the first ones are displayed.
|
||||
* This is mainly for informational purpose to help developers.
|
||||
*/
|
||||
void synctex_scanner_display(synctex_scanner_p scanner);
|
||||
|
||||
/* Managing the input file names.
|
||||
* Given a tag, synctex_scanner_get_name will return the corresponding file name.
|
||||
* Conversely, given a file name, synctex_scanner_get_tag will return, the corresponding tag.
|
||||
* The file name must be the very same as understood by TeX.
|
||||
* For example, if you \input myDir/foo.tex, the file name is myDir/foo.tex.
|
||||
* No automatic path expansion is performed.
|
||||
* Finally, synctex_scanner_input is the first input node of the scanner.
|
||||
* To browse all the input node, use a loop like
|
||||
* ...
|
||||
* synctex_node_p = input_node;
|
||||
* ...
|
||||
* if((input_node = synctex_scanner_input(scanner))) {
|
||||
* do {
|
||||
* blah
|
||||
* } while((input_node=synctex_node_sibling(input_node)));
|
||||
* }
|
||||
*
|
||||
* The output is the name that was used to create the scanner.
|
||||
* The synctex is the real name of the synctex file,
|
||||
* it was obtained from output by setting the proper file extension.
|
||||
*/
|
||||
const char * synctex_scanner_get_name(synctex_scanner_p scanner,int tag);
|
||||
|
||||
int synctex_scanner_get_tag(synctex_scanner_p scanner,const char * name);
|
||||
|
||||
synctex_node_p synctex_scanner_input(synctex_scanner_p scanner);
|
||||
synctex_node_p synctex_scanner_input_with_tag(synctex_scanner_p scanner,int tag);
|
||||
const char * synctex_scanner_get_output(synctex_scanner_p scanner);
|
||||
const char * synctex_scanner_get_synctex(synctex_scanner_p scanner);
|
||||
|
||||
/* The x and y offset of the origin in TeX coordinates. The magnification
|
||||
These are used by pdf viewers that want to display the real box size.
|
||||
For example, getting the horizontal coordinates of a node would require
|
||||
synctex_node_box_h(node)*synctex_scanner_magnification(scanner)+synctex_scanner_x_offset(scanner)
|
||||
Getting its TeX width would simply require
|
||||
synctex_node_box_width(node)*synctex_scanner_magnification(scanner)
|
||||
but direct methods are available for that below.
|
||||
*/
|
||||
int synctex_scanner_x_offset(synctex_scanner_p scanner);
|
||||
int synctex_scanner_y_offset(synctex_scanner_p scanner);
|
||||
float synctex_scanner_magnification(synctex_scanner_p scanner);
|
||||
|
||||
/**
|
||||
* ## Browsing the nodes
|
||||
* parent, child and sibling are standard names for tree nodes.
|
||||
* The parent is one level higher,
|
||||
* the child is one level deeper,
|
||||
* and the sibling is at the same level.
|
||||
* A node and its sibling have the same parent.
|
||||
* A node is the parent of its children.
|
||||
* A node is either the child of its parent,
|
||||
* or belongs to the sibling chain of its parent's child.
|
||||
* The sheet or form of a node is the topmost ancestor,
|
||||
* it is of type sheet or form.
|
||||
* The next node is either the child, the sibling or the parent's sibling,
|
||||
* unless the parent is a sheet, a form or NULL.
|
||||
* This allows to navigate through all the nodes of a given sheet node:
|
||||
*
|
||||
* synctex_node_p node = sheet;
|
||||
* while((node = synctex_node_next(node))) {
|
||||
* // do something with node
|
||||
* }
|
||||
*
|
||||
* With synctex_sheet_content and synctex_form_content,
|
||||
* you can retrieve the sheet node given the page
|
||||
* or form tag.
|
||||
* The page is 1 based, according to TeX standards.
|
||||
* Conversely synctex_node_parent_sheet or
|
||||
* synctex_node_parent_form allows to retrieve
|
||||
* the sheet or the form containing a given node.
|
||||
* Notice that a node is not contained in a sheet
|
||||
* and a form at the same time.
|
||||
* Some nodes are not contained in either (handles).
|
||||
*/
|
||||
|
||||
synctex_node_p synctex_node_parent(synctex_node_p node);
|
||||
synctex_node_p synctex_node_parent_sheet(synctex_node_p node);
|
||||
synctex_node_p synctex_node_parent_form(synctex_node_p node);
|
||||
synctex_node_p synctex_node_child(synctex_node_p node);
|
||||
synctex_node_p synctex_node_last_child(synctex_node_p node);
|
||||
synctex_node_p synctex_node_sibling(synctex_node_p node);
|
||||
synctex_node_p synctex_node_last_sibling(synctex_node_p node);
|
||||
synctex_node_p synctex_node_arg_sibling(synctex_node_p node);
|
||||
synctex_node_p synctex_node_next(synctex_node_p node);
|
||||
|
||||
/**
|
||||
* Top level entry points.
|
||||
* The scanner owns a list of sheet siblings and
|
||||
* a list of form siblings.
|
||||
* Sheets or forms have one child which is a box:
|
||||
* theie contents.
|
||||
* - argument page: 1 based sheet page number.
|
||||
* - argument tag: 1 based form tag number.
|
||||
*/
|
||||
synctex_node_p synctex_sheet(synctex_scanner_p scanner,int page);
|
||||
synctex_node_p synctex_sheet_content(synctex_scanner_p scanner,int page);
|
||||
synctex_node_p synctex_form(synctex_scanner_p scanner,int tag);
|
||||
synctex_node_p synctex_form_content(synctex_scanner_p scanner,int tag);
|
||||
|
||||
/* This is primarily used for debugging purpose.
|
||||
* The second one logs information for the node and recursively displays information for its next node */
|
||||
void synctex_node_log(synctex_node_p node);
|
||||
void synctex_node_display(synctex_node_p node);
|
||||
|
||||
/* For quite all nodes, horizontal, vertical coordinates, and width.
|
||||
* These are expressed in TeX small points coordinates, with origin at the top left corner.
|
||||
*/
|
||||
int synctex_node_h(synctex_node_p node);
|
||||
int synctex_node_v(synctex_node_p node);
|
||||
int synctex_node_width(synctex_node_p node);
|
||||
int synctex_node_height(synctex_node_p node);
|
||||
int synctex_node_depth(synctex_node_p node);
|
||||
|
||||
/* For all nodes, dimensions of the enclosing box.
|
||||
* These are expressed in TeX small points coordinates, with origin at the top left corner.
|
||||
* A box is enclosing itself.
|
||||
*/
|
||||
int synctex_node_box_h(synctex_node_p node);
|
||||
int synctex_node_box_v(synctex_node_p node);
|
||||
int synctex_node_box_width(synctex_node_p node);
|
||||
int synctex_node_box_height(synctex_node_p node);
|
||||
int synctex_node_box_depth(synctex_node_p node);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
554
lisp/pdf-tools/build/server/synctex_parser_advanced.h
Normal file
554
lisp/pdf-tools/build/server/synctex_parser_advanced.h
Normal file
@@ -0,0 +1,554 @@
|
||||
/*
|
||||
Copyright (c) 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr
|
||||
|
||||
This file is part of the __SyncTeX__ package.
|
||||
|
||||
[//]: # (Latest Revision: Sun Oct 15 15:09:55 UTC 2017)
|
||||
[//]: # (Version: 1.21)
|
||||
|
||||
See `synctex_parser_readme.md` for more details
|
||||
|
||||
## License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE
|
||||
|
||||
Except as contained in this notice, the name of the copyright holder
|
||||
shall not be used in advertising or otherwise to promote the sale,
|
||||
use or other dealings in this Software without prior written
|
||||
authorization from the copyright holder.
|
||||
*/
|
||||
|
||||
#include "synctex_parser.h"
|
||||
#include "synctex_parser_utils.h"
|
||||
|
||||
#ifndef __SYNCTEX_PARSER_PRIVATE__
|
||||
# define __SYNCTEX_PARSER_PRIVATE__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* Reminder that the argument must not be NULL */
|
||||
typedef synctex_node_p synctex_non_null_node_p;
|
||||
|
||||
/* Each node of the tree, except the scanner itself belongs to a class.
|
||||
* The class object is just a struct declaring the owning scanner
|
||||
* This is a pointer to the scanner as root of the tree.
|
||||
* The type is used to identify the kind of node.
|
||||
* The class declares pointers to a creator and a destructor method.
|
||||
* The log and display fields are used to log and display the node.
|
||||
* display will also display the child, sibling and parent sibling.
|
||||
* parent, child and sibling are used to navigate the tree,
|
||||
* from TeX box hierarchy point of view.
|
||||
* The friend field points to a method which allows to navigate from friend to friend.
|
||||
* A friend is a node with very close tag and line numbers.
|
||||
* Finally, the info field point to a method giving the private node info offset.
|
||||
*/
|
||||
|
||||
/**
|
||||
* These are the masks for the synctex node types.
|
||||
* int's are 32 bits at least.
|
||||
*/
|
||||
enum {
|
||||
synctex_shift_root,
|
||||
synctex_shift_no_root,
|
||||
synctex_shift_void,
|
||||
synctex_shift_no_void,
|
||||
synctex_shift_box,
|
||||
synctex_shift_no_box,
|
||||
synctex_shift_proxy,
|
||||
synctex_shift_no_proxy,
|
||||
synctex_shift_h,
|
||||
synctex_shift_v
|
||||
};
|
||||
enum {
|
||||
synctex_mask_root = 1,
|
||||
synctex_mask_no_root = synctex_mask_root<<1,
|
||||
synctex_mask_void = synctex_mask_no_root<<1,
|
||||
synctex_mask_no_void = synctex_mask_void<<1,
|
||||
synctex_mask_box = synctex_mask_no_void<<1,
|
||||
synctex_mask_no_box = synctex_mask_box<<1,
|
||||
synctex_mask_proxy = synctex_mask_no_box<<1,
|
||||
synctex_mask_no_proxy = synctex_mask_proxy<<1,
|
||||
synctex_mask_h = synctex_mask_no_proxy<<1,
|
||||
synctex_mask_v = synctex_mask_h<<1,
|
||||
};
|
||||
enum {
|
||||
synctex_mask_non_void_hbox = synctex_mask_no_void
|
||||
| synctex_mask_box
|
||||
| synctex_mask_h,
|
||||
synctex_mask_non_void_vbox = synctex_mask_no_void
|
||||
| synctex_mask_box
|
||||
| synctex_mask_v
|
||||
};
|
||||
typedef enum {
|
||||
synctex_node_mask_sf =
|
||||
synctex_mask_root
|
||||
|synctex_mask_no_void
|
||||
|synctex_mask_no_box
|
||||
|synctex_mask_no_proxy,
|
||||
synctex_node_mask_vbox =
|
||||
synctex_mask_no_root
|
||||
|synctex_mask_no_void
|
||||
|synctex_mask_box
|
||||
|synctex_mask_no_proxy
|
||||
|synctex_mask_v,
|
||||
synctex_node_mask_hbox =
|
||||
synctex_mask_no_root
|
||||
|synctex_mask_no_void
|
||||
|synctex_mask_box
|
||||
|synctex_mask_no_proxy
|
||||
|synctex_mask_h,
|
||||
synctex_node_mask_void_vbox =
|
||||
synctex_mask_no_root
|
||||
|synctex_mask_void
|
||||
|synctex_mask_box
|
||||
|synctex_mask_no_proxy
|
||||
|synctex_mask_v,
|
||||
synctex_node_mask_void_hbox =
|
||||
synctex_mask_no_root
|
||||
|synctex_mask_void
|
||||
|synctex_mask_box
|
||||
|synctex_mask_no_proxy
|
||||
|synctex_mask_h,
|
||||
synctex_node_mask_vbox_proxy =
|
||||
synctex_mask_no_root
|
||||
|synctex_mask_no_void
|
||||
|synctex_mask_box
|
||||
|synctex_mask_proxy
|
||||
|synctex_mask_v,
|
||||
synctex_node_mask_hbox_proxy =
|
||||
synctex_mask_no_root
|
||||
|synctex_mask_no_void
|
||||
|synctex_mask_box
|
||||
|synctex_mask_proxy
|
||||
|synctex_mask_h,
|
||||
synctex_node_mask_nvnn =
|
||||
synctex_mask_no_root
|
||||
|synctex_mask_void
|
||||
|synctex_mask_no_box
|
||||
|synctex_mask_no_proxy,
|
||||
synctex_node_mask_input =
|
||||
synctex_mask_root
|
||||
|synctex_mask_void
|
||||
|synctex_mask_no_box
|
||||
|synctex_mask_no_proxy,
|
||||
synctex_node_mask_proxy =
|
||||
synctex_mask_no_root
|
||||
|synctex_mask_void
|
||||
|synctex_mask_no_box
|
||||
|synctex_mask_proxy
|
||||
} synctex_node_mask_t;
|
||||
|
||||
enum {
|
||||
/* input */
|
||||
synctex_tree_sibling_idx = 0,
|
||||
synctex_tree_s_input_max = 1,
|
||||
/* All */
|
||||
synctex_tree_s_parent_idx = 1,
|
||||
synctex_tree_sp_child_idx = 2,
|
||||
synctex_tree_spc_friend_idx = 3,
|
||||
synctex_tree_spcf_last_idx = 4,
|
||||
synctex_tree_spcfl_vbox_max = 5,
|
||||
/* hbox supplement */
|
||||
synctex_tree_spcfl_next_hbox_idx = 5,
|
||||
synctex_tree_spcfln_hbox_max = 6,
|
||||
/* hbox proxy supplement */
|
||||
synctex_tree_spcfln_target_idx = 6,
|
||||
synctex_tree_spcflnt_proxy_hbox_max = 7,
|
||||
/* vbox proxy supplement */
|
||||
synctex_tree_spcfl_target_idx = 5,
|
||||
synctex_tree_spcflt_proxy_vbox_max = 6,
|
||||
/* spf supplement*/
|
||||
synctex_tree_sp_friend_idx = 2,
|
||||
synctex_tree_spf_max = 3,
|
||||
/* box boundary supplement */
|
||||
synctex_tree_spf_arg_sibling_idx = 3,
|
||||
synctex_tree_spfa_max = 4,
|
||||
/* proxy supplement */
|
||||
synctex_tree_spf_target_idx = 3,
|
||||
synctex_tree_spft_proxy_max = 4,
|
||||
/* last proxy supplement */
|
||||
synctex_tree_spfa_target_idx = 4,
|
||||
synctex_tree_spfat_proxy_last_max = 5,
|
||||
/* sheet supplement */
|
||||
synctex_tree_s_child_idx = 1,
|
||||
synctex_tree_sc_next_hbox_idx = 2,
|
||||
synctex_tree_scn_sheet_max = 3,
|
||||
/* form supplement */
|
||||
synctex_tree_sc_target_idx = 2,
|
||||
synctex_tree_sct_form_max = 3,
|
||||
/* spct */
|
||||
synctex_tree_spc_target_idx = 3,
|
||||
synctex_tree_spct_handle_max = 4,
|
||||
};
|
||||
|
||||
enum {
|
||||
/* input */
|
||||
synctex_data_input_tag_idx = 0,
|
||||
synctex_data_input_line_idx = 1,
|
||||
synctex_data_input_name_idx = 2,
|
||||
synctex_data_input_tln_max = 3,
|
||||
/* sheet */
|
||||
synctex_data_sheet_page_idx = 0,
|
||||
synctex_data_p_sheet_max = 1,
|
||||
/* form */
|
||||
synctex_data_form_tag_idx = 0,
|
||||
synctex_data_t_form_max = 1,
|
||||
/* tlchv */
|
||||
synctex_data_tag_idx = 0,
|
||||
synctex_data_line_idx = 1,
|
||||
synctex_data_column_idx = 2,
|
||||
synctex_data_h_idx = 3,
|
||||
synctex_data_v_idx = 4,
|
||||
synctex_data_tlchv_max = 5,
|
||||
/* tlchvw */
|
||||
synctex_data_width_idx = 5,
|
||||
synctex_data_tlchvw_max = 6,
|
||||
/* box */
|
||||
synctex_data_height_idx = 6,
|
||||
synctex_data_depth_idx = 7,
|
||||
synctex_data_box_max = 8,
|
||||
/* hbox supplement */
|
||||
synctex_data_mean_line_idx = 8,
|
||||
synctex_data_weight_idx = 9,
|
||||
synctex_data_h_V_idx = 10,
|
||||
synctex_data_v_V_idx = 11,
|
||||
synctex_data_width_V_idx = 12,
|
||||
synctex_data_height_V_idx = 13,
|
||||
synctex_data_depth_V_idx = 14,
|
||||
synctex_data_hbox_max = 15,
|
||||
/* ref */
|
||||
synctex_data_ref_tag_idx = 0,
|
||||
synctex_data_ref_h_idx = 1,
|
||||
synctex_data_ref_v_idx = 2,
|
||||
synctex_data_ref_thv_max = 3,
|
||||
/* proxy */
|
||||
synctex_data_proxy_h_idx = 0,
|
||||
synctex_data_proxy_v_idx = 1,
|
||||
synctex_data_proxy_hv_max = 2,
|
||||
/* handle */
|
||||
synctex_data_handle_w_idx = 0,
|
||||
synctex_data_handle_w_max = 1,
|
||||
};
|
||||
|
||||
/* each synctex node has a class */
|
||||
typedef struct synctex_class_t synctex_class_s;
|
||||
typedef synctex_class_s * synctex_class_p;
|
||||
|
||||
|
||||
/* synctex_node_p is a pointer to a node
|
||||
* synctex_node_s is the target of the synctex_node_p pointer
|
||||
* It is a pseudo object oriented program.
|
||||
* class is a pointer to the class object the node belongs to.
|
||||
* implementation is meant to contain the private data of the node
|
||||
* basically, there are 2 kinds of information: navigation information and
|
||||
* synctex information. Both will depend on the type of the node,
|
||||
* thus different nodes will have different private data.
|
||||
* There is no inheritancy overhead.
|
||||
*/
|
||||
typedef union {
|
||||
synctex_node_p as_node;
|
||||
int as_integer;
|
||||
char * as_string;
|
||||
void * as_pointer;
|
||||
} synctex_data_u;
|
||||
typedef synctex_data_u * synctex_data_p;
|
||||
|
||||
# if defined(SYNCTEX_USE_CHARINDEX)
|
||||
typedef unsigned int synctex_charindex_t;
|
||||
synctex_charindex_t synctex_node_charindex(synctex_node_p node);
|
||||
typedef synctex_charindex_t synctex_lineindex_t;
|
||||
synctex_lineindex_t synctex_node_lineindex(synctex_node_p node);
|
||||
synctex_node_p synctex_scanner_handle(synctex_scanner_p scanner);
|
||||
# define SYNCTEX_DECLARE_CHARINDEX \
|
||||
synctex_charindex_t char_index;\
|
||||
synctex_lineindex_t line_index;
|
||||
# define SYNCTEX_DECLARE_CHAR_OFFSET \
|
||||
synctex_charindex_t charindex_offset;
|
||||
# else
|
||||
# define SYNCTEX_DECLARE_CHARINDEX
|
||||
# define SYNCTEX_DECLARE_CHAR_OFFSET
|
||||
# endif
|
||||
struct synctex_node_t {
|
||||
SYNCTEX_DECLARE_CHARINDEX
|
||||
synctex_class_p class_;
|
||||
#ifdef DEBUG
|
||||
synctex_data_u data[22];
|
||||
#else
|
||||
synctex_data_u data[1];
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef synctex_node_p * synctex_node_r;
|
||||
|
||||
typedef struct {
|
||||
int h;
|
||||
int v;
|
||||
} synctex_point_s;
|
||||
|
||||
typedef synctex_point_s * synctex_point_p;
|
||||
|
||||
typedef struct {
|
||||
synctex_point_s min; /* top left */
|
||||
synctex_point_s max; /* bottom right */
|
||||
} synctex_box_s;
|
||||
|
||||
typedef synctex_box_s * synctex_box_p;
|
||||
/**
|
||||
* These are the types of the synctex nodes.
|
||||
* No need to use them but the compiler needs them here.
|
||||
* There are 3 kinds of nodes.
|
||||
* - primary nodes
|
||||
* - proxies
|
||||
* - handles
|
||||
* Primary nodes are created at parse time
|
||||
* of the synctex file.
|
||||
* Proxies are used to support pdf forms.
|
||||
* The ref primary nodes are replaced by a tree
|
||||
* of proxy nodes which duplicate the tree of primary
|
||||
* nodes available in the referred form.
|
||||
* Roughly speaking, the primary nodes of the form
|
||||
* know what to display, the proxy nodes know where.
|
||||
* Handles are used in queries. They point to either
|
||||
* primary nodes or proxies.
|
||||
*/
|
||||
typedef enum {
|
||||
synctex_node_type_none = 0,
|
||||
synctex_node_type_input,
|
||||
synctex_node_type_sheet,
|
||||
synctex_node_type_form,
|
||||
synctex_node_type_ref,
|
||||
synctex_node_type_vbox,
|
||||
synctex_node_type_void_vbox,
|
||||
synctex_node_type_hbox,
|
||||
synctex_node_type_void_hbox,
|
||||
synctex_node_type_kern,
|
||||
synctex_node_type_glue,
|
||||
synctex_node_type_rule,
|
||||
synctex_node_type_math,
|
||||
synctex_node_type_boundary,
|
||||
synctex_node_type_box_bdry,
|
||||
synctex_node_type_proxy,
|
||||
synctex_node_type_proxy_last,
|
||||
synctex_node_type_proxy_vbox,
|
||||
synctex_node_type_proxy_hbox,
|
||||
synctex_node_type_handle,
|
||||
synctex_node_number_of_types
|
||||
} synctex_node_type_t;
|
||||
/* synctex_node_type gives the type of a given node,
|
||||
* synctex_node_isa gives the same information as a human readable text. */
|
||||
synctex_node_type_t synctex_node_type(synctex_node_p node);
|
||||
const char * synctex_node_isa(synctex_node_p node);
|
||||
|
||||
synctex_node_type_t synctex_node_target_type(synctex_node_p node);
|
||||
|
||||
synctex_node_type_t synctex_node_type(synctex_node_p node);
|
||||
const char * synctex_node_isa(synctex_node_p node);
|
||||
|
||||
void synctex_node_log(synctex_node_p node);
|
||||
void synctex_node_display(synctex_node_p node);
|
||||
|
||||
/* Given a node, access to the location in the synctex file where it is defined.
|
||||
*/
|
||||
|
||||
int synctex_node_form_tag(synctex_node_p node);
|
||||
|
||||
int synctex_node_weight(synctex_node_p node);
|
||||
int synctex_node_child_count(synctex_node_p node);
|
||||
|
||||
int synctex_node_h(synctex_node_p node);
|
||||
int synctex_node_v(synctex_node_p node);
|
||||
int synctex_node_width(synctex_node_p node);
|
||||
|
||||
int synctex_node_box_h(synctex_node_p node);
|
||||
int synctex_node_box_v(synctex_node_p node);
|
||||
int synctex_node_box_width(synctex_node_p node);
|
||||
int synctex_node_box_height(synctex_node_p node);
|
||||
int synctex_node_box_depth(synctex_node_p node);
|
||||
|
||||
int synctex_node_hbox_h(synctex_node_p node);
|
||||
int synctex_node_hbox_v(synctex_node_p node);
|
||||
int synctex_node_hbox_width(synctex_node_p node);
|
||||
int synctex_node_hbox_height(synctex_node_p node);
|
||||
int synctex_node_hbox_depth(synctex_node_p node);
|
||||
|
||||
synctex_scanner_p synctex_scanner_new(void);
|
||||
synctex_node_p synctex_node_new(synctex_scanner_p scanner,synctex_node_type_t type);
|
||||
|
||||
/**
|
||||
* Scanner display switcher getter.
|
||||
* If the switcher is 0, synctex_node_display is disabled.
|
||||
* If the switcher is <0, synctex_node_display has no limit.
|
||||
* If the switcher is >0, only the first switcher (as number) nodes are displayed.
|
||||
* - parameter: a scanner
|
||||
* - returns: an integer
|
||||
*/
|
||||
int synctex_scanner_display_switcher(synctex_scanner_p scanR);
|
||||
void synctex_scanner_set_display_switcher(synctex_scanner_p scanR, int switcher);
|
||||
|
||||
/**
|
||||
* Iterator is the structure used to traverse
|
||||
* the answer to client queries.
|
||||
* First answers are the best matches, according
|
||||
* to criteria explained below.
|
||||
* Next answers are not ordered.
|
||||
* Objects are handles to nodes in the synctex node tree starting at scanner.
|
||||
*/
|
||||
typedef struct synctex_iterator_t synctex_iterator_s;
|
||||
typedef synctex_iterator_s * synctex_iterator_p;
|
||||
|
||||
/**
|
||||
* Designated creator for a display query, id est,
|
||||
* forward navigation from source to output.
|
||||
* Returns NULL if the query has no answer.
|
||||
* Code example:
|
||||
* synctex_iterator_p iterator = NULL;
|
||||
* if ((iterator = synctex_iterator_new_display(...)) {
|
||||
* synctex_node_p node = NULL;
|
||||
* while((node = synctex_iterator_next_result(iterator))) {
|
||||
* do something with node...
|
||||
* }
|
||||
*/
|
||||
synctex_iterator_p synctex_iterator_new_display(synctex_scanner_p scanner,const char * name,int line,int column, int page_hint);
|
||||
/**
|
||||
* Designated creator for an edit query, id est,
|
||||
* backward navigation from output to source.
|
||||
* Code example:
|
||||
* synctex_iterator_p iterator = NULL;
|
||||
* if ((iterator = synctex_iterator_new_edit(...)) {
|
||||
* synctex_node_p node = NULL;
|
||||
* while((node = synctex_iterator_next_result(iterator))) {
|
||||
* do something with node...
|
||||
* }
|
||||
*/
|
||||
synctex_iterator_p synctex_iterator_new_edit(synctex_scanner_p scanner,int page,float h,float v);
|
||||
/**
|
||||
* Free all the resources.
|
||||
* - argument iterator: the object to free...
|
||||
* You should free the iterator before the scanner
|
||||
* owning the nodes it iterates with.
|
||||
*/
|
||||
void synctex_iterator_free(synctex_iterator_p iterator);
|
||||
/**
|
||||
* Whether the iterator actually points to an object.
|
||||
* - argument iterator: the object to iterate on...
|
||||
*/
|
||||
synctex_bool_t synctex_iterator_has_next(synctex_iterator_p iterator);
|
||||
/**
|
||||
* Returns the pointed object and advance the cursor
|
||||
* to the next object. Returns NULL and does nothing
|
||||
* if the end has already been reached.
|
||||
* - argument iterator: the object to iterate on...
|
||||
*/
|
||||
synctex_node_p synctex_iterator_next_result(synctex_iterator_p iterator);
|
||||
/**
|
||||
* Reset the cursor position to the first result.
|
||||
* - argument iterator: the object to iterate on...
|
||||
*/
|
||||
int synctex_iterator_reset(synctex_iterator_p iterator);
|
||||
/**
|
||||
* The number of objects left for traversal.
|
||||
* - argument iterator: the object to iterate on...
|
||||
*/
|
||||
int synctex_iterator_count(synctex_iterator_p iterator);
|
||||
|
||||
/**
|
||||
* The target of the node, either a handle or a proxy.
|
||||
*/
|
||||
synctex_node_p synctex_node_target(synctex_node_p node);
|
||||
|
||||
#ifndef SYNCTEX_NO_UPDATER
|
||||
/* The main synctex updater object.
|
||||
* This object is used to append information to the synctex file.
|
||||
* Its implementation is considered private.
|
||||
* It is used by the synctex command line tool to take into account modifications
|
||||
* that could occur while postprocessing files by dvipdf like filters.
|
||||
*/
|
||||
typedef struct synctex_updater_t synctex_updater_s;
|
||||
typedef synctex_updater_s * synctex_updater_p;
|
||||
|
||||
/* Designated initializer.
|
||||
* Once you are done with your whole job,
|
||||
* free the updater */
|
||||
synctex_updater_p synctex_updater_new_with_output_file(const char * output, const char * directory);
|
||||
|
||||
/* Use the next functions to append records to the synctex file,
|
||||
* no consistency tests made on the arguments */
|
||||
void synctex_updater_append_magnification(synctex_updater_p updater, char * magnification);
|
||||
void synctex_updater_append_x_offset(synctex_updater_p updater, char * x_offset);
|
||||
void synctex_updater_append_y_offset(synctex_updater_p updater, char * y_offset);
|
||||
|
||||
/* You MUST free the updater, once everything is properly appended */
|
||||
void synctex_updater_free(synctex_updater_p updater);
|
||||
#endif
|
||||
|
||||
#if defined(SYNCTEX_DEBUG)
|
||||
# include "assert.h"
|
||||
# define SYNCTEX_ASSERT assert
|
||||
#else
|
||||
# define SYNCTEX_ASSERT(UNUSED)
|
||||
#endif
|
||||
|
||||
#if defined(SYNCTEX_TESTING)
|
||||
#warning TESTING IS PROHIBITED
|
||||
#if __clang__
|
||||
#define __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \
|
||||
_Pragma("clang diagnostic push") \
|
||||
_Pragma("clang diagnostic ignored \"-Wformat-extra-args\"")
|
||||
|
||||
#define __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS _Pragma("clang diagnostic pop")
|
||||
#else
|
||||
#define __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS
|
||||
#define __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS
|
||||
#endif
|
||||
|
||||
# define SYNCTEX_TEST_BODY(counter, condition, desc, ...) \
|
||||
do { \
|
||||
__PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \
|
||||
if (!(condition)) { \
|
||||
++counter; \
|
||||
printf("**** Test failed: %s\nfile %s\nfunction %s\nline %i\n",#condition,__FILE__,__FUNCTION__,__LINE__); \
|
||||
printf((desc), ##__VA_ARGS__); \
|
||||
} \
|
||||
__PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \
|
||||
} while(0)
|
||||
|
||||
# define SYNCTEX_TEST_PARAMETER(counter, condition) SYNCTEX_TEST_BODY(counter, (condition), "Invalid parameter not satisfying: %s", #condition)
|
||||
|
||||
int synctex_test_input(synctex_scanner_p scanner);
|
||||
int synctex_test_proxy(synctex_scanner_p scanner);
|
||||
int synctex_test_tree(synctex_scanner_p scanner);
|
||||
int synctex_test_page(synctex_scanner_p scanner);
|
||||
int synctex_test_handle(synctex_scanner_p scanner);
|
||||
int synctex_test_display_query(synctex_scanner_p scanner);
|
||||
int synctex_test_charindex();
|
||||
int synctex_test_sheet_1();
|
||||
int synctex_test_sheet_2();
|
||||
int synctex_test_sheet_3();
|
||||
int synctex_test_form();
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
3
lisp/pdf-tools/build/server/synctex_parser_local.h
Normal file
3
lisp/pdf-tools/build/server/synctex_parser_local.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#include <stdio.h>
|
||||
#define printf(fmt, args...) (fprintf (stderr, (fmt), ## args))
|
||||
#define SYNCTEX_INLINE
|
||||
204
lisp/pdf-tools/build/server/synctex_parser_readme.txt
Normal file
204
lisp/pdf-tools/build/server/synctex_parser_readme.txt
Normal file
@@ -0,0 +1,204 @@
|
||||
This file is part of the SyncTeX package.
|
||||
|
||||
Please refer to synctex_parser_readme.md
|
||||
|
||||
The Synchronization TeXnology named SyncTeX is a new feature
|
||||
of recent TeX engines designed by Jerome Laurens.
|
||||
It allows to synchronize between input and output, which means to
|
||||
navigate from the source document to the typeset material and vice versa.
|
||||
More information on http://itexmac2.sourceforge.net/SyncTeX.html
|
||||
|
||||
This package is mainly for developers, it mainly contains the following files:
|
||||
|
||||
synctex_parser_readme.txt
|
||||
synctex_parser_version.txt
|
||||
synctex_parser_utils.c
|
||||
synctex_parser_utils.h
|
||||
synctex_parser_local.h
|
||||
synctex_parser_private.h
|
||||
synctex_parser.h
|
||||
synctex_parser.c
|
||||
|
||||
The file you are reading contains more information about the SyncTeX parser history.
|
||||
|
||||
In order to support SyncTeX in a viewer, it is sufficient to include
|
||||
in the source the files synctex_parser.h and synctex_parser.c.
|
||||
The synctex parser usage is described in synctex_parser.h header file.
|
||||
|
||||
The other files are used by tex engines or by the synctex command line utility:
|
||||
|
||||
ChangeLog
|
||||
README.txt
|
||||
am
|
||||
man1
|
||||
man5
|
||||
synctex-common.h
|
||||
synctex-convert.sh
|
||||
synctex-e-mem.ch0
|
||||
synctex-e-mem.ch1
|
||||
synctex-e-rec.ch0
|
||||
synctex-e-rec.ch1
|
||||
synctex-etex.h
|
||||
synctex-mem.ch0
|
||||
synctex-mem.ch1
|
||||
synctex-mem.ch2
|
||||
synctex-pdf-rec.ch2
|
||||
synctex-pdftex.h
|
||||
synctex-rec.ch0
|
||||
synctex-rec.ch1
|
||||
synctex-rec.ch2
|
||||
synctex-tex.h
|
||||
synctex-xe-mem.ch2
|
||||
synctex-xe-rec.ch2
|
||||
synctex-xe-rec.ch3
|
||||
synctex-xetex.h
|
||||
synctex.c
|
||||
synctex.defines
|
||||
synctex.h
|
||||
synctex_main.c
|
||||
tests
|
||||
|
||||
|
||||
Version:
|
||||
--------
|
||||
This is version 1, which refers to the synctex output file format.
|
||||
The files are identified by a build number.
|
||||
In order to help developers to automatically manage the version and build numbers
|
||||
and download the parser only when necessary, the synctex_parser.version
|
||||
is an ASCII text file just containing the current version and build numbers.
|
||||
|
||||
History:
|
||||
--------
|
||||
1.1: Thu Jul 17 09:28:13 UTC 2008
|
||||
- First official version available in TeXLive 2008 DVD.
|
||||
Unfortunately, the backwards synchronization is not working properly mainly for ConTeXt users, see below.
|
||||
1.2: Tue Sep 2 10:28:32 UTC 2008
|
||||
- Correction for ConTeXt support in the edit query.
|
||||
The previous method was assuming that TeX boxes do not overlap,
|
||||
which is reasonable for LaTeX but not for ConTeXt.
|
||||
This assumption is no longer considered.
|
||||
1.3: Fri Sep 5 09:39:57 UTC 2008
|
||||
- Local variable "read" renamed to "already_read" to avoid conflicts.
|
||||
- "inline" compiler directive renamed to "SYNCTEX_INLINE" for code support and maintenance
|
||||
- _synctex_error cannot be inlined due to variable arguments (thanks Christiaan Hofman)
|
||||
- Correction in the display query, extra boundary nodes are used for a more precise forwards synchronization
|
||||
1.4: Fri Sep 12 08:12:34 UTC 2008
|
||||
- For an unknown reason, the previous version was not the real 1.3 (as used in iTeXMac2 build 747).
|
||||
As a consequence, a crash was observed.
|
||||
- Some typos are fixed.
|
||||
1.6: Mon Nov 3 20:20:02 UTC 2008
|
||||
- The bug that prevented synchronization with compressed files on windows has been fixed.
|
||||
- New interface to allow system specific customization.
|
||||
- Note that some APIs have changed.
|
||||
1.8: Mer 8 jul 2009 11:32:38 UTC
|
||||
Note that version 1.7 was delivered privately.
|
||||
- bug fix: synctex was causing a memory leak in pdftex and xetex, thus some processing speed degradation
|
||||
- bug fix: the synctex command line tool was broken when updating a .synctex file
|
||||
- enhancement: better accuracy of the synchronization process
|
||||
- enhancement: the pdf output file and the associated .synctex file no longer need to live in the same directory.
|
||||
The new -d option of the synctex command line tool manages this situation.
|
||||
This is handy when using something like tex -output-directory=DIR ...
|
||||
1.9: Wed Nov 4 11:52:35 UTC 2009
|
||||
- Various typo fixed
|
||||
- OutputDebugString replaced by OutputDebugStringA to deliberately disable unicode preprocessing
|
||||
- New conditional created because OutputDebugStringA is only available since Windows 2K professional
|
||||
1.10: Sun Jan 10 10:12:32 UTC 2010
|
||||
- Bug fix in synctex_parser.c to solve a synchronization problem with amsmath's gather environment.
|
||||
Concerns the synctex tool.
|
||||
1.11: Sun Jan 17 09:12:31 UTC 2010
|
||||
- Bug fix in synctex_parser.c, function synctex_node_box_visible_v: 'x' replaced by 'y'.
|
||||
Only 3rd party tools are concerned.
|
||||
1.12: Mon Jul 19 21:52:10 UTC 2010
|
||||
- Bug fix in synctex_parser.c, function __synctex_open: the io_mode was modified even in case of a non zero return,
|
||||
causing a void .synctex.gz file to be created even if it was not expected. Reported by Marek Kasik concerning a bug on evince.
|
||||
1.13: Fri Mar 11 07:39:12 UTC 2011
|
||||
- Bug fix in synctex_parser.c, better synchronization as suggested by Jan Sundermeyer (near line 3388).
|
||||
- Stronger code design in synctex_parser_utils.c, function _synctex_get_name (really neutral behavior).
|
||||
Only 3rd party tools are concerned.
|
||||
1.14: Fri Apr 15 19:10:57 UTC 2011
|
||||
- taking output_directory into account
|
||||
- Replaced FOPEN_WBIN_MODE by FOPEN_W_MODE when opening the text version of the .synctex file.
|
||||
- Merging with LuaTeX's version of synctex.c
|
||||
1.15: Fri Jun 10 14:10:17 UTC 2011
|
||||
This concerns the synctex command line tool and 3rd party developers.
|
||||
TeX and friends are not concerned by these changes.
|
||||
- Bug fixed in _synctex_get_io_mode_name, sometimes the wrong mode was returned
|
||||
- Support for LuaTeX convention of './' file prefixing
|
||||
1.16: Tue Jun 14 08:23:30 UTC 2011
|
||||
This concerns the synctex command line tool and 3rd party developers.
|
||||
TeX and friends are not concerned by these changes.
|
||||
- Better forward search (thanks Jose Alliste)
|
||||
- Support for LuaTeX convention of './' file prefixing now for everyone, not only for Windows
|
||||
1.17: Fri Oct 14 08:15:16 UTC 2011
|
||||
This concerns the synctex command line tool and 3rd party developers.
|
||||
TeX and friends are not concerned by these changes.
|
||||
- synctex_parser.c: cosmetic changes to enhance code readability
|
||||
- Better forward synchronization.
|
||||
The problem occurs for example with LaTeX \item command.
|
||||
The fact is that this command creates nodes at parse time but these nodes are used only
|
||||
after the text material of the \item is displayed on the page. The consequence is that sometimes,
|
||||
forward synchronization spots an irrelevant point from the point of view of the editing process.
|
||||
This was due to some very basic filtering policy, where a somehow arbitrary choice was made when
|
||||
many different possibilities where offered for synchronisation.
|
||||
Now, forward synchronization prefers nodes inside an hbox with as many acceptable spots as possible.
|
||||
This is achieved with the notion of mean line and node weight.
|
||||
- Adding support for the new file naming convention with './'
|
||||
+ function synctex_ignore_leading_dot_slash_in_path replaces synctex_ignore_leading_dot_slash
|
||||
+ function _synctex_is_equivalent_file_name is more permissive
|
||||
Previously, the function synctex_scanner_get_tag would give an answer only when
|
||||
the given file name was EXACTLY one of the file names listed in the synctex file.
|
||||
The we added some changes accepting for example 'foo.tex' instead of './foo.tex'.
|
||||
Now we have an even looser policy for dealing with file names.
|
||||
If the given file name does not match exactly one the file names of the synctex file,
|
||||
then we try to match the base names. If there is only one match of the base names,
|
||||
then it is taken as a match for the whole names.
|
||||
The base name is defined as following:
|
||||
./foo => foo
|
||||
/my///.////foo => foo
|
||||
/foo => /foo
|
||||
/my//.foo => /my//.foo
|
||||
1.17: Tue Mar 13 10:10:03 UTC 2012
|
||||
- minor changes, no version changes
|
||||
- syntax man pages are fixed as suggested by M. Shimata
|
||||
see mail to tex-live@tug.org titled "syntax.5 has many warnings from groff" and "syntax.1 use invalid macro for mdoc"
|
||||
1.17: Tue Jan 14 09:55:00 UTC 2014
|
||||
- fixed a segfault, from Sebastian Ramacher
|
||||
1.17: Mon Aug 04
|
||||
- fixed a memory leak
|
||||
1.18: Thu Jun 25 11:36:05 UTC 2015
|
||||
- nested sheets now fully supported (does it make sense in TeX)
|
||||
- cosmetic changes: uniform indentation
|
||||
- suppression of warnings, mainly long/int ones. In short, zlib likes ints when size_t likes longs.
|
||||
- CLI synctex tool can build out of TeXLive (modulo appropriate options passed to the compiler)
|
||||
1.19: Thu Mar 9 21:26:27 UTC 2017
|
||||
- the nested sheets patch was not a good solution.
|
||||
It has been moved from the parser to the engine.
|
||||
See the synctex.c source file for detailed explanations.
|
||||
- there is a new synctex format specification.
|
||||
We can see that a .synctex file can contain many times
|
||||
the same vertical position because many objects belong
|
||||
to the same line. When the options read -synctex=±2 or more,
|
||||
a very basic compression algorithm is used:
|
||||
if synctex is about write the same number then it writes
|
||||
an = sign instead. This saves approximately 10% of the
|
||||
synctex output file, either compressed or not.
|
||||
The new synctex parser has been updated accordingly.
|
||||
Actual tex frontend won't see any difference with the
|
||||
TeX engines that include this new feature.
|
||||
Frontends with the new parser won't see any difference
|
||||
with the older TeX engines.
|
||||
Frontends with the new parser will only see a difference
|
||||
with new TeX engines if -synctex=±2 or more is used.
|
||||
|
||||
Acknowledgments:
|
||||
----------------
|
||||
The author received useful remarks from the pdfTeX developers, especially Hahn The Thanh,
|
||||
and significant help from XeTeX developer Jonathan Kew
|
||||
|
||||
Nota Bene:
|
||||
----------
|
||||
If you include or use a significant part of the synctex package into a software,
|
||||
I would appreciate to be listed as contributor and see "SyncTeX" highlighted.
|
||||
|
||||
Copyright (c) 2008-2014 jerome DOT laurens AT u-bourgogne DOT fr
|
||||
|
||||
570
lisp/pdf-tools/build/server/synctex_parser_utils.c
Normal file
570
lisp/pdf-tools/build/server/synctex_parser_utils.c
Normal file
@@ -0,0 +1,570 @@
|
||||
/*
|
||||
Copyright (c) 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr
|
||||
|
||||
This file is part of the __SyncTeX__ package.
|
||||
|
||||
[//]: # (Latest Revision: Fri Jul 14 16:20:41 UTC 2017)
|
||||
[//]: # (Version: 1.21)
|
||||
|
||||
See `synctex_parser_readme.md` for more details
|
||||
|
||||
## License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE
|
||||
|
||||
Except as contained in this notice, the name of the copyright holder
|
||||
shall not be used in advertising or otherwise to promote the sale,
|
||||
use or other dealings in this Software without prior written
|
||||
authorization from the copyright holder.
|
||||
|
||||
*/
|
||||
|
||||
/* In this file, we find all the functions that may depend on the operating system. */
|
||||
|
||||
#include <synctex_parser_utils.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__)
|
||||
#define SYNCTEX_WINDOWS 1
|
||||
#endif
|
||||
|
||||
#if defined(__OS2__)
|
||||
#define SYNCTEX_OS2 1
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define SYNCTEX_RECENT_WINDOWS 1
|
||||
#endif
|
||||
|
||||
#ifdef SYNCTEX_WINDOWS
|
||||
#include <windows.h>
|
||||
#include <shlwapi.h> /* Use shlwapi.lib */
|
||||
#endif
|
||||
|
||||
void *_synctex_malloc(size_t size) {
|
||||
void * ptr = malloc(size);
|
||||
if(ptr) {
|
||||
memset(ptr,0, size);/* ensures null termination of strings */
|
||||
}
|
||||
return (void *)ptr;
|
||||
}
|
||||
|
||||
void _synctex_free(void * ptr) {
|
||||
if (ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(_WIN32)
|
||||
# include <syslog.h>
|
||||
#endif
|
||||
|
||||
int _synctex_log(int level, const char * prompt, const char * reason,va_list arg) {
|
||||
int result;
|
||||
# ifdef SYNCTEX_RECENT_WINDOWS
|
||||
{/* This code is contributed by William Blum.
|
||||
As it does not work on some older computers,
|
||||
the _WIN32 conditional here is replaced with a SYNCTEX_RECENT_WINDOWS one.
|
||||
According to http://msdn.microsoft.com/en-us/library/aa363362(VS.85).aspx
|
||||
Minimum supported client Windows 2000 Professional
|
||||
Minimum supported server Windows 2000 Server
|
||||
People running Windows 2K standard edition will not have OutputDebugStringA.
|
||||
JL.*/
|
||||
char *buff;
|
||||
size_t len;
|
||||
OutputDebugStringA(prompt);
|
||||
len = _vscprintf(reason, arg) + 1;
|
||||
buff = (char*)malloc( len * sizeof(char) );
|
||||
result = vsprintf(buff, reason, arg) +strlen(prompt);
|
||||
OutputDebugStringA(buff);
|
||||
OutputDebugStringA("\n");
|
||||
free(buff);
|
||||
}
|
||||
# elif SYNCTEX_USE_SYSLOG
|
||||
char * buffer1 = NULL;
|
||||
char * buffer2 = NULL;
|
||||
openlog ("SyncTeX", LOG_CONS | LOG_PID | LOG_PERROR | LOG_NDELAY, LOG_LOCAL0);
|
||||
if (vasprintf(&buffer1,reason,arg)>=0
|
||||
&& asprintf(&buffer2,"%s%s",prompt, buffer1)>=0) {
|
||||
syslog (level, "%s", buffer2);
|
||||
result = (int)strlen(buffer2);
|
||||
} else {
|
||||
syslog (level, "%s",prompt);
|
||||
vsyslog(level,reason,arg);
|
||||
result = (int)strlen(prompt);
|
||||
}
|
||||
free(buffer1);
|
||||
free(buffer2);
|
||||
closelog();
|
||||
# else
|
||||
FILE * where = level == LOG_ERR? stderr: stdout;
|
||||
result = fputs(prompt,where);
|
||||
result += vfprintf(where, reason, arg);
|
||||
result += fprintf(where,"\n");
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
|
||||
int _synctex_error(const char * reason,...) {
|
||||
va_list arg;
|
||||
int result;
|
||||
va_start (arg, reason);
|
||||
#if defined(SYNCTEX_RECENT_WINDOWS) /* LOG_ERR is not used */
|
||||
result = _synctex_log(0, "! SyncTeX Error : ", reason, arg);
|
||||
#else
|
||||
result = _synctex_log(LOG_ERR, "! SyncTeX Error : ", reason, arg);
|
||||
#endif
|
||||
va_end (arg);
|
||||
return result;
|
||||
}
|
||||
|
||||
int _synctex_debug(const char * reason,...) {
|
||||
va_list arg;
|
||||
int result;
|
||||
va_start (arg, reason);
|
||||
#if defined(SYNCTEX_RECENT_WINDOWS) /* LOG_DEBUG is not used */
|
||||
result = _synctex_log(0, "! SyncTeX Error : ", reason, arg);
|
||||
#else
|
||||
result = _synctex_log(LOG_DEBUG, "! SyncTeX Error : ", reason, arg);
|
||||
#endif
|
||||
va_end (arg);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* strip the last extension of the given string, this string is modified! */
|
||||
void _synctex_strip_last_path_extension(char * string) {
|
||||
if(NULL != string){
|
||||
char * last_component = NULL;
|
||||
char * last_extension = NULL;
|
||||
# if defined(SYNCTEX_WINDOWS)
|
||||
last_component = PathFindFileName(string);
|
||||
last_extension = PathFindExtension(string);
|
||||
if(last_extension == NULL)return;
|
||||
if(last_component == NULL)last_component = string;
|
||||
if(last_extension>last_component){/* filter out paths like "my/dir/.hidden" */
|
||||
last_extension[0] = '\0';
|
||||
}
|
||||
# else
|
||||
char * next = NULL;
|
||||
/* first we find the last path component */
|
||||
if(NULL == (last_component = strstr(string,"/"))){
|
||||
last_component = string;
|
||||
} else {
|
||||
++last_component;
|
||||
while((next = strstr(last_component,"/"))){
|
||||
last_component = next+1;
|
||||
}
|
||||
}
|
||||
# if defined(SYNCTEX_OS2)
|
||||
/* On OS2, the '\' is also a path separator. */
|
||||
while((next = strstr(last_component,"\\"))){
|
||||
last_component = next+1;
|
||||
}
|
||||
# endif /* SYNCTEX_OS2 */
|
||||
/* then we find the last path extension */
|
||||
if((last_extension = strstr(last_component,"."))){
|
||||
++last_extension;
|
||||
while((next = strstr(last_extension,"."))){
|
||||
last_extension = next+1;
|
||||
}
|
||||
--last_extension;/* back to the "." */
|
||||
if(last_extension>last_component){/* filter out paths like ....my/dir/.hidden"*/
|
||||
last_extension[0] = '\0';
|
||||
}
|
||||
}
|
||||
# endif /* SYNCTEX_WINDOWS */
|
||||
}
|
||||
}
|
||||
|
||||
synctex_bool_t synctex_ignore_leading_dot_slash_in_path(const char ** name_ref)
|
||||
{
|
||||
if (SYNCTEX_IS_DOT((*name_ref)[0]) && SYNCTEX_IS_PATH_SEPARATOR((*name_ref)[1])) {
|
||||
do {
|
||||
(*name_ref) += 2;
|
||||
while (SYNCTEX_IS_PATH_SEPARATOR((*name_ref)[0])) {
|
||||
++(*name_ref);
|
||||
}
|
||||
} while(SYNCTEX_IS_DOT((*name_ref)[0]) && SYNCTEX_IS_PATH_SEPARATOR((*name_ref)[1]));
|
||||
return synctex_YES;
|
||||
}
|
||||
return synctex_NO;
|
||||
}
|
||||
|
||||
/* The base name is necessary to deal with the 2011 file naming convention...
|
||||
* path is a '\0' terminated string
|
||||
* The return value is the trailing part of the argument,
|
||||
* just following the first occurrence of the regexp pattern "[^|/|\].[\|/]+".*/
|
||||
const char * _synctex_base_name(const char *path) {
|
||||
const char * ptr = path;
|
||||
do {
|
||||
if (synctex_ignore_leading_dot_slash_in_path(&ptr)) {
|
||||
return ptr;
|
||||
}
|
||||
do {
|
||||
if (!*(++ptr)) {
|
||||
return path;
|
||||
}
|
||||
} while (!SYNCTEX_IS_PATH_SEPARATOR(*ptr));
|
||||
} while (*(++ptr));
|
||||
return path;
|
||||
}
|
||||
|
||||
/* Compare two file names, windows is sometimes case insensitive... */
|
||||
synctex_bool_t _synctex_is_equivalent_file_name(const char *lhs, const char *rhs) {
|
||||
/* Remove the leading regex '(\./+)*' in both rhs and lhs */
|
||||
synctex_ignore_leading_dot_slash_in_path(&lhs);
|
||||
synctex_ignore_leading_dot_slash_in_path(&rhs);
|
||||
next_character:
|
||||
if (SYNCTEX_IS_PATH_SEPARATOR(*lhs)) {/* lhs points to a path separator */
|
||||
if (!SYNCTEX_IS_PATH_SEPARATOR(*rhs)) {/* but not rhs */
|
||||
return synctex_NO;
|
||||
}
|
||||
++lhs;
|
||||
++rhs;
|
||||
synctex_ignore_leading_dot_slash_in_path(&lhs);
|
||||
synctex_ignore_leading_dot_slash_in_path(&rhs);
|
||||
goto next_character;
|
||||
} else if (SYNCTEX_IS_PATH_SEPARATOR(*rhs)) {/* rhs points to a path separator but not lhs */
|
||||
return synctex_NO;
|
||||
} else if (SYNCTEX_ARE_PATH_CHARACTERS_EQUAL(*lhs,*rhs)){/* uppercase do not match */
|
||||
return synctex_NO;
|
||||
} else if (!*lhs) {/* lhs is at the end of the string */
|
||||
return *rhs ? synctex_NO : synctex_YES;
|
||||
} else if(!*rhs) {/* rhs is at the end of the string but not lhs */
|
||||
return synctex_NO;
|
||||
}
|
||||
++lhs;
|
||||
++rhs;
|
||||
goto next_character;
|
||||
}
|
||||
|
||||
synctex_bool_t _synctex_path_is_absolute(const char * name) {
|
||||
if(!strlen(name)) {
|
||||
return synctex_NO;
|
||||
}
|
||||
# if defined(SYNCTEX_WINDOWS) || defined(SYNCTEX_OS2)
|
||||
if(strlen(name)>2) {
|
||||
return (name[1]==':' && SYNCTEX_IS_PATH_SEPARATOR(name[2]))?synctex_YES:synctex_NO;
|
||||
}
|
||||
return synctex_NO;
|
||||
# else
|
||||
return SYNCTEX_IS_PATH_SEPARATOR(name[0])?synctex_YES:synctex_NO;
|
||||
# endif
|
||||
}
|
||||
|
||||
/* We do not take care of UTF-8 */
|
||||
const char * _synctex_last_path_component(const char * name) {
|
||||
const char * c = name+strlen(name);
|
||||
if(c>name) {
|
||||
if(!SYNCTEX_IS_PATH_SEPARATOR(*c)) {
|
||||
do {
|
||||
--c;
|
||||
if(SYNCTEX_IS_PATH_SEPARATOR(*c)) {
|
||||
return c+1;
|
||||
}
|
||||
} while(c>name);
|
||||
}
|
||||
return c;/* the last path component is the void string*/
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
int _synctex_copy_with_quoting_last_path_component(const char * src, char ** dest_ref, size_t size) {
|
||||
if(src && dest_ref) {
|
||||
const char * lpc;
|
||||
# define dest (*dest_ref)
|
||||
dest = NULL; /* Default behavior: no change and success. */
|
||||
lpc = _synctex_last_path_component(src);
|
||||
if(strlen(lpc)) {
|
||||
if(strchr(lpc,' ') && lpc[0]!='"' && lpc[strlen(lpc)-1]!='"') {
|
||||
/* We are in the situation where adding the quotes is allowed. */
|
||||
/* Time to add the quotes. */
|
||||
/* Consistency test: we must have dest+size>dest+strlen(dest)+2
|
||||
* or equivalently: strlen(dest)+2<size (see below) */
|
||||
if(strlen(src)<size) {
|
||||
if((dest = (char *)malloc(size+2))) {
|
||||
char * dpc = dest + (lpc-src); /* dpc is the last path component of dest. */
|
||||
if(dest != strncpy(dest,src,size)) {
|
||||
_synctex_error("! _synctex_copy_with_quoting_last_path_component: Copy problem");
|
||||
free(dest);
|
||||
dest = NULL;/* Don't forget to reinitialize. */
|
||||
return -2;
|
||||
}
|
||||
memmove(dpc+1,dpc,strlen(dpc)+1); /* Also move the null terminating character. */
|
||||
dpc[0]='"';
|
||||
dpc[strlen(dpc)+1]='\0';/* Consistency test */
|
||||
dpc[strlen(dpc)]='"';
|
||||
return 0; /* Success. */
|
||||
}
|
||||
return -1; /* Memory allocation error. */
|
||||
}
|
||||
_synctex_error("! _synctex_copy_with_quoting_last_path_component: Internal inconsistency");
|
||||
return -3;
|
||||
}
|
||||
return 0; /* Success. */
|
||||
}
|
||||
return 0; /* No last path component. */
|
||||
# undef dest
|
||||
}
|
||||
return 1; /* Bad parameter, this value is subject to changes. */
|
||||
}
|
||||
|
||||
/* The client is responsible of the management of the returned string, if any. */
|
||||
char * _synctex_merge_strings(const char * first,...);
|
||||
|
||||
char * _synctex_merge_strings(const char * first,...) {
|
||||
va_list arg;
|
||||
size_t size = 0;
|
||||
const char * temp;
|
||||
/* First retrieve the size necessary to store the merged string */
|
||||
va_start (arg, first);
|
||||
temp = first;
|
||||
do {
|
||||
size_t len = strlen(temp);
|
||||
if(UINT_MAX-len<size) {
|
||||
_synctex_error("! _synctex_merge_strings: Capacity exceeded.");
|
||||
return NULL;
|
||||
}
|
||||
size+=len;
|
||||
} while( (temp = va_arg(arg, const char *)) != NULL);
|
||||
va_end(arg);
|
||||
if(size>0) {
|
||||
char * result = NULL;
|
||||
++size;
|
||||
/* Create the memory storage */
|
||||
if(NULL!=(result = (char *)malloc(size))) {
|
||||
char * dest = result;
|
||||
va_start (arg, first);
|
||||
temp = first;
|
||||
do {
|
||||
if((size = strlen(temp))>0) {
|
||||
/* There is something to merge */
|
||||
if(dest != strncpy(dest,temp,size)) {
|
||||
_synctex_error("! _synctex_merge_strings: Copy problem");
|
||||
free(result);
|
||||
result = NULL;
|
||||
return NULL;
|
||||
}
|
||||
dest += size;
|
||||
}
|
||||
} while( (temp = va_arg(arg, const char *)) != NULL);
|
||||
va_end(arg);
|
||||
dest[0]='\0';/* Terminate the merged string */
|
||||
return result;
|
||||
}
|
||||
_synctex_error("! _synctex_merge_strings: Memory problem");
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The purpose of _synctex_get_name is to find the name of the synctex file.
|
||||
* There is a list of possible filenames from which we return the most recent one and try to remove all the others.
|
||||
* With two runs of pdftex or xetex we are sure the the synctex file is really the most appropriate.
|
||||
*/
|
||||
int _synctex_get_name(const char * output, const char * build_directory, char ** synctex_name_ref, synctex_io_mode_t * io_mode_ref)
|
||||
{
|
||||
if(output && synctex_name_ref && io_mode_ref) {
|
||||
/* If output is already absolute, we just have to manage the quotes and the compress mode */
|
||||
size_t size = 0;
|
||||
char * synctex_name = NULL;
|
||||
synctex_io_mode_t io_mode = *io_mode_ref;
|
||||
const char * base_name = _synctex_last_path_component(output); /* do not free, output is the owner. base name of output*/
|
||||
/* Do we have a real base name ? */
|
||||
if(strlen(base_name)>0) {
|
||||
/* Yes, we do. */
|
||||
const char * temp = NULL;
|
||||
char * core_name = NULL; /* base name of output without path extension. */
|
||||
char * dir_name = NULL; /* dir name of output */
|
||||
char * quoted_core_name = NULL;
|
||||
char * basic_name = NULL;
|
||||
char * gz_name = NULL;
|
||||
char * quoted_name = NULL;
|
||||
char * quoted_gz_name = NULL;
|
||||
char * build_name = NULL;
|
||||
char * build_gz_name = NULL;
|
||||
char * build_quoted_name = NULL;
|
||||
char * build_quoted_gz_name = NULL;
|
||||
struct stat buf;
|
||||
time_t the_time = 0;
|
||||
/* Create core_name: let temp point to the dot before the path extension of base_name;
|
||||
* We start form the \0 terminating character and scan the string upward until we find a dot.
|
||||
* The leading dot is not accepted. */
|
||||
if((temp = strrchr(base_name,'.')) && (size = temp - base_name)>0) {
|
||||
/* There is a dot and it is not at the leading position */
|
||||
if(NULL == (core_name = (char *)malloc(size+1))) {
|
||||
_synctex_error("! _synctex_get_name: Memory problem 1");
|
||||
return -1;
|
||||
}
|
||||
if(core_name != strncpy(core_name,base_name,size)) {
|
||||
_synctex_error("! _synctex_get_name: Copy problem 1");
|
||||
free(core_name);
|
||||
dir_name = NULL;
|
||||
return -2;
|
||||
}
|
||||
core_name[size] = '\0';
|
||||
} else {
|
||||
/* There is no path extension,
|
||||
* Just make a copy of base_name */
|
||||
core_name = _synctex_merge_strings(base_name);
|
||||
}
|
||||
/* core_name is properly set up, owned by "self". */
|
||||
/* creating dir_name. */
|
||||
size = strlen(output)-strlen(base_name);
|
||||
if(size>0) {
|
||||
/* output contains more than one path component */
|
||||
if(NULL == (dir_name = (char *)malloc(size+1))) {
|
||||
_synctex_error("! _synctex_get_name: Memory problem");
|
||||
free(core_name);
|
||||
return -1;
|
||||
}
|
||||
if(dir_name != strncpy(dir_name,output,size)) {
|
||||
_synctex_error("! _synctex_get_name: Copy problem");
|
||||
free(dir_name);
|
||||
dir_name = NULL;
|
||||
free(core_name);
|
||||
dir_name = NULL;
|
||||
return -2;
|
||||
}
|
||||
dir_name[size] = '\0';
|
||||
}
|
||||
/* dir_name is properly set up. It ends with a path separator, if non void. */
|
||||
/* creating quoted_core_name. */
|
||||
if(strchr(core_name,' ')) {
|
||||
quoted_core_name = _synctex_merge_strings("\"",core_name,"\"");
|
||||
}
|
||||
/* quoted_core_name is properly set up. */
|
||||
if(dir_name &&strlen(dir_name)>0) {
|
||||
basic_name = _synctex_merge_strings(dir_name,core_name,synctex_suffix,NULL);
|
||||
if(quoted_core_name && strlen(quoted_core_name)>0) {
|
||||
quoted_name = _synctex_merge_strings(dir_name,quoted_core_name,synctex_suffix,NULL);
|
||||
}
|
||||
} else {
|
||||
basic_name = _synctex_merge_strings(core_name,synctex_suffix,NULL);
|
||||
if(quoted_core_name && strlen(quoted_core_name)>0) {
|
||||
quoted_name = _synctex_merge_strings(quoted_core_name,synctex_suffix,NULL);
|
||||
}
|
||||
}
|
||||
if(!_synctex_path_is_absolute(output) && build_directory && (size = strlen(build_directory))) {
|
||||
temp = build_directory + size - 1;
|
||||
if(_synctex_path_is_absolute(temp)) {
|
||||
build_name = _synctex_merge_strings(build_directory,basic_name,NULL);
|
||||
if(quoted_core_name && strlen(quoted_core_name)>0) {
|
||||
build_quoted_name = _synctex_merge_strings(build_directory,quoted_name,NULL);
|
||||
}
|
||||
} else {
|
||||
build_name = _synctex_merge_strings(build_directory,"/",basic_name,NULL);
|
||||
if(quoted_core_name && strlen(quoted_core_name)>0) {
|
||||
build_quoted_name = _synctex_merge_strings(build_directory,"/",quoted_name,NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(basic_name) {
|
||||
gz_name = _synctex_merge_strings(basic_name,synctex_suffix_gz,NULL);
|
||||
}
|
||||
if(quoted_name) {
|
||||
quoted_gz_name = _synctex_merge_strings(quoted_name,synctex_suffix_gz,NULL);
|
||||
}
|
||||
if(build_name) {
|
||||
build_gz_name = _synctex_merge_strings(build_name,synctex_suffix_gz,NULL);
|
||||
}
|
||||
if(build_quoted_name) {
|
||||
build_quoted_gz_name = _synctex_merge_strings(build_quoted_name,synctex_suffix_gz,NULL);
|
||||
}
|
||||
/* All the others names are properly set up... */
|
||||
/* retain the most recently modified file */
|
||||
# define TEST(FILENAME,COMPRESS_MODE) \
|
||||
if(FILENAME) {\
|
||||
if (stat(FILENAME, &buf)) { \
|
||||
free(FILENAME);\
|
||||
FILENAME = NULL;\
|
||||
} else if (buf.st_mtime>the_time) { \
|
||||
the_time=buf.st_mtime; \
|
||||
synctex_name = FILENAME; \
|
||||
if (COMPRESS_MODE) { \
|
||||
io_mode |= synctex_io_gz_mask; \
|
||||
} else { \
|
||||
io_mode &= ~synctex_io_gz_mask; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
TEST(basic_name,synctex_DONT_COMPRESS);
|
||||
TEST(gz_name,synctex_COMPRESS);
|
||||
TEST(quoted_name,synctex_DONT_COMPRESS);
|
||||
TEST(quoted_gz_name,synctex_COMPRESS);
|
||||
TEST(build_name,synctex_DONT_COMPRESS);
|
||||
TEST(build_gz_name,synctex_COMPRESS);
|
||||
TEST(build_quoted_name,synctex_DONT_COMPRESS);
|
||||
TEST(build_quoted_gz_name,synctex_COMPRESS);
|
||||
# undef TEST
|
||||
/* Free all the intermediate filenames, except the one that will be used as returned value. */
|
||||
# define CLEAN_AND_REMOVE(FILENAME) \
|
||||
if(FILENAME && (FILENAME!=synctex_name)) {\
|
||||
remove(FILENAME);\
|
||||
printf("synctex tool info: %s removed\n",FILENAME);\
|
||||
free(FILENAME);\
|
||||
FILENAME = NULL;\
|
||||
}
|
||||
CLEAN_AND_REMOVE(basic_name);
|
||||
CLEAN_AND_REMOVE(gz_name);
|
||||
CLEAN_AND_REMOVE(quoted_name);
|
||||
CLEAN_AND_REMOVE(quoted_gz_name);
|
||||
CLEAN_AND_REMOVE(build_name);
|
||||
CLEAN_AND_REMOVE(build_gz_name);
|
||||
CLEAN_AND_REMOVE(build_quoted_name);
|
||||
CLEAN_AND_REMOVE(build_quoted_gz_name);
|
||||
# undef CLEAN_AND_REMOVE
|
||||
/* set up the returned values */
|
||||
* synctex_name_ref = synctex_name;
|
||||
/* synctex_name won't always end in .gz, even when compressed. */
|
||||
FILE * F = fopen(synctex_name, "r");
|
||||
if (F != NULL) {
|
||||
if (!feof(F)
|
||||
&& 31 == fgetc(F)
|
||||
&& !feof(F)
|
||||
&& 139 == fgetc(F)) {
|
||||
io_mode = synctex_compress_mode_gz;
|
||||
}
|
||||
fclose(F);
|
||||
}
|
||||
* io_mode_ref = io_mode;
|
||||
return 0;
|
||||
}
|
||||
return -1;/* bad argument */
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
const char * _synctex_get_io_mode_name(synctex_io_mode_t io_mode) {
|
||||
static const char * synctex_io_modes[4] = {"r","rb","a","ab"};
|
||||
unsigned index = ((io_mode & synctex_io_gz_mask)?1:0) + ((io_mode & synctex_io_append_mask)?2:0);// bug pointed out by Jose Alliste
|
||||
return synctex_io_modes[index];
|
||||
}
|
||||
163
lisp/pdf-tools/build/server/synctex_parser_utils.h
Normal file
163
lisp/pdf-tools/build/server/synctex_parser_utils.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
Copyright (c) 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr
|
||||
|
||||
This file is part of the __SyncTeX__ package.
|
||||
|
||||
[//]: # (Latest Revision: Fri Jul 14 16:20:41 UTC 2017)
|
||||
[//]: # (Version: 1.21)
|
||||
|
||||
See `synctex_parser_readme.md` for more details
|
||||
|
||||
## License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE
|
||||
|
||||
Except as contained in this notice, the name of the copyright holder
|
||||
shall not be used in advertising or otherwise to promote the sale,
|
||||
use or other dealings in this Software without prior written
|
||||
authorization from the copyright holder.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SYNCTEX_PARSER_UTILS_H
|
||||
#define SYNCTEX_PARSER_UTILS_H
|
||||
|
||||
/* The utilities declared here are subject to conditional implementation.
|
||||
* All the operating system special stuff goes here.
|
||||
* The problem mainly comes from file name management: path separator, encoding...
|
||||
*/
|
||||
|
||||
#include "synctex_version.h"
|
||||
|
||||
typedef int synctex_bool_t;
|
||||
# define synctex_YES (0==0)
|
||||
# define synctex_NO (0==1)
|
||||
|
||||
# define synctex_ADD_QUOTES -1
|
||||
# define synctex_COMPRESS -1
|
||||
# define synctex_DONT_ADD_QUOTES 0
|
||||
# define synctex_DONT_COMPRESS 0
|
||||
|
||||
#ifndef __SYNCTEX_PARSER_UTILS__
|
||||
# define __SYNCTEX_PARSER_UTILS__
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
# if defined(_WIN32) || defined(__OS2__)
|
||||
# define SYNCTEX_CASE_SENSITIVE_PATH 0
|
||||
# define SYNCTEX_IS_PATH_SEPARATOR(c) ('/' == c || '\\' == c)
|
||||
# else
|
||||
# define SYNCTEX_CASE_SENSITIVE_PATH 1
|
||||
# define SYNCTEX_IS_PATH_SEPARATOR(c) ('/' == c)
|
||||
# endif
|
||||
|
||||
# if defined(_WIN32) || defined(__OS2__)
|
||||
# define SYNCTEX_IS_DOT(c) ('.' == c)
|
||||
# else
|
||||
# define SYNCTEX_IS_DOT(c) ('.' == c)
|
||||
# endif
|
||||
|
||||
# if SYNCTEX_CASE_SENSITIVE_PATH
|
||||
# define SYNCTEX_ARE_PATH_CHARACTERS_EQUAL(left,right) (left != right)
|
||||
# else
|
||||
# define SYNCTEX_ARE_PATH_CHARACTERS_EQUAL(left,right) (toupper(left) != toupper(right))
|
||||
# endif
|
||||
|
||||
/* This custom malloc functions initializes to 0 the newly allocated memory.
|
||||
* There is no bzero function on windows. */
|
||||
void *_synctex_malloc(size_t size);
|
||||
|
||||
/* To balance _synctex_malloc.
|
||||
* ptr might be NULL. */
|
||||
void _synctex_free(void * ptr);
|
||||
|
||||
/* This is used to log some informational message to the standard error stream.
|
||||
* On Windows, the stderr stream is not exposed and another method is used.
|
||||
* The return value is the number of characters printed. */
|
||||
int _synctex_error(const char * reason,...);
|
||||
int _synctex_debug(const char * reason,...);
|
||||
|
||||
/* strip the last extension of the given string, this string is modified!
|
||||
* This function depends on the OS because the path separator may differ.
|
||||
* This should be discussed more precisely. */
|
||||
void _synctex_strip_last_path_extension(char * string);
|
||||
|
||||
/* Compare two file names, windows is sometimes case insensitive...
|
||||
* The given strings may differ stricto sensu, but represent the same file name.
|
||||
* It might not be the real way of doing things.
|
||||
* The return value is an undefined non 0 value when the two file names are equivalent.
|
||||
* It is 0 otherwise. */
|
||||
synctex_bool_t _synctex_is_equivalent_file_name(const char *lhs, const char *rhs);
|
||||
|
||||
/* Description forthcoming.*/
|
||||
synctex_bool_t _synctex_path_is_absolute(const char * name);
|
||||
|
||||
/* Description forthcoming...*/
|
||||
const char * _synctex_last_path_component(const char * name);
|
||||
|
||||
/* Description forthcoming...*/
|
||||
const char * _synctex_base_name(const char *path);
|
||||
|
||||
/* If the core of the last path component of src is not already enclosed with double quotes ('"')
|
||||
* and contains a space character (' '), then a new buffer is created, the src is copied and quotes are added.
|
||||
* In all other cases, no destination buffer is created and the src is not copied.
|
||||
* 0 on success, which means no error, something non 0 means error, mainly due to memory allocation failure, or bad parameter.
|
||||
* This is used to fix a bug in the first version of pdftex with synctex (1.40.9) for which names with spaces
|
||||
* were not managed in a standard way.
|
||||
* On success, the caller owns the buffer pointed to by dest_ref (is any) and
|
||||
* is responsible of freeing the memory when done.
|
||||
* The size argument is the size of the src buffer. On return the dest_ref points to a buffer sized size+2.*/
|
||||
int _synctex_copy_with_quoting_last_path_component(const char * src, char ** dest_ref, size_t size);
|
||||
|
||||
/* These are the possible extensions of the synctex file */
|
||||
extern const char * synctex_suffix;
|
||||
extern const char * synctex_suffix_gz;
|
||||
|
||||
typedef unsigned int synctex_io_mode_t;
|
||||
|
||||
typedef enum {
|
||||
synctex_io_append_mask = 1,
|
||||
synctex_io_gz_mask = synctex_io_append_mask<<1
|
||||
} synctex_io_mode_masks_t;
|
||||
|
||||
typedef enum {
|
||||
synctex_compress_mode_none = 0,
|
||||
synctex_compress_mode_gz = 1
|
||||
} synctex_compress_mode_t;
|
||||
|
||||
int _synctex_get_name(const char * output, const char * build_directory, char ** synctex_name_ref, synctex_io_mode_t * io_mode_ref);
|
||||
|
||||
/* returns the correct mode required by fopen and gzopen from the given io_mode */
|
||||
const char * _synctex_get_io_mode_name(synctex_io_mode_t io_mode);
|
||||
|
||||
synctex_bool_t synctex_ignore_leading_dot_slash_in_path(const char ** name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* SYNCTEX_PARSER_UTILS_H */
|
||||
1
lisp/pdf-tools/build/server/synctex_parser_version.txt
Normal file
1
lisp/pdf-tools/build/server/synctex_parser_version.txt
Normal file
@@ -0,0 +1 @@
|
||||
1.21
|
||||
59
lisp/pdf-tools/build/server/synctex_version.h
Normal file
59
lisp/pdf-tools/build/server/synctex_version.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright (c) 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr
|
||||
|
||||
This file is part of the __SyncTeX__ package.
|
||||
|
||||
[//]: # (Latest Revision: Fri Jul 14 16:20:41 UTC 2017)
|
||||
[//]: # (Version: 1.21)
|
||||
|
||||
See `synctex_parser_readme.md` for more details
|
||||
|
||||
## License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE
|
||||
|
||||
Except as contained in this notice, the name of the copyright holder
|
||||
shall not be used in advertising or otherwise to promote the sale,
|
||||
use or other dealings in this Software without prior written
|
||||
authorization from the copyright holder.
|
||||
|
||||
## Acknowledgments:
|
||||
|
||||
The author received useful remarks from the __pdfTeX__ developers, especially Hahn The Thanh,
|
||||
and significant help from __XeTeX__ developer Jonathan Kew.
|
||||
|
||||
## Nota Bene:
|
||||
|
||||
If you include or use a significant part of the __SyncTeX__ package into a software,
|
||||
I would appreciate to be listed as contributor and see "__SyncTeX__" highlighted.
|
||||
*/
|
||||
|
||||
#ifndef __SYNCTEX_VERSION__
|
||||
# define __SYNCTEX_VERSION__
|
||||
|
||||
# define SYNCTEX_VERSION_MAJOR 1
|
||||
|
||||
# define SYNCTEX_VERSION_STRING "1.21"
|
||||
|
||||
# define SYNCTEX_CLI_VERSION_STRING "1.5"
|
||||
|
||||
#endif
|
||||
2
lisp/pdf-tools/build/server/test/docker/.gitignore
vendored
Normal file
2
lisp/pdf-tools/build/server/test/docker/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.Dockerfile
|
||||
*.build
|
||||
9
lisp/pdf-tools/build/server/test/docker/lib/run-tests
Executable file
9
lisp/pdf-tools/build/server/test/docker/lib/run-tests
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
PATH="$(dirname "$0")":$PATH
|
||||
|
||||
set -e
|
||||
|
||||
yes-or-enter | ./autobuild -i /bin
|
||||
yes-or-enter | ./autobuild -i /usr/bin | \
|
||||
grep -q "Skipping package installation (already installed)"
|
||||
9
lisp/pdf-tools/build/server/test/docker/lib/yes-or-enter
Executable file
9
lisp/pdf-tools/build/server/test/docker/lib/yes-or-enter
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Step over prompts from the package-manager.
|
||||
if [ -f /etc/arch-release ]; then
|
||||
yes ''
|
||||
else
|
||||
yes
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
ADD . /epdfinfo
|
||||
WORKDIR /epdfinfo
|
||||
RUN make -s distclean || true
|
||||
CMD ["sh", "./test/docker/lib/run-tests"]
|
||||
@@ -0,0 +1,6 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM base/archlinux
|
||||
RUN pacman -Syu --noconfirm --noprogressbar && \
|
||||
pacman -S --noconfirm --noprogressbar poppler-glib base-devel
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM centos:7
|
||||
RUN yum update -y && yum install -y gcc gcc-c++ poppler-glib-devel
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM debian:8
|
||||
RUN apt-get update -y && apt-get install -y gcc g++ libpoppler-glib-dev
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM debian:9
|
||||
RUN apt-get update -y && apt-get install -y gcc g++ libpoppler-glib-dev
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM fedora:24
|
||||
RUN dnf update -y && dnf install -y gcc gcc-c++ poppler-glib-devel
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM fedora:25
|
||||
RUN dnf update -y && dnf install -y gcc gcc-c++ poppler-glib-devel
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM fedora:26
|
||||
RUN dnf update -y && dnf install -y gcc gcc-c++ poppler-glib-devel
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM gentoo/stage3-amd64
|
||||
RUN emerge --sync && emerge sys-devel/gcc app-text/poppler
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM ubuntu:trusty
|
||||
RUN apt-get update -y && apt-get install -y gcc g++ libpoppler-glib-dev
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM ubuntu:xenial
|
||||
RUN apt-get update -y && apt-get install -y gcc g++ libpoppler-glib-dev
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- dockerfile -*-
|
||||
FROM ubuntu:artful
|
||||
RUN apt-get update -y && apt-get install -y gcc g++ libpoppler-glib-dev
|
||||
|
||||
Reference in New Issue
Block a user