diff options
Diffstat (limited to 'Build/source/utils/psutils/psutils-1.21')
29 files changed, 6496 insertions, 0 deletions
diff --git a/Build/source/utils/psutils/psutils-1.21/LICENSE b/Build/source/utils/psutils/psutils-1.21/LICENSE new file mode 100644 index 00000000000..cf532202464 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/LICENSE @@ -0,0 +1,27 @@ + PS Utilities Package + +PSUtils is copyright (C) 1991-1997 Angus J. C. Duggan, and (c) 2012-2013 +Reuben Thomas <rrt@sc3d.org> + +It may be copied and used for any purpose (including distribution as part of +a for-profit product), provided: + +1) The original attribution of the programs is clearly displayed in the product + and/or documentation, even if the programs are modified and/or renamed as + part of the product. + +2) The original source code of the programs is provided free of charge (except + for reasonable distribution costs). For a definition of reasonable + distribution costs, see the Gnu General Public License or Larry Wall's + Artistic License (provided with the Perl 4 kit). The GPL and Artistic + License in NO WAY affect this license; they are merely used as examples of + the spirit in which it is intended. + +3) These programs are provided "as-is". No warranty or guarantee of their + fitness for any particular task is provided. Use of these programs is + completely at your own risk. + +Basically, I don't mind how you use the programs so long as you acknowledge +the author, and give people the originals if they want them. + + AJCD 4/4/95 diff --git a/Build/source/utils/psutils/psutils-1.21/Makefile.am b/Build/source/utils/psutils/psutils-1.21/Makefile.am new file mode 100644 index 00000000000..a3d6f727979 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/Makefile.am @@ -0,0 +1,42 @@ +# Makefile for PS utilities +# +# Copyright (C) Reuben Thomas 2012 +# See LICENSE for license + +SUBDIRS = lib + +ACLOCAL_AMFLAGS = -I m4 + +AM_CFLAGS = $(WERROR_CFLAGS) $(WARN_CFLAGS) + +noinst_LIBRARIES = libpsutils.a +libpsutils_a_SOURCES = psutil.c psspec.c +libpsutils_a_LIBADD = $(LIBPAPER) +LDADD = libpsutils.a + +bin_PROGRAMS = psbook psselect pstops epsffit psnup psresize + +bin_SCRIPTS = psjoin extractres + +man_MANS = psutils.1 \ + psbook.1 psselect.1 pstops.1 epsffit.1 psnup.1 psresize.1 \ + psjoin.1 extractres.1 includeres.1 + +EXTRA_DIST = m4/gnulib-cache.m4 \ + psutil.h psspec.h \ + $(bin_SCRIPTS) \ + $(man_MANS) + +all: includeres + +includeres: extractres + $(RM) $@ && $(LN_S) extractres $@ + +install-exec-hook: + cd $(DESTDIR)$(bindir); $(RM) includeres; $(LN_S) extractres includeres + +uninstall-hook: + $(RM) $(DESTDIR)$(bindir)/includeres + +clean-local: + $(RM) includeres diff --git a/Build/source/utils/psutils/psutils-1.21/README b/Build/source/utils/psutils/psutils-1.21/README new file mode 100644 index 00000000000..81b72f8b859 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/README @@ -0,0 +1,89 @@ +PostScript Utilities + +Web site: https://github.com/rrthomas/psutils +Maintainer: Reuben Thomas <rrt@sc3d.org> + +PSUtils is a suite of utilities for manipulating PostScript documents +produced according to the Document Structuring Conventions (some older +software may need to be configured to produce DSC-conformant +PostScript; if PSUtils doesn't work, check your documentation). It is +possible to select and rearrange pages, including arrangement into +signatures for booklet printing, and page merging for n-up printing. + +PSUtils should work in any POSIX environment with libpaper (support on +non-POSIX systems may be provided by gnulib). + +libpaper: http://packages.qa.debian.org/libp/libpaper.html +Ghostscript: http://www.ghostscript.com/ + + +PROGRAMS + +psbook rearrange pages into signatures +psselect select pages and page ranges +pstops perform general page rearrangement and selection +psnup put multiple pages on to one page +psresize alter document paper size +epsffit fit an EPSF file to a given bounding box +extractres filter to extract resources from PostScript files +includeres filter to include resources into PostScript files +psjoin concatenate multiple PostScript files + +psselect in modeled on Chris Torek's dviselect, as is psbook, via +Angus Duggan's dvibook; pstops is modeled on Tom Rokicki's dvidvi. + + +INSTALLATION + +./configure && make && make install + +Run ./configure --help for options. + + +BUGS + +The utilities don't check for PS-Adobe-?.? conformance; they assume documents +conform. + +Please send bug reports, patches and suggestions to the bug tracker or +maintainer (see the top of this file). + + +ACKNOWLEDGEMENTS + +PSUtils was written by Angus Duggan, who maintained it up to release 1 +patchlevel 17. + +Bug fixes and suggestions for improvements to PSUtils have come from many +people, including: + + Brian Colfer brianc@labmed.ucsf.edu + Charles A. Finnell finnell@org.mitre.lear + Conrad Kimball cek@com.boeing.sdc + J. W. Hawtin + Jochen Schwarze schwarze@de.isa + Ken Carpenter khc@edu.ksu.eece + Kristian Jorg etxkrjg@se.ericsson.solsta + Larry Weissman larryw@nsr.bioeng.washington.edu + Michael L. Brown brown@wi.extrel.com + Hunter Goatley goathunter@wkuvx1.bitnet + John Interrante interran@uluru.Stanford.edu + Maurizio Cremonesi MAUCREM@imiclvx.earn + Matthew Stier Matthew.Stier@East.Sun.com + Gerry Pratt cca13@seq1.kl.ac.uk + Robert Joop rj@rainbow.in-berlin.de + Johan Vromans jv@mh.nl + Bryan Faubion bryanf@tc.fluke.com + Chris Ritson C.R.Ritson@ncl.ac.uk + Michele Marziani MARZIANI@VAXFE.INFN.IT + Michael I. Schwartz mschwart@diana.cair.du.edu + Chris Ritson C.R.Ritson@newcastle.ac.uk + Joerg Eisenreich + Andreas Borchert borchert@mathematik.uni-ulm.de + Mike Coleman + Dale Scheetz dwarf@polaris.net + Yves Arrouye arrouye@marin.fdn.fr + Stanislav Brabec utx@penguin.cz + Reuben Thomas rrt@sc3d.org + +(Apologies to anyone left out; it was not intentional.) diff --git a/Build/source/utils/psutils/psutils-1.21/bootstrap b/Build/source/utils/psutils/psutils-1.21/bootstrap new file mode 100755 index 00000000000..92f6bc212ea --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/bootstrap @@ -0,0 +1,3107 @@ +#! /bin/sh +# Print a version string. +scriptversion=2011-08-19.18; # UTC + +# Bootstrap this package from checked-out sources. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# 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/>. + +# Originally written by Paul Eggert. The canonical version of this +# script is maintained as build-aux/bootstrap in gnulib, however, to +# be useful to your project, you should place a copy of it under +# version control in the top-level directory of your project. The +# intent is that all customization can be done with a bootstrap.conf +# file also maintained in your version control; gnulib comes with a +# template build-aux/bootstrap.conf to get you started. + +# Please report bugs or propose patches to bug-gnulib@gnu.org. + + +## ================================================================== ## +## ## +## DO NOT EDIT THIS FILE, CUSTOMIZE IT USING A BOOTSTRAP.CONF ## +## ## +## ================================================================== ## + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase denotes values stored in the environment. These +# variables should generally be overridden by the user - however, we do +# set them to `true' in some parts of this script to prevent them being +# called at the wrong time by other tools that we call (`autoreconf', +# for example). +# +# We also allow `LIBTOOLIZE' and `M4' to be overridden, and export the +# result for child processes, but they are handled by the function +# `func_find_tool' and not defaulted in this section. + +: "${ACLOCAL=aclocal}" +: "${AUTOCONF=autoconf}" +: "${AUTOHEADER=autoheader}" +: "${AUTOM4TE=autom4te}" +: "${AUTOHEADER=autoheader}" +: "${AUTOMAKE=automake}" +: "${AUTOPOINT=autopoint}" +: "${AUTORECONF=autoreconf}" +: "${CMP=cmp}" +: "${CONFIG_SHELL=/bin/sh}" +: "${DIFF=diff}" +: "${EGREP=egrep}" +: "${FGREP=fgrep}" +: "${GIT=git}" +: "${GREP=grep}" +: "${LN_S=ln -s}" +: "${RM=rm}" +: "${SED=sed}" + +export ACLOCAL +export AUTOCONF +export AUTOHEADER +export AUTOM4TE +export AUTOHEADER +export AUTOMAKE +export AUTOPOINT +export AUTORECONF + + +## -------------- ## +## Configuration. ## +## -------------- ## + +# Short help message in response to `-h'. Add to this in `bootstrap.conf' +# if you accept any additional options. +usage_message="Bootstrap this package from the checked-out sources. + +Common Bootstrap Options: + -c, --copy copy files instead of creating symbolic links. + --debug enable verbose shell tracing + -n, --dry-run print commands rather than running them + -f, --force attempt to bootstrap even if the sources seem not to have + been checked out. + --gnulib-srcdir=DIRNAME + specify a local directory where gnulib sources reside. + Use this if you already have the gnulib sources on your + machine, and don't want to waste your bandwidth + downloading them again. Defaults to \$GNULIB_SRCDIR. + --skip-git do not fetch files from remote repositories + --skip-po do not download po files. + -v, --verbose verbosely report processing + --version print version information and exit + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -h, --help print short or long help message and exit +" + +# Warning categories used by `bootstrap', append others if you use them +# in your `bootstrap.conf'. +warning_categories="recommend settings upgrade" + +# Additional text appended to `usage_message' in response to `--help'. +long_help_message=" +Warning categories include: + \`all' show all warnings + \`none' turn off all the warnings + \`error' warnings are treated as fatal errors + \`recommend' show warnings about missing recommended packages + \`settings' show warnings about missing \`bootstrap.conf' settings + \`upgrade' show warnings about out-dated files + +If the file $progpath.conf exists in the same directory as this script, its +contents are read as shell variables to configure the bootstrap. + +For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR +are honored. + +Running without arguments will suffice in most cases. +" + +# A newline delimited list of triples of programs (that respond to +# --version), the minimum version numbers required (or just `-' in the +# version field if any version will be sufficient) and homepage URLs +# to help locate missing packages. +buildreq= + +# Name of a file containing instructions on installing missing packages +# required in `buildreq'. +buildreq_readme=README-hacking + +# These are extracted from AC_INIT in configure.ac, though you can +# override those values in `bootstrap.conf' if you prefer. +build_aux= +macro_dir= +package= +package_name= +package_version= +package_bugreport= + +# These are extracted from `gnulib-cache.m4', or else fall-back +# automatically on the gnulib defaults; unless you set the values +# manually in `bootstrap.conf'. +doc_base= +gnulib_mk= +gnulib_name= +local_gl_dir= +source_base= +tests_base= + +# The list of gnulib modules required at `gnulib-tool' time. If you +# check `gnulib-cache.m4' into your repository, then this list will be +# extracted automatically. +gnulib_modules= + +# Extra gnulib files that are not in modules, which override files of +# the same name installed by other bootstrap tools. +gnulib_non_module_files=" + build-aux/compile + build-aux/install-sh + build-aux/missing + build-aux/mdate-sh + build-aux/texinfo.tex + build-aux/depcomp + build-aux/config.guess + build-aux/config.sub + doc/INSTALL +" + +# Relative path to the local gnulib submodule, and url to the upstream +# git repository. If you have a gnulib entry in your .gitmodules file, +# these values are ignored. +gnulib_path= +gnulib_url= + +# Additional gnulib-tool options to use. +gnulib_tool_options=" + --no-changelog +" + +# bootstrap removes any macro-files that are not included by aclocal.m4, +# except for files listed in this variable which are always kept. +gnulib_precious=" + gnulib-tool.m4 +" + +# When truncating long commands for display, always allow at least this +# many characters before truncating. +min_cmd_len=160 + +# The command to download all .po files for a specified domain into +# a specified directory. Fill in the first %s is the domain name, and +# the second with the destination directory. Use rsync's -L and -r +# options because the latest/%s directory and the .po files within are +# all symlinks. +po_download_command_format=\ +"rsync --delete --exclude '*.s1' -Lrtvz \ +'translationproject.org::tp/latest/%s/' '%s'" + +# Other locale categories that need message catalogs. +extra_locale_categories= + +# Additional xgettext options to use. Gnulib might provide you with an +# extensive list of additional options to append to this, but gettext +# 0.16.1 and newer appends them automaticaly, so you can safely ignore +# the complaints from `gnulib-tool' if your $configure_ac states: +# +# AM_GNU_GETTEXT_VERSION([0.16.1]) +xgettext_options=" + --flag=_:1:pass-c-format + --flag=N_:1:pass-c-format +" + +# Package copyright holder for gettext files. Defaults to FSF if unset. +copyright_holder= + +# File that should exist in the top directory of a checked out hierarchy, +# but not in a distribution tarball. +checkout_only_file= + +# Whether to use copies instead of symlinks by default (if set to true, +# the --copy option has no effect). +copy=false + +# Set this to ".cvsignore .gitignore" in `bootstrap.conf' if you want +# those files to be generated in directories like `lib/', `m4/', and `po/', +# or set it to "auto" to make this script select which to use based +# on which version control system (if any) is used in the source directory. +# Or set it to "none" to ignore VCS ignore files entirely. Default is +# "auto". +vc_ignore= + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# NLS nuisances. +LANGUAGE=C +export LANGUAGE + +# Ensure file names are sorted consistently across platforms. +LC_ALL=C +export LC_ALL + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. +if (eval 'x=a; x+=" b"; test "x$x" = "xa b"') 2>/dev/null +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# `func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_funcs " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a coll to `func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_funcs " in + *" $1 "*) ;; + *) func_fatal_error "Error: \`$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`echo "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +func_run_hooks () +{ + $debug_cmd + + case " $hookable_funcs " in + *" $1 "*) ;; + *) func_fatal_error "Error: \`$1' does not support hook funcions.n" ;; + esac + + eval hook_funcs="\$$1_hooks" + + # shift away the first argument (FUNC_NAME) + shift + func_run_hooks_result=${1+"$@"} + + for hook_func in $hook_funcs; do + eval $hook_func '"$@"' + + # store returned options list back into positional + # parameters for next `cmd' execution. + eval set dummy "$func_run_hooks_result"; shift + done +} + + +## ------------------- ## +## Hookable functions. ## +## ------------------- ## + +# After `bootstrap.conf' has been sourced, execution proceeds by calling +# `func_bootstrap'. Where a function is decorated with `func_hookable +# func_name', you will find a matching `func_run_hooks func_name' which +# executes all functions added with `func_add_hook func_name my_func'. +# +# You might notice that many of these functions begin with a series of +# `$require_foo' lines. See the docu-comments at the start of the +# `Resource management' section for a description of what these are. + + +# func_bootstrap [ARG]... +# ----------------------- +# All the functions called inside func_bootstrap are hookable. See the +# the individual implementations for details. +func_bootstrap () +{ + $debug_cmd + + # Save the current positional parameters to prevent them being + # corrupted by calls to `set' in `func_init'. + func_quote_for_eval ${1+"$@"} + my_saved_positional_parameters="$func_quote_for_eval_result" + + # initialisation + func_init + + # option processing + eval func_options "$my_saved_positional_parameters" + + # post-option preparation + func_prep + + # reconfigure the package + func_reconfigure + + # finalisation + func_fini +} + + +# func_init +# --------- +# Any early initialisations can be hooked to this function. Consider +# whether you can hook onto `func_prep' instead, because if you hook +# any slow to execute code in here, it will also add to the time before +# `./bootstrap --version' can respond. +func_hookable func_init +func_init () +{ + $debug_cmd + + func_run_hooks func_init +} + + +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () +{ + $debug_cmd + + func_options_prep ${1+"$@"} + eval func_parse_options \ + ${func_options_prep_result+"$func_options_prep_result"} + eval func_validate_options \ + ${func_parse_options+"$func_parse_options_result"} + + eval func_run_hooks func_options \ + ${func_validate_options_result+"$func_validate_options_result"} + + # save modified positional parameters for caller + func_options_result="$func_run_hooks_result" +} + + +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propogate that back to rest of this script, then the complete +# modified list must be put in `func_run_hooks_result' before +# returning. +func_hookable func_options_prep +func_options_prep () +{ + $debug_cmd + + warning_func=func_error + + # Option defaults: + opt_copy=${copy-false} + opt_dry_run=false + opt_force=false + opt_gnulib_srcdir="$GNULIB_SRCDIR" + opt_skip_git=false + opt_skip_po=false + opt_warning= + opt_verbose=false + + func_run_hooks func_options_prep ${1+"$@"} + + # save modified positional parameters for caller + func_options_prep_result="$func_run_hooks_result" +} + + +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +# +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, remove any +# options that you action, and then pass back the remaining unprocessed +# options in `func_run_hooks_result', escaped suitably for `eval'. Like +# this: +# +# my_silent_option () +# { +# $debug_cmd +# +# case $1 in +# --silent|-s) opt_silent=:; shift ;; +# esac +# +# func_quote_for_eval ${1+"$@"} +# func_run_hooks_result="$func_quote_for_eval_result" +# } +# func_add_hook func_parse_options my_silent_option +# +func_hookable func_parse_options +func_parse_options () +{ + $debug_cmd + + func_parse_options_result= + + # this just eases exit handling + while test $# -gt 0; do + + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + func_run_hooks func_parse_options ${1+"$@"} + + # Adjust func_parse_options positional parameters to match + eval set dummy "$func_run_hooks_result"; shift + + opt="$1" + shift + case $opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + --dry-run|--dryrun|-n) + opt_dry_run=: ;; + --copy|-c) opt_copy=: ;; + --force|-f) opt_force=: ;; + + --gnulib-srcdir) + test $# = 0 && func_missing_arg $opt && break + opt_gnulib_srcdir="$1" + shift + ;; + + --skip-git) opt_skip_git=: ;; + --skip-po) opt_skip_po=: ;; + --verbose|-v) opt_verbose=: ;; + + --warnings|--warning|-W) + test $# = 0 && func_missing_arg $opt && break + case " $1 " in + " all ") + opt_warning=" $warning_categories" + ;; + " none ") + opt_warning=" none" + warning_func=: + ;; + " error ") + warning_func=func_fatal_error + ;; + *" $warning_categories "*) + func_append_u opt_warning " $1" + ;; + *) + func_fatal_error \ + "Error: unsupported warning category: \`$1'" + ;; + esac + shift + ;; + + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options: + --*=*) + func_split_equals "$opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-c*|-f*|-n*|-v*|-x*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) set dummy "$opt"; shift; break ;; + -*) func_fatal_help "unrecognised option: \`$opt'" ;; + *) set dummy "$opt"; shift; break ;; + esac + done + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result="$func_quote_for_eval_result" +} + + +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () +{ + $debug_cmd + + # display all warnings if -W was not given + test -n "$opt_warning" || opt_warning="$warning_categories" + + func_run_hooks func_validate_options ${1+"$@"} + + # Validate options. + test $# -gt 0 \ + && func_fatal_help "too many arguments" + + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_validate_options_result="$func_quote_for_eval_result" +} + + +# func_prep +# --------- +# Function to perform preparation for remaining bootstrap process. If +# your hooked code relies on the outcome of `func_options' hook it here +# rather than to `func_init'. +# +# All the functions called inside func_prep are hookable. See the +# individual implementations for details. +func_hookable func_prep +func_prep () +{ + $debug_cmd + + $require_bootstrap_uptodate + $require_buildtools_uptodate + $require_checkout_only_file + + $require_gnulib_merge_changelog + + # fetch update files from the translation project + func_update_translations + + func_run_hooks func_prep +} + + +# func_update_translations +# ------------------------ +# Update package po files and translations. +func_hookable func_update_translations +func_update_translations () +{ + $debug_cmd + + $opt_skip_po || { + test -d po && { + $require_package + + func_update_po_files po $package || exit $? + } + + func_run_hooks func_update_translations + } +} + + +# func_reconfigure +# ---------------- +# Reconfigure the current package by running the appropriate autotools in a +# suitable order. +func_hookable func_reconfigure +func_reconfigure () +{ + $debug_cmd + + # Released `autopoint' has the tendency to install macros that have + # been obsoleted in current `gnulib., so run this before `gnulib-tool'. + func_autopoint + + # Autoreconf runs `aclocal' before `libtoolize', which causes spurious + # warnings if the initial `aclocal' is confused by the libtoolized + # (or worse: out-of-date) macro directory. + func_libtoolize + + # If you need to do anything after `gnulib-tool' is done, but before + # `autoreconf' runs, you don't need to override this whole function, + # because `func_gnulib_tool' is hookable. + func_gnulib_tool + + func_autoreconf + + func_run_hooks func_reconfigure +} + + +# func_gnulib_tool +# ---------------- +# Run `gnulib-tool' to fetch gnulib modules into the current package. +# +# It's assumed that since you are using gnulib's `bootstrap' script, +# you're also using gnulib elsewhere in your package. If not, then +# you can replace this function in `bootstrap.conf' with: +# +# func_gnulib_tool () { :; } +# +# (although the function returns immediately if $gnulib_tool is set to +# true in any case). +func_hookable func_gnulib_tool +func_gnulib_tool () +{ + $debug_cmd + + $require_gnulib_tool + $require_libtoolize + + test true = "$gnulib_tool" || { + if test -n "$gnulib_modules"; then + $require_gnulib_cache + $require_build_aux + $require_macro_dir + + # Try not to pick up any stale values from `gnulib-cache.m4'. + rm -f "$gnulib_cache" + + gnulib_mode="--import" + + # `gnulib_modules' and others are maintained in `bootstrap.conf`: + # Use `gnulib --import` to fetch gnulib modules. + test -n "$build_aux" \ + && func_append_u gnulib_tool_options " --aux-dir=$build_aux" + test -n "$macro_dir" \ + && func_append_u gnulib_tool_options " --m4-base=$macro_dir" + test -n "$doc_base" \ + && func_append_u gnulib_tool_options " --doc-base=$doc_base" + test -n "$gnulib_name" \ + && func_append_u gnulib_tool_options " --lib=$gnulib_name" + test -n "$local_gl_dir" \ + && func_append_u gnulib_tool_options " --local-dir=$local_gl_dir" + test -n "$source_base" \ + && func_append_u gnulib_tool_options " --source-base=$source_base" + test -n "$gnulib_mk" \ + && func_append_u gnulib_tool_options " --makefile-name=$gnulib_mk" + test -n "$tests_base" && { + func_append_u gnulib_tool_options " --tests-base=$tests_base" + func_append_u gnulib_tool_options " --with-tests" + } + else + + # `gnulib_modules' and others are cached in `gnulib-cache.m4': + # Use `gnulib --update' to fetch gnulib modules. + gnulib_mode="--update" + fi + + # Add a sensible default libtool option to gnulib_tool_options. + case " $gnulib_tool_options " in + *" --no-libtool "*|*" --libtool "*) ;; + *) if test true = "$LIBTOOLIZE"; then + func_append_u gnulib_tool_options " --no-libtool" + else + func_append_u gnulib_tool_options " --libtool" + fi + ;; + esac + + $opt_copy || func_append_u gnulib_tool_options " --symbolic" + + func_append_u gnulib_tool_options " $gnulib_mode" + func_append gnulib_tool_options " $gnulib_modules" + + # The embedded echo is to squash whitespace before display. + gnulib_cmd=`echo $gnulib_tool $gnulib_tool_options` + + func_show_eval "$gnulib_cmd" 'exit $?' + } + + func_run_hooks func_gnulib_tool +} + + +# func_fini +# --------- +# Function to perform all finalisation for the bootstrap process. +func_hookable func_fini +func_fini () +{ + $debug_cmd + + func_install_gnulib_non_module_files + func_gettext_configuration + func_clean_dangling_symlinks + func_clean_unused_macros + func_skip_po_recommendation + + func_run_hooks func_fini + + func_echo "Done. Now you can run './configure'." +} + + +# func_gettext_configuration +# -------------------------- +# Edit configuration values into po/Makevars. +func_hookable func_gettext_configuration +func_gettext_configuration () +{ + $debug_cmd + + $require_autopoint + + test true = "$AUTOPOINT" || { + $require_copyright_holder + $require_extra_locale_categories + $require_package_bugreport + + # Escape xgettext options for sed Makevars generation below. + # We have to delete blank lines in a separate script so that we don't + # append \\\ to the penultimate line, and then delete the last empty + # line, which messes up the variable substitution later in this + # function. Note that adding a literal \\\ requires double escaping + # here, once for the execution subshell, and again for the assignment, + # which is why there are actually 12 (!!) backslashes in the script. + my_xgettext_options=`echo "$xgettext_options$nl" |$SED '/^$/d' |$SED ' + $b + s|$| \\\\\\\\\\\\|'` + + # Create gettext configuration. + func_echo "Creating po/Makevars from po/Makevars.template ..." + $RM -f po/Makevars + $SED ' + /^EXTRA_LOCALE_CATEGORIES *=/s|=.*|= '"$extra_locale_categories"'| + /^COPYRIGHT_HOLDER *=/s|=.*|= '"$copyright_holder"'| + /^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$package_bugreport"'| + /^XGETTEXT_OPTIONS *=/{ + s|$| \\| + a\ + '"$my_xgettext_options"' \\\ + $${end_of_xgettext_options+} + } + ' po/Makevars.template >po/Makevars || exit 1 + } + + func_run_hooks func_gettext_configuration +} + + + +## --------------- ## +## Core functions. ## +## --------------- ## + +# This section contains the main functions called from the `Hookable +# functions' (shown above), and are the ones you're most likely +# to want to replace with your own implementations in `bootstrap.conf'. + + +# func_autopoint +# -------------- +# If this package uses gettext, then run `autopoint'. +func_autopoint () +{ + $debug_cmd + + $require_autopoint + + test true = "$AUTOPOINT" \ + || func_show_eval "$AUTOPOINT --force" 'exit $?' +} + + +# func_libtoolize +# --------------- +# If this package uses libtool, then run `libtoolize'. +func_libtoolize () +{ + $debug_cmd + + $require_libtoolize + + test true = "$LIBTOOLIZE" || { + my_libtoolize_options= + $opt_copy && func_append my_libtoolize_options " --copy" + $opt_force && func_append my_libtoolize_options " --force" + $opt_verbose || func_append my_libtoolize_options " --quiet" + func_show_eval "$LIBTOOLIZE$my_libtoolize_options" 'exit $?' + } +} + + +# func_autoreconf +# --------------- +# Being careful not to re-run `autopoint' or `libtoolize', and not to +# try to run `autopoint', `libtoolize' or `autoheader' on packages that +# don't use them, defer to `autoreconf' for execution of the remaining +# autotools to bootstrap this package. +func_autoreconf () +{ + $debug_cmd + + $require_autoheader + $require_build_aux # automake and others put files in here + $require_macro_dir # aclocal and others put files in here + + # We ran these manually already, and autoreconf won't exec `:' + save_AUTOPOINT="$AUTOPOINT"; AUTOPOINT=true + save_LIBTOOLIZE="$LIBTOOLIZE"; LIBTOOLIZE=true + + my_autoreconf_options= + $opt_copy || func_append my_autoreconf_options " --symlink" + $opt_force && func_append my_autoreconf_options " --force" + $opt_verbose && func_append my_autoreconf_options " --verbose" + func_show_eval "$AUTORECONF$my_autoreconf_options --install" 'exit $?' + + AUTOPOINT="$save_AUTOPOINT" + LIBTOOLIZE="$save_LIBTOOLIZE" +} + + +# func_install_gnulib_non_module_files +# ------------------------------------ +# Get additional non-module files from gnulib, overriding existing files. +func_install_gnulib_non_module_files () +{ + $debug_cmd + + $require_build_aux + $require_gnulib_path + + test -n "$gnulib_non_module_files" && { + if test -n "$gnulib_path"; then + maybe_exit_cmd=: + + for file in $gnulib_non_module_files; do + case $file in + */COPYING*) dest=COPYING;; + */INSTALL) dest=INSTALL;; + build-aux/*) dest=$build_aux/`expr "$file" : 'build-aux/\(.*\)'`;; + *) dest=$file;; + esac + + # Be sure to show all copying errors before bailing out + if test -f "$gnulib_path/$file"; then + func_symlink_to_dir "$gnulib_path" $file $dest + else + func_error "Error: \`$gnulib_path/$file' does not exist" + maybe_exit_cmd="exit $EXIT_FAILURE" + fi + done + + $maybe_exit_cmd + else + func_warning recommend "\ +Unable to link \`\$gnulib_non_module_files', please provide the +location of a complete \`gnulib' tree by setting \`gnulib_path' in +your \`bootstrap.conf' or with the \`--gnulib-srcdir' option - or +else specify the location of your \`git' binary by setting \`GIT' +in the environment so that a fresh \`gnulib' submodule can be cloned." + fi + } +} + + +# func_check_configuration VARNAME [CONFIGURE_MACRO] +# -------------------------------------------------- +func_check_configuration () +{ + $debug_cmd + + $require_configure_ac + + eval 'test -n "$'$1'"' || { + my_error_msg="Error: please set \`$1' in \`bootstrap.conf'" + test -n "$2" \ + && func_append my_error_msg " + or add the following (or similar) to your \`$configure_ac': + $2" + + func_fatal_error "$my_error_msg" + } +} + + +# func_clean_dangling_symlinks +# ---------------------------- +# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some +# gnulib-populated directories. Such .m4 files would cause aclocal to +# fail. The following requires GNU find 4.2.3 or newer. Considering +# the usual portability constraints of this script, that may seem a very +# demanding requirement, but it should be ok. Ignore any failure, +# which is fine, since this is only a convenience to help developers +# avoid the relatively unusual case in which a symlinked-to .m4 file is +# git-removed from gnulib between successive runs of this script. +func_clean_dangling_symlinks () +{ + $debug_cmd + + $require_macro_dir + $require_source_base + + func_verbose "cleaning dangling symlinks" + + find "$macro_dir" "$source_base" \ + -depth \( -name '*.m4' -o -name '*.[ch]' \) \ + -type l -xtype l -delete > /dev/null 2>&1 +} + + +# func_clean_unused_macros +# ------------------------ +# Autopoint can result in over-zealously adding macros into $macro_dir +# even though they are not actually used, for example tests to help +# build the `intl' directory even though you have specified +# `AM_GNU_GETTEXT([external])' in your configure.ac. This function +# looks removes any macro files that can be found in gnulib, but +# are not `m4_include'd by `aclocal.m4'. +func_clean_unused_macros () +{ + $debug_cmd + + $require_gnulib_path + $require_macro_dir + + test -n "$gnulib_path" && test -f aclocal.m4 && { + aclocal_m4s=`find . -name aclocal.m4 -print` + + # We use `ls|grep' instead of `ls *.m4' to avoid exceeding + # command line length limits in some shells. + for file in `cd $macro_dir && ls -1 |grep '\.m4$'`; do + + # Remove a macro file when aclocal.m4 does not m4_include it... + func_grep_q 'm4_include([[]'$macro_dir/$file'])' $aclocal_m4s \ + || test ! -f $gnulib_path/m4/$file || { + + # ...and there is an identical file in gnulib... + if func_cmp_s $gnulib_path/m4/$file $macro_dir/$file; then + + # ...and it's not in the precious list (`echo' is needed + # here to squash whitespace for the match expression). + case " "`echo $gnulib_precious`" " in + *" $file "*) ;; + *) rm -f $macro_dir/$file + func_verbose \ + "removing unused gnulib file \`$macro_dir/$file'" + esac + fi + } + done + } +} + + +# func_skip_po_recommendation +# --------------------------- +# If there is a po directory, and `--skip-po' wasn't passed, let the +# user know that they can use `--skip-po' on subsequent invocations. +func_skip_po_recommendation () +{ + test ! -d po \ + || $opt_skip_po \ + || func_warning recommend "\ +If your pofiles are up-to-date, you can rerun bootstrap +as \`$progname --skip-po' to avoid redownloading." +} + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Where a variable already has a non- +# empty value (as set by the package's `bootstrap.conf'), that value is +# used in preference to deriving the default. Call them using their +# associated `require_*' variable to ensure that they are executed, at +# most, once. + + +# require_checkout_only_file +# -------------------------- +# Bail out if this package only bootstraps properly from a repository +# checkout. +require_checkout_only_file=func_require_checkout_only_file +func_require_checkout_only_file () +{ + $debug_cmd + + test -n "$checkout_only_file" && test ! -f "$checkout_only_file" \ + && func_fatal_error "\ +Error: Bootstrapping from a non-checked-out distribution is risky." + + require_checkout_only_file=: +} + + +# require_aclocal_amflags +# ----------------------- +# Ensure `$aclocal_amflags' has a sensible default, extracted from +# `Makefile.am' if necessary. +require_aclocal_amflags=func_require_aclocal_amflags +func_require_aclocal_amflags () +{ + $debug_cmd + + $require_makefile_am + + my_sed_extract_aclocal_amflags='s|#.*$|| + /^[ ]*ACLOCAL_AMFLAGS[ ]*=/ { + s|^.*=[ ]*\(.*\)|aclocal_amflags="\1"| + p + }' + + my_aclocal_flags_cmd=`$SED -n "$my_sed_extract_aclocal_amflags" \ + "$makefile_am"` + eval "$my_aclocal_flags_cmd" + + func_verbose "ACLOCAL_AMFLAGS='$aclocal_amflags'" + + require_aclocal_amflags=: +} + + +# require_autobuild_buildreq +# -------------------------- +# Try to find whether the bootstrap requires autobuild. +require_autobuild_buildreq=func_require_autobuild_buildreq +func_require_autobuild_buildreq () +{ + $debug_cmd + + printf "$buildreq"| func_grep_q '^[ ]*autobuild' || { + $require_configure_ac + + func_extract_trace AB_INIT + test -n "$func_extract_trace_result" && { + func_append buildreq 'autobuild - http://josefsson.org/autobuild/ +' + func_verbose "auto-adding \`autobuild' to build requirements" + } + } + + require_autobuild_buildreq=: +} + + +# require_autoconf_buildreq +# require_gettext_buildreq +# require_libtoolize_buildreq +# --------------------------- +# Try to find the minimum compatible version of autoconf/libtool +# required to bootstrap successfully, and add it to `$buildreq'. +for tool in autoconf libtoolize gettext; do + b=$tool + v=require_${tool}_buildreq + f=func_$v + case $tool in + autoconf) m=AC_PREREQ ;; + libtoolize) m=LT_PREREQ; b=libtool ;; + gettext) m=AM_GNU_GETTEXT_VERSION ;; + esac + + eval $v'='$f' + '$f' () + { + $debug_cmd + + # The following is ignored if undefined, but might be necessary + # in order for `func_find_tool` to run. + ${require_'$tool'-:} + + printf "$buildreq" | func_grep_q '\''^[ ]*'$tool\'' || { + $require_configure_ac + + func_extract_trace '$m' + my_version="$func_extract_trace_result" + test -n "$my_version" && { + func_append buildreq "\ + '$tool' $my_version http://www.gnu.org/s/'$b' +" + func_verbose \ + "auto-adding \`'$tool'-$my_version'\'' to build requirements" + } + } + + '$v'=: + } +' +done + + +# require_autoheader +# ------------------ +# Skip autoheader if it's not needed. +require_autoheader=func_require_autoheader +func_require_autoheader () +{ + $debug_cmd + + test true = "$AUTOHEADER" || { + func_extract_trace AC_CONFIG_HEADERS + test -n "$func_extract_trace_result" \ + || func_extract_trace AC_CONFIG_HEADER + + test -n "$func_extract_trace_result" || { + AUTOHEADER=true + + func_verbose "export AUTOHEADER='$AUTOHEADER'" + + # Make sure the search result is visible to subshells + export AUTOHEADER + } + } + + require_autoheader=: +} + + +# require_automake_buildreq +# ------------------------- +# Try to find the minimum compatible version of automake required to +# bootstrap successfully, and add it to `$buildreq'. +require_automake_buildreq=func_require_automake_buildreq +func_require_automake_buildreq () +{ + $debug_cmd + + # if automake is not already listed in $buildreq... + printf "$buildreq"| func_grep_q automake || { + func_extract_trace AM_INIT_AUTOMAKE + + # ...and AM_INIT_AUTOMAKE is declared... + test -n "$func_extract_trace_result" && { + automake_version=`echo "$func_extract_trace_result" \ + |$SED 's|[^0-9]*||; s| .*$||'` + test -n "$automake_version" || automake_version="-" + + func_append buildreq "\ + automake $automake_version http://www.gnu.org/s/automake +" + func_verbose \ + "auto-adding \`automake-$automake_version' to build requirements" + } + } + + require_automake_buildreq=: +} + + +# require_autopoint +# ----------------- +# Skip autopoint if it's not needed. +require_autopoint=func_require_autopoint +func_require_autopoint () +{ + $debug_cmd + + test true = "$AUTOPOINT" || { + func_extract_trace AM_GNU_GETTEXT_VERSION + + test -n "$func_extract_trace_result" || { + AUTOPOINT=true + + func_verbose "export AUTOPOINT='$AUTOPOINT'" + + # Make sure the search result is visible to subshells + export AUTOPOINT + } + } + + require_autopoint=: +} + + +# func_require_bootstrap_uptodate +# ------------------------------- +# Complain if the version of bootstrap in the gnulib directory differs +# from the one we are running. +require_bootstrap_uptodate=func_require_bootstrap_uptodate +func_require_bootstrap_uptodate () +{ + $debug_cmd + + $require_gnulib_path + + test x = x"$gnulib_path" \ + || func_cmp_s $progpath $gnulib_path/build-aux/bootstrap \ + || func_warning upgrade "\ +\`$progpath' differs from \`./$gnulib_path/build-aux/bootstrap', +please consider adopting the canonical version from gnulib." + + require_bootstrap_uptodate=: +} + + +# require_build_aux +# ----------------- +# Ensure that `$build_aux' is set, and if it doesn't already point to an +# existing directory, create one. +require_build_aux=func_require_build_aux +func_require_build_aux () +{ + $debug_cmd + + test -n "$build_aux" || { + $require_configure_ac + + func_extract_trace AC_CONFIG_AUX_DIR + build_aux="$func_extract_trace_result" + func_check_configuration build_aux \ + "AC_CONFIG_AUX_DIR([name of a directory for build scripts])" + + func_verbose "build_aux='$build_aux'" + } + + $require_vc_ignore_files + + # If the build_aux directory doesn't exist, create it now, and mark it + # as ignored for the VCS. + if test ! -d "$build_aux"; then + func_show_eval "mkdir '$build_aux'" + + test -n "$vc_ignore_files" \ + || func_insert_sorted_if_absent "$build_aux" $vc_ignore_files + fi + + require_build_aux=: +} + + +# func_require_buildtools_uptodate +# -------------------------------- +# Ensure all the packages listed in BUILDREQS are available on the build +# machine at the minimum versions or better. +require_buildtools_uptodate=func_require_buildtools_uptodate +func_require_buildtools_uptodate () +{ + $debug_cmd + + $require_autobuild_buildreq + $require_autoconf_buildreq + $require_automake_buildreq + $require_libtoolize_buildreq + $require_gettext_buildreq + + test -n "$buildreq" && { + func_check_versions $buildreq + $func_check_versions_result || { + test -n "$buildreq_readme" \ + && test -f "$buildreq_readme" \ + && func_error "\ +Error: $buildreq_readme explains how to obtain these prerequisite programs: +" + func_strtable 7 11 12 36 \ + "Program" "Min_version" "Homepage" $buildreq + func_fatal_error "$func_strtable_result" + } + } + + require_buildtools_uptodate=: +} + + +# require_configure_ac +# -------------------- +# Ensure that there is a `configure.ac' or `configure.in' file in the +# current directory, and that `$configure_ac' contains its name. +require_configure_ac=func_require_configure_ac +func_require_configure_ac () +{ + $debug_cmd + + test -n "$configure_ac" || { + for configure_ac in configure.ac configure.in; do + test -f $configure_ac && break + done + + <$configure_ac + } + + func_verbose "found \`$configure_ac'" + + require_configure_ac=: +} + + +# require_copyright_holder +# ------------------------ +# Ensure there is a sensible non-empty default value in `$copyright_holder'. +require_copyright_holder=func_require_copyright_holder +func_require_copyright_holder () +{ + $debug_cmd + + test -n "$copyright_holder" || { + copyright_holder='Free Software Foundation, Inc.' + func_warning settings "\ +Please set copyright_holder explicitly in \`bootstrap.conf'; +defaulting to \`$copyright_holder'." + } + + require_copyright_holder=: +} + + +# require_dotgitmodules +# --------------------- +# Ensure we have a `.gitmodules' file, with appropriate `gnulib' settings. +require_dotgitmodules=func_require_dotgitmodules +func_require_dotgitmodules () +{ + $debug_cmd + + $require_git + + test true = "$GIT" || { + # A gnulib entry in .gitmodules always takes precedence. + my_path="`$GIT config --file .gitmodules submodule.gnulib.path 2>/dev/null`" + + test -n "$my_path" || { + $require_vc_ignore_files + + func_verbose "creating \`.gitmodules'" + + # If the .gitmodules file doesn't exist, create it now, and mark + # it as ignored for the VCS. + test -n "$gnulib_path" || gnulib_path=gnulib + test -n "$gnulib_url" || gnulib_url=git://git.sv.gnu.org/gnulib + + { + echo '[submodule "gnulib"]' + echo " path = $gnulib_path" + echo " url = $gnulib_url" + } >> .gitmodules + + test -n "$vc_ignore_files" \ + || func_insert_sorted_if_absent ".gitmodules" $vc_ignore_files + } + } + + require_dotgitmodules=: +} + + +# require_extra_locale_categories +# ------------------------------- +# Ensure there is a default value in `$extra_locale_categories' +require_extra_locale_categories=func_require_extra_locale_categories +func_require_extra_locale_categories () +{ + $debug_cmd + + # Defaults to empty, so run with whatever value may have been set in + # `bootstrap.conf'. + require_extra_locale_categories=: +} + + +# require_git +# ----------- +# Ignore git if it's not available, or we're not in a git checkout tree. +require_git=func_require_git +func_require_git () +{ + $debug_cmd + + $opt_skip_git && GIT=true + + test true = "$GIT" || { + if test -f .gitignore && ($GIT --version) >/dev/null 2>&1; then :; else + GIT=true + fi + } + + func_verbose "GIT='$GIT'" + + require_git=: +} + + +# require_gnu_m4 +# -------------- +# Search for GNU M4, and export it in $M4. +require_gnu_m4=func_require_gnu_m4 +func_require_gnu_m4 () +{ + $debug_cmd + + test -n "$M4" || { + # Find the first m4 binary that responds to --version. + func_find_tool M4 gm4 gnum4 m4 + } + + test -n "$M4" || func_fatal_error "\ +Error: Please install GNU M4, or \`export M4=/path/to/gnu/m4'." + + func_verbose "export M4='$M4'" + + # Make sure the search result is visible to subshells + export M4 + + require_gnu_m4=: +} + + +# require_gnulib_cache +# -------------------- +# Ensure there is a non-empty default for `$gnulib_cache', and that it +# names an existing file. +require_gnulib_cache=func_require_gnulib_cache +func_require_gnulib_cache () +{ + $debug_cmd + + $require_macro_dir + + test -n "$gnulib_cache" \ + || gnulib_cache="$macro_dir/gnulib-cache.m4" + + func_verbose "found \`$gnulib_cache'" + + require_gnulib_cache=: +} + + +# require_gnulib_files_already_present +# ------------------------------------ +# If we have no means to update imported gnulib files, then try to +# ensure at least that this tree already has files from a previous +# `gnulib-tool' run. +require_gnulib_files_already_present=func_require_gnulib_files_already_present +func_require_gnulib_files_already_present () +{ + $debug_cmd + + $require_build_aux + $require_macro_dir + $require_gnulib_mk + $require_source_base + + # As a heuristic, only bail out if any of the following + # are missing. + my_gnulib_files_already_present=" + $build_aux/install-sh + $macro_dir/00gnulib.m4 + $source_base/${gnulib_mk:-Makefile.am} + " + + $opt_dry_run || { + for my_file in $my_gnulib_files_already_present; do + test -f "$my_file" || func_fatal_error "\ +Error: Can't find, copy or download required gnulib files, + please provide the location of a complete \`gnulib' tree + by setting \`gnulib_path' in your \`bootstrap.conf' or + with the \`--gnulib-srcdir' option - or else specify the + location of your \`git' binary by setting \`GIT' in the + environment so that a fresh \`gnulib' submodule can be + cloned." + done + } + + require_gnulib_files_already_present=: +} + + +# require_gnulib_merge_changelog +# ------------------------------ +# See if we can use gnulib's git-merge-changelog merge driver. +require_gnulib_merge_changelog=func_require_gnulib_merge_changelog +func_require_gnulib_merge_changelog () +{ + $debug_cmd + + test -f ChangeLog && { + $require_git + + test true = "$GIT" || { + if $GIT config merge.merge-changelog.driver >/dev/null ; then + : + elif (git-merge-changelog --version) >/dev/null 2>&1 ; then + func_echo "initializing git-merge-changelog driver" + $GIT config merge.merge-changelog.name 'GNU-style ChangeLog merge driver' + $GIT config merge.merge-changelog.driver 'git-merge-changelog %O %A %B' + else + func_warning recommend \ + "Consider installing git-merge-changelog from gnulib." + fi + } + } + + require_gnulib_merge_changelog=: +} + + +# require_gnulib_mk +# ----------------- +# Ensure gnulib_mk has a sensible value, extracted from `gnulib-cache.m4' +# if possible, otherwise letting `gnulib-tool' pick a default. +require_gnulib_mk=func_require_gnulib_mk +func_require_gnulib_mk () +{ + $debug_cmd + + test -n "$gnulib_mk" || { + $require_gnulib_cache + $require_macro_dir + + func_extract_trace "gl_MAKEFILE_NAME" "$gnulib_cache" + gnulib_mk="$func_extract_trace_result" + + test -n "$gnulib_mk" && func_verbose "gnulib_mk='$gnulib_mk'" + } + + require_gnulib_mk=: +} + + +# require_gnulib_path +# require_gnulib_url +# ------------------- +# Ensure `gnulib_path' and `gnulib_url' are set. +require_gnulib_path=func_require_dotgitmodules_parameters +require_gnulib_url=func_require_dotgitmodules_parameters +func_require_dotgitmodules_parameters () +{ + $debug_cmd + + $require_git + + if test true = "$GIT"; then + # If we can't find git (or if the user specified `--skip-git'), + # then use an existing gnulib directory specified with + # `--gnulib-srcdir' if possible. + test -n "$gnulib_path" \ + || test ! -x "$opt_gnulib_srcdir/gnulib-tool" \ + || gnulib_path="$opt_gnulib_srcdir" + fi + + $require_dotgitmodules + + # Extract the parameters with sed, since git may be missing + test -n "$gnulib_path" \ + || gnulib_path=`sed -e '/^.submodule "gnulib".$/,${ + /[ ]*path *= */{ + s,[ ]*,,g;s,^[^=]*=,,;p + } + };d' .gitmodules | sed 1q` + test -n "$gnulib_url" \ + || gnulib_url=`sed -e '/^.submodule "gnulib".$/,${ + /[ ]*url *= */{ + s,[ ]*,,g;s,^[^=]*=,,;p + } + };d' .gitmodules | sed 1q` + + func_verbose "gnulib_path='$gnulib_path'" + func_verbose "gnulib_url='$gnulib_url'" + + require_gnulib_path=: + require_gnulib_url=: +} + + +# require_gnulib_submodule +# ------------------------ +# Ensure that there is a current gnulib submodule at `$gnulib_path'. +require_gnulib_submodule=func_require_gnulib_submodule +func_require_gnulib_submodule () +{ + $debug_cmd + + $require_git + + if test true = "$GIT"; then + func_warning recommend \ + "No \`git' found; imported gnulib modules may be outdated." + else + $require_gnulib_path + $require_gnulib_url + + if test -f .gitmodules && test -f "$gnulib_path/gnulib-tool"; then + func_show_eval "$GIT submodule update" \ + 'func_fatal_error "Error: Unable to update gnulib submodule."' + + elif test -n "$opt_gnulib_srcdir"; then + # Older git can't clone into an empty directory. + rmdir "$gnulib_path" 2>/dev/null + func_show_eval "$GIT clone --reference '$opt_gnulib_srcdir' \ + '$gnulib_url' '$gnulib_path'" \ + && func_show_eval "$GIT submodule init" \ + && func_show_eval "$GIT submodule update" \ + || func_fatal_error "Error: Unable to fetch gnulib submodule." + + # Without --gnulib-srcdir, and no existing checked out submodule, we + # create a new shallow clone of the remote gnulib repository. + else + trap func_cleanup_gnulib 1 2 13 15 + + shallow= + $GIT clone -h 2>&1 |func_grep_q -- --depth \ + && shallow='--depth 2' + + func_show_eval "$GIT clone $shallow '$gnulib_url' '$gnulib_path'" \ + func_cleanup_gnulib + + trap - 1 2 13 15 + fi + fi + + require_gnulib_submodule=: +} + + +# require_gnulib_tool +# ------------------- +# Ensure that `$gnulib_tool' is set, and points to an executable file, +# or else fall back to using the binary `true' if the main gnulib +# files appear to have been imported already. +require_gnulib_tool=func_require_gnulib_tool +func_require_gnulib_tool () +{ + $debug_cmd + + $require_gnulib_submodule + + test true = "$gnulib_tool" || { + $require_gnulib_path + + test -n "$gnulib_tool" \ + || gnulib_tool="$gnulib_path/gnulib-tool" + + test -x "$gnulib_tool" || { + $require_gnulib_files_already_present + + gnulib_tool=true + func_warning recommend \ + "No \`gnulib-tool' found; gnulib modules may be missing." + } + + test true = "$gnulib_tool" \ + || func_verbose "found \`$gnulib_tool'" + } + + require_gnulib_tool=: +} + + +# require_libtoolize +# ------------------ +# Skip libtoolize if it's not needed. +require_libtoolize=func_require_libtoolize +func_require_libtoolize () +{ + $debug_cmd + + # Unless we're not searching for libtool use by this package, set + # LIBTOOLIZE to true if none of `LT_INIT', `AC_PROG_LIBTOOL' and + # `AM_PROG_LIBTOOL' are used in configure. + test true = "$LIBTOOLIZE" || { + func_extract_trace LT_INIT + test -n "$func_extract_trace_result"||func_extract_trace AC_PROG_LIBTOOL + test -n "$func_extract_trace_result"||func_extract_trace AM_PROG_LIBTOOL + test -n "$func_extract_trace_result"||LIBTOOLIZE=true + } + + test -n "$LIBTOOLIZE" || { + # Find libtoolize, named glibtoolize in Mac Ports, but prefer + # user-installed libtoolize to ancient glibtoolize shipped by + # Apple with Mac OS X when Mac Ports is not installed. + func_find_tool LIBTOOLIZE libtoolize glibtoolize + } + + func_verbose "export LIBTOOLIZE='$LIBTOOLIZE'" + + # Make sure the search result is visible to subshells + export LIBTOOLIZE + + require_libtoolize=: +} + + +# require_macro_dir +# ----------------- +# Ensure that `$macro_dir' is set, and if it doesn't already point to an +# existing directory, create one. +require_macro_dir=func_require_macro_dir +func_require_macro_dir () +{ + $debug_cmd + + # Sometimes this is stored in `configure.ac'. + test -n "$macro_dir" || { + func_extract_trace AC_CONFIG_MACRO_DIR + macro_dir="$func_extract_trace_result" + } + + # Otherwise we might find it in `Makefile.am'. + test -n "$macro_dir" || { + $require_aclocal_amflags + + my_sed_scan='s|^.*-I[ ]*\([^ ]*\) .*|\1|' + + # Trailing space in echo is required by the sed script. + macro_dir=`echo "$aclocal_amflags " |$SED "$my_sed_scan"` + } + + func_verbose "macro_dir='$macro_dir'" + + func_check_configuration macro_dir \ + "AC_CONFIG_MACRO_DIR([name of a directory for configure m4 files])" + + $require_vc_ignore_files + + # If the macro_dir directory doesn't exist, create it now, and mark it + # as ignored for the VCS. + if test ! -d "$macro_dir"; then + mkdir "$macro_dir" || func_permissions_error "$macro_dir" + + test -n "$vc_ignore_files" \ + || func_insert_sorted_if_absent "$macro_dir" $vc_ignore_files + fi + + require_macro_dir=: +} + + +# require_makefile_am +# ------------------- +# Ensure there is a `Makefile.am' in the current directory. +# names an existing file. +require_makefile_am=func_require_makefile_am +func_require_makefile_am () +{ + $debug_cmd + + test -n "$makefile_am" \ + || makefile_am="Makefile.am" + + <"$makefile_am" + + func_verbose "found \`$makefile_am'" + + require_makefile_am=: +} + + +# require_package +# --------------- +# Ensure that `$package' contains a sensible default value. +require_package=func_require_package +func_require_package () +{ + $debug_cmd + + test -n "$package" || { + $require_package_name + + package=`echo "$package_name" \ + |$SED 's/GNU //;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + } + + func_verbose "package='$package'" + + require_package=: +} + + +# require_package_bugreport +# ------------------------- +# Ensure that this has a sensible value, extracted from `configure.ac' +# if appropriate (and possible!). +require_package_bugreport=func_require_package_bugreport +func_require_package_bugreport () +{ + $debug_cmd + + func_extract_trace AC_INIT + + save_ifs="$IFS" + IFS=: + set dummy $func_extract_trace_result + IFS="$save_ifs" + shift + + test -n "$package_bugreport" || package_bugreport="$3" + func_check_configuration package_bugreport \ + "AC_INIT([$package_name], [$package_version], [bug-$package@gnu.org])" + func_verbose "package_bugreport='$package_bugreport'" + + require_package_bugreport=: +} + + +# require_package_name +# -------------------- +# Ensure that this has a sensible value, extracted from `configure.ac' +# if appropriate (and possible!). +require_package_name=func_require_package_name +func_require_package_name () +{ + $debug_cmd + + func_extract_trace AC_INIT + + save_ifs="$IFS" + IFS=: + set dummy $func_extract_trace_result + IFS="$save_ifs" + shift + + test -n "$package_name" || package_name="$1" + func_check_configuration package_name \ + "AC_INIT([name of your package], [package version number])" + func_verbose "package_name='$package_name'" + + require_package_name=: +} + + +# require_package_version +# ----------------------- +# Ensure that this has a sensible value, extracted from `configure.ac' +# if appropriate (and possible!). While we might have set all the +# parameters extracted from AC_INIT at once, `package_version' in +# particular is not necessarily available as early as the others, since +# `git-version-gen' is often involved, and until then we can't rely on +# getting a correct version number from an AC_INIT extraction. +require_package_version=func_require_package_version +func_require_package_version () +{ + $debug_cmd + + func_extract_trace AC_INIT + + save_ifs="$IFS" + IFS=: + set dummy $func_extract_trace_result + IFS="$save_ifs" + shift + + test -n "$package_version" || package_version="$2" + func_check_configuration package_version \ + "AC_INIT([$package_name], [package version number])" + func_verbose "package_version='$package_version'" + + require_package_version=: +} + + +# require_source_base +# ------------------- +# Ensure that source_base has a sensible value, extracted from +# `gnulib-cache.m4' if possible. +require_source_base=func_require_source_base +func_require_source_base () + { + $debug_cmd + + $require_gnulib_cache + + test -f "$gnulib_cache" && test x = "x$source_base" && { + $require_macro_dir + + func_extract_trace "gl_SOURCE_BASE" "$gnulib_cache" + + source_base="$func_extract_trace_result" + + func_verbose "source_base='$source_base'" + } + + # Only prevent repeated calls if we found something... + # gnulib-cache.m4 might arrive before the next call. + test -n "$source_base" && require_source_base=: +} + + +# require_vc_ignore_files +# ----------------------- +# Ensure that `$vc_ignore' has been processed to list VCS ignore files +# in `$vc_ignore_files' +require_vc_ignore_files=func_require_vc_ignore_files +func_require_vc_ignore_files () +{ + $debug_cmd + + test -n "$vc_ignore" || vc_ignore=auto + + if test auto = "$vc_ignore" && test x = x"$vc_ignore_files"; then + vc_ignore_files= + test -d .git && vc_ignore_files=.gitignore + test -d CVS && vc_ignore_files="$vc_ignore_files .cvsignore" + else + vc_ignore_files="$vc_ignore" + fi + + func_verbose "vc_ignore_files='$vc_ignore_files'" + + require_vc_ignore_files=: +} + + +## ------------------## +## Helper functions. ## +## ------------------## + +# This section contains the helper functions used by the rest of `bootstrap'. + +# func_len STRING +# --------------- +# STRING may not start with a hyphen. +if (eval 'x=123; test x${#x} = "x3"') 2>/dev/null +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo 0` + } +fi + + +# func_unset VAR +# -------------- +# Portably unset VAR. +func_unset () +{ + { eval $1=; unset $1; } +} +unset=func_unset + + +# func_cmp_s FILE1 FILE2 +# ---------------------- +# Return non-zero exit status unless FILE1 and FILE2 are identical, without +# output. +func_cmp_s () +{ + $debug_cmd + + # This function relies on non-zero exit status, which will cause the + # program to exit when running in `set -e' mode. + $CMP "$@" >/dev/null 2>&1 +} + + +# func_grep_q EXPRESSION [FILENAME..]. +# ------------------------------------ +# Check whether EXPRESSION matches any line of any listed FILENAME, +# without output. +func_grep_q () +{ + $debug_cmd + + # This function relies on non-zero exit status, which will cause the + # program to exit when running in `set -e' mode. + $GREP "$@" >/dev/null 2>&1 +} + + +# func_append_u VAR VALUE +# ----------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_u options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_u () +{ + $debug_cmd + + eval my_current_value='`echo $'$1'`' + my_delim=`expr "$2" : '\(.\)'` + + case $my_delim$my_current_value$my_delim in + *"$2$my_delim"*) ;; + *) func_append "$@" ;; + esac +} + + +# func_strpad STR WIDTH CHAR +# -------------------------- +# Trim STR, or pad with CHAR to force a total length of WIDTH. +func_strpad () +{ + $debug_cmd + + my_width=`expr "$2" - 1` + func_strpad_result=`echo "$1" |$SED ' + :a + s|^.\{0,'"$my_width"'\}$|&'"$3"'| + ta + '` +} + + +# func_strrpad STR WIDTH CHAR +# --------------------------- +# Trim STR, or right-justify-pad with CHAR to force a total length of +# WIDTH. +func_strrpad () +{ + $debug_cmd + + my_width=`expr "$2" - 1` + func_strrpad_result=`echo "$1" |$SED ' + :a + s|^.\{0,'"$my_width"'\}$|'"$3"'&| + ta + '` +} + + +# func_strrow INDENT FIELD WIDTH [FIELDn WIDTHn]... +# ------------------------------------------------- +# Return a string containing each FIELD left justified to WIDTH, with +# the whole thing indented by INDENT spaces. This function is used to +# render one row of aligned columns for a table by func_strtable(). +func_strrow () +{ + $debug_cmd + + func_strrow_linelen="$1"; shift + + my_row= + while test $# -gt 0; do + func_strrow_linelen=`expr $func_strrow_linelen + $2` + func_strpad "$1" $2 " " + func_append my_row "$func_strpad_result" + shift; shift + done + + func_strrpad "$my_row" $func_strrow_linelen " " + func_strrow_result="$func_strrpad_result" +} + + +# func_strtable INDENT WIDTH1...WIDTHn HEADER1...HEADERn FIELD1...FIELDn +# ---------------------------------------------------------------------- +# Generate a string of newline-separated rows arranged in lined-up +# columns of the given WIDTHs, with the entire table indented by INDENT +# spaces. The number of columns is determined by the number of integer +# valued WIDTH arguments following INDENT. The next set (i.e. a number +# of arguments equal to the number of WIDTH arguments) of fields are +# treated as the table's column HEADERs, and are separated from the +# remainder of the table by an indented row of `-' characters. Remaining +# arguments are each aligned below the next available header, wrapping +# to a new row as necessary. Finally another row of `-' characters is +# added to mark the end of the table. +# +# For example an unindented 3 column table with 2 rows of data would be +# generated by this call: +# +# func_strtable 3 20 10 25 \ +# Header1 Header2 Header3 \ +# Row1Col1 Row1Col2 Row1Col3 \ +# Row2Col1 Row2Col2 Row2Col3 +# +# returning the following string: +# +# " Header1 Header2 Header3 +# ------------------------------------------------------- +# Row1Col1 Row1Col2 Row1Col3 +# Row2Col1 Row2Col2 Row2Col3 +# -------------------------------------------------------" +func_strtable () +{ + $debug_cmd + + # Save the indent value, we'll need it for each row we render. + my_indent="$1"; shift + + # Collect remaining numeric args into a list for reuse between + # members of each row when we call func_strrow later. + my_widths="$1"; shift + while test 0 -lt `expr "$1" : '[1-9][0-9]*$'`; do + func_append my_widths " $1"; shift + done + + # Extract the same number of positional parameters as there are + # width elements - we'll do the header rows separately so that + # we can insert a divider line. + my_header="$my_indent" + for my_width in $my_widths; do + func_append my_header " $1 $my_width"; shift + done + func_strrow $my_header + + # Strip off the indent, and make a divider with `-' chars, then + # reindent. + my_divider=`echo "$func_strrow_result" \ + |$SED 's|[^ ]|-|g + :a + s|- |--|g + ta + '` + + # Append the header and divider to the running result. + func_append func_strtable_result "\ +$func_strrow_result +$my_divider +" + + # The remaining rows are zipped between the width values we + # unwound earlier just like the header row above. + while test $# -gt 0; do + my_row="$my_indent" + for my_width in $my_widths; do + func_append my_row " $1 $my_width"; shift + done + func_strrow $my_row + func_append func_strtable_result "\ +$func_strrow_result +" + done + + # Mark the end of the table with a final divider line. + func_append func_strtable_result "$my_divider" +} + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message, taking newlines into account. +func_echo () +{ + my_message="$*" + + save_IFS="$IFS" + IFS="$nl" + for my_line in $my_message; do + IFS="$save_IFS" + echo "$progname: $my_line" + done + IFS="$save_IFS" +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + my_message="$*" + + save_IFS="$IFS" + IFS="$nl" + for my_line in $my_message; do + IFS="$save_IFS" + echo "$progname: $bold_on$my_line$bold_off" 1>&2 + done + IFS="$save_IFS" +} + +# Allow display of bold text on terminals that support it +bold_on= +bold_off= +if test -t 1; then + if test -n "`tput bold 2>/dev/null`" \ + && test -n "`tput sgr0 2>/dev/null`" + then + bold_on=`tput bold` + bold_off=`tput sgr0` + fi +fi + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + + +# func_internal_error ARG... +# -------------------------- +# Echo program name prefixed message to standard error, and exit. +func_internal_error () +{ + func_fatal_error "INTERNAL ERROR: " ${1+"$@"} " + Please report this bug to \`bug-gnulib@gnu.org' + in as much detail as possible." +} + + +# func_permissions_error FILE-OR-DIRECTORY +# ---------------------------------------- +# Echo program name prefixed permissions error message to standard +# error, and exit. +func_permissions_error () +{ + $debug_cmd + + func_fatal_error "Error: Failed to create \`$1', check permissions." +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY. +func_warning () +{ + $debug_cmd + + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category \`$1'" ;; + esac + + my_category="$1" + shift + + case " $opt_warning " in + *" $my_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + $debug_cmd + + func_error ${1+"$@"} + func_fatal_error "$fatal_help" +} +fatal_help="Try \`$progname --help' for more information." ## default + + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + cat <<EOF +$progname $scriptversion +EOF + $SED -n '/(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + }' < "$progpath" + + exit $? +} + + +# func_usage [NOEXIT] +# ------------------- +# Echo short help message to standard output and exit. +func_usage () +{ + $debug_cmd + + echo "$progpath [OPTION]..." + echo "" + echo "$usage_message" + + my_ret=$? + test -n "$1" || { + echo "Run \`$progname --help | more' for full usage" + exit $my_ret + } +} + + +# func_help [NOEXIT] +# ------------------ +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $debug_cmd + + func_usage noexit + echo "$long_help_message" + + my_ret=$? + test -n "$1" || exit $my_ret +} + + +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $debug_cmd + + func_error "Error: Missing argument for \`$1'." + exit_cmd=exit +} + + +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if (eval 'x=-abc; y=${x#??}; z=${x%$y}; test x$y$z = xbc-a') 2>/dev/null +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt + + +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the `=' sign. +if (eval 'x='--ab=cd'; y=${x#*=}; z=${x%%=*}; test x$y$z = xcd--ab') 2>/dev/null +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs="" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*)'` + func_split_equals_rhs="" + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_result= + + while test $# -gt 0; do + case $1 in + *[\\\`\"\$]*) + my_unquoted_arg=`printf "$1" | $SED "$sed_quote_subst"` ;; + *) + my_unquoted_arg="$1" ;; + esac + + case $my_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_quoted_arg="\"$my_unquoted_arg\"" + ;; + *) + my_quoted_arg="$my_unquoted_arg" ;; + esac + test -n "$func_quote_for_eval_result" \ + && func_append func_quote_for_eval_result " " + func_append func_quote_for_eval_result "$my_quoted_arg" + shift + done +} + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_eval $my_cmd + eval func_truncate_cmd $func_quote_for_eval_result + func_echo "running: $func_truncate_cmd_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_truncate_cmd CMD [ARG]... +# ------------------------------ +# For unreasonably long commands (such as a gnulib-tool invocation with +# the full module list for import), truncate CMD after the second non- +# option ARG. +func_truncate_cmd () +{ + $debug_cmd + + my_last_arg_opt_p=false + func_truncate_cmd_result= + + set dummy "$@"; shift + + while test $# -gt 0; do + my_opt="$1"; shift + + test -n "$func_truncate_cmd_result" \ + && func_append func_truncate_cmd_result ' ' + func_append func_truncate_cmd_result "$my_opt" + + func_len "x$func_truncate_cmd_result" + + case $my_opt in + -*) my_last_arg_opt_p=: ;; + *) $my_last_arg_opt_p \ + || test $min_cmd_len -gt $func_len_result \ + || break + my_last_arg_opt_p=false + ;; + esac + done + + test $# -gt 0 && func_append func_truncate_cmd_result "..." +} + + +# func_extract_trace MACRO_NAME [FILENAME]... +# ------------------------------------------- +# set `$func_extract_trace_result' to a colon delimited list of +# arguments to MACRO_NAME in FILENAME. If no FILENAME is not given, +# then `configure.ac' is assumed. +func_extract_trace () +{ + $debug_cmd + + $require_configure_ac + $require_gnu_m4 + + my_macro="$1"; shift + test $# -gt 0 || { + set dummy $configure_ac + shift + } + + # Generate an error if the first file is missing + <"$1" + + # Sadly, we can't use `autom4te' tracing to extract macro + # arguments, because it complains about things we want to + # ignore at bootstrap time - like missing m4_include files; + # AC_PREREQ being newer than the installed autoconf; and + # returns nothing when tracing `AM_INIT_AUTOMAKE' when + # aclocal hasn't been generated yet. + # + # The following tries to emulate a less persnickety version + # of (and due to not having to wait for Perl startup on + # every invocation, it's probably faster too): + # + # autom4te --language=Autoconf --trace=$my_macro:\$% "$@" + # + # First we give a minimal set of macro declarations to M4 + # to prime it for reading Autoconf macros, while still + # providing some of the functionality generally used at + # m4-time to supply dynamic arguments to Autocof functions, + # but without following `m4_s?include' files. + # + # We discard M4's stdout, but the M4 trace output from reading + # our "autoconf.mini" followed by any other files passed to + # this function is then scanned by sed to transform it into + # a colon delimited argument list assigned to a shell variable. + # + # Finally, we `eval' the sed generated assignment to get + # the result back into this script for further use by callers + # of this function. + + func_extract_trace_result= + eval `echo ' + # Initialisation. + m4_changequote([,]) + m4_define([m4_copy], [m4_define([$2], m4_defn([$1]))]) + m4_define([m4_rename], [m4_copy([$1], [$2])m4_undefine([$1])]) + + # Disable these macros. + m4_undefine([m4_dnl]) + m4_undefine([m4_include]) + m4_undefine([m4_m4exit]) + m4_undefine([m4_m4wrap]) + m4_undefine([m4_maketemp]) + + # Copy and rename macros not handled by "m4 --prefix". + m4_define([dnl], [m4_builtin([dnl])]) + m4_copy([m4_define], [m4_defun]) + m4_rename([m4_ifelse], [m4_if]) + m4_ifdef([m4_mkstemp], [m4_undefine([m4_mkstemp])]) + m4_rename([m4_patsubst], [m4_bpatsubst]) + m4_rename([m4_regexp], [m4_bregexp]) + + # "m4sugar.mini" - useful m4-time macros for dynamic arguments. + # If we discover packages that need more m4 macros defined in + # order to bootstrap correctly, add them here: + m4_define([m4_bmatch], + [m4_if([$#], 0, [], [$#], 1, [], [$#], 2, [$2], + [m4_if(m4_bregexp([$1], [$2]), -1, + [$0([$1], m4_shift3($@))], [$3])])]) + m4_define([m4_ifndef], [m4_ifdef([$1], [$3], [$2])]) + m4_define([m4_ifset], + [m4_ifdef([$1], [m4_ifval(m4_defn([$1]), [$2], [$3])], [$3])]) + m4_define([m4_require], [$1]) + m4_define([m4_shift3], [m4_shift(m4shift(m4shift($@)))]) + + # "autoconf.mini" - things from autoconf macros we care about. + m4_copy([m4_defun], [AC_DEFUN]) + + # Dummy definition for the macro we want to trace. + # AM_INIT_AUTOMAKE at least produces no trace without this. + AC_DEFUN(['"$my_macro"'])' \ + |$M4 -daq --prefix --trace="$my_macro" - "$@" 2>&1 1>/dev/null \ + |$SED -n 's|#.*$|| + /^m4trace: -1- '"$my_macro"'/ { + s|^m4trace: -1- '"$my_macro"'[([]*|func_extract_trace_result='\''| + s|], [[]|:|g + s|[])]*$|:'\''| + s|[^'\'']$|\&'\''| + p + }'` + + # Leave the ':' sentinel in place for successfully traced macros + # without arguments, otherwise remove it so that the results of + # single-argument macros can be used without additional parsing. + test : = "$func_extract_trace_result" \ + || func_extract_trace_result=`echo "$func_extract_trace_result" |$SED 's|:$||'` +} + + +# func_insert_sorted_if_absent STR FILE... +# ---------------------------------------- +# If $STR is not already on a line by itself in $FILE, insert it, +# sorting the new contents of the file and replacing $FILE with the result. +func_insert_sorted_if_absent () +{ + $debug_cmd + + str=$1 + shift + + for file + do + test -f $file || touch $file + + func_grep_q "$str" "$file" \ + && func_verbose "inserting \`$str' into \`$file'" + + echo "$str" | sort -u - $file | func_cmp_s - $file \ + || echo "$str" | sort -u - $file -o $file \ + || func_permissions_error "$file" + done +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () # sort -V is not generally available +{ + $debug_cmd + + ver1="$1" + ver2="$2" + + # split on '.' and compare each component + i=1 + while : ; do + p1=`echo "$ver1" | cut -d. -f$i` + p2=`echo "$ver2" | cut -d. -f$i` + if test ! "$p1"; then + echo "$1 $2" + break + elif test ! "$p2"; then + echo "$2 $1" + break + elif test ! "$p1" = "$p2"; then + if test "$p1" -gt "$p2" 2>/dev/null; then # numeric comparison + echo "$2 $1" + elif test "$p2" -gt "$p1" 2>/dev/null; then # numeric comparison + echo "$1 $2" + else # numeric, then lexicographic comparison + lp=`printf "$p1\n$p2\n" | sort -n | tail -n1` + if test "$lp" = "$p2"; then + echo "$1 $2" + else + echo "$2 $1" + fi + fi + break + fi + i=`expr $i + 1` + done +} + + +# func_get_version APP +# -------------------- +# echo the version number (if any) of APP, which is looked up along your +# PATH. +func_get_version () +{ + $debug_cmd + + app=$1 + + { $app --version || $app --version </dev/null; } >/dev/null 2>&1 \ + || return 1 + + $app --version 2>&1 | + $SED -n '# extract version within line + s|.*[v ]\{1,\}\([0-9]\{1,\}\.[.a-z0-9-]*\).*|\1| + t done + + # extract version at start of line + s|^\([0-9]\{1,\}\.[.a-z0-9-]*\).*|\1| + t done + + d + + :done + #the following essentially does s|5.005|5.5| + s|\.0*\([1-9]\)|.\1|g + p + q' +} + + +# func_check_versions APP1 VER1 URL1 ...[APPN VERN URLN] +# ------------------------------------------------------ +func_check_versions () +{ + $debug_cmd + + func_check_versions_result=: + + while test $# -gt 0; do + my_app="$1"; shift + my_reqver="$1"; shift + my_url="$1"; shift + + # Honor $APP variables ($TAR, $AUTOCONF, etc.) + my_appvar=`echo $my_app | tr '[a-z]' '[A-Z]'` + test "$my_appvar" = TAR && my_appvar=AMTAR + eval "my_app=\${$my_appvar-$my_app}" + my_instver=`func_get_version $my_app` + + test ! "$my_instver" \ + || func_verbose "found \`$my_app' version $my_instver" + + # Fail if --version didn't work. + if test ! "$my_instver"; then + func_error "Error: \`$my_app' not found" + func_check_versions_result=false + + # Fail if a new version than what we have is required. + elif test ! "$my_reqver" = "-"; then + my_newer=`func_sort_ver $my_reqver $my_instver | cut -d' ' -f2` + test ! "$my_newer" = "$my_instver" && { + func_error "\ +Error: \`$my_app' version == $my_instver is too old + \`$my_app' version >= $my_reqver is required" + func_check_versions_result=false + } + fi + done +} + + +# func_cleanup_gnulib +# ------------------- +# Recursively delete everything below the path in the global variable +# GNULIB_PATH. +func_cleanup_gnulib () +{ + $debug_cmd + + status=$? + $RM -fr "$gnulib_path" + exit $status +} + + +# func_symlink_to_dir SRCDIR FILENAME [DEST_FILENAME] +# --------------------------------------------------- +# Make a symlink from FILENAME in SRCDIR to the current directory, +# optionally calling the symlink DEST_FILENAME. +func_symlink_to_dir () +{ + $debug_cmd + + $require_vc_ignore_files + + src=$1/$2 + dst=${3-$2} + + test -f "$src" && { + + # If the destination directory doesn't exist, create it. + # This is required at least for "lib/uniwidth/cjk.h". + dst_dir=`dirname "$dst"` + if ! test -d "$dst_dir"; then + mkdir -p "$dst_dir" + + # If we've just created a directory like lib/uniwidth, + # tell version control system(s) it's ignorable. + # FIXME: for now, this does only one level + parent=`dirname "$dst_dir"` + for dot_ig in x $vc_ignore_files; do + test $dot_ig = x && continue + ig=$parent/$dot_ig + func_insert_sorted_if_absent `echo "$dst_dir" |$SED 's|.*/||'` $ig + done + fi + + if $opt_copy; then + { + test ! -h "$dst" \ + || func_show_eval "$RM -f '$dst'" + } \ + && test -f "$dst" \ + && func_cmp_s "$src" "$dst" \ + && func_echo "copying file \`$src'" \ + && cp -fp "$src" "$dst" + else + test -h "$dst" \ + && src_ls=`ls -diL "$src" 2>/dev/null` \ + && set $src_ls && src_i=$1 \ + && dst_ls=`ls -diL "$dst" 2>/dev/null` \ + && set $dst_ls && dst_i=$1 \ + && test "$src_i" = "$dst_i" \ + || { + dot_dots= + case $src in + /*) ;; + *) + case /$dst/ in + *//* | */../* | */./* | /*/*/*/*/*/) + func_fatal_error "\ +Error: Invalid symlink calculation: $src -> $dst" + ;; + /*/*/*/*/) dot_dots=../../../;; + /*/*/*/) dot_dots=../../;; + /*/*/) dot_dots=../;; + esac + ;; + esac + + func_echo "linking file \`$src'" + ln -fs "$dot_dots$src" "$dst" + } + fi + } +} + + +# func_download_po_files SUBDIR DOMAIN +# ------------------------------------ +func_download_po_files () +{ + $debug_cmd + + func_echo "getting translations into $1 for $2..." + cmd=`printf "$po_download_command_format" "$2" "$1"` + eval "$cmd" +} + + +# func_find_tool ENVVAR NAMES... +# ------------------------------ +# Search for a required program. Use the value of ENVVAR, if set, +# otherwise find the first of the NAMES that can be run (i.e., +# supports --version). If found, set ENVVAR to the program name, +# die otherwise. +func_find_tool () +{ + $debug_cmd + + find_tool_envvar=$1 + shift + find_tool_names=$@ + eval "find_tool_res=\$$find_tool_envvar" + if test x"$find_tool_res" = x; then + for i + do + if ($i --version </dev/null) >/dev/null 2>&1; then + find_tool_res=$i + break + fi + done + else + find_tool_error_prefix="\$$find_tool_envvar: " + fi + test x"$find_tool_res" = x && func_fatal_error "\ +Error: One of these is required: + $find_tool_names" + + ($find_tool_res --version </dev/null) >/dev/null 2>&1 \ + || func_fatal_error "\ +Error: ${find_tool_error_prefix}Cannot run \`$find_tool_res --version'" + + eval "$find_tool_envvar=\$find_tool_res" + eval "export $find_tool_envvar" +} + + +# func_update_po_files PO_DIR DOMAIN +# ---------------------------------- +# Mirror .po files to $po_dir/.reference and copy only the new +# or modified ones into $po_dir. Also update $po_dir/LINGUAS. +# Note po files that exist locally only are left in $po_dir but will +# not be included in LINGUAS and hence will not be distributed. +func_update_po_files () +{ + $debug_cmd + + # Directory containing primary .po files. + # Overwrite them only when we're sure a .po file is new. + po_dir=$1 + domain=$2 + + # Mirror *.po files into this dir. + # Usually contains *.s1 checksum files. + ref_po_dir="$po_dir/.reference" + + test -d $ref_po_dir || mkdir $ref_po_dir || return + func_download_po_files $ref_po_dir $domain \ + && ls "$ref_po_dir"/*.po 2>/dev/null | + $SED 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return + + # Find sha1sum, named gsha1sum on MacPorts, and shasum on MacOS 10.6. + func_find_tool SHA1SUM sha1sum gsha1sum shasum + + langs=`cd $ref_po_dir && echo *.po|$SED 's|\.po||g'` + test "$langs" = '*' && langs=x + for po in $langs; do + case $po in x) continue;; esac + new_po="$ref_po_dir/$po.po" + cksum_file="$ref_po_dir/$po.s1" + if ! test -f "$cksum_file" || + ! test -f "$po_dir/$po.po" || + ! $SHA1SUM -c --status "$cksum_file" \ + < "$new_po" > /dev/null; then + echo "updated $po_dir/$po.po..." + cp "$new_po" "$po_dir/$po.po" \ + && $SHA1SUM < "$new_po" > "$cksum_file" + fi + done +} + + + +## ----------------- ## +## Global variables. ## +## ----------------- ## + +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Allow overriding, eg to get a function call trace: +# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash bootstrap +debug_cmd="${debug_cmd-:}" +exit_cmd=: + +dirname='s|/[^/]*$||' +basename='s|^.*/||' + +nl=' +' + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +progname=`echo "$progpath" |$SED "$basename"` + +## -------------------------------------------------- ## +## Source package customisations in `bootstrap.conf'. ## +## -------------------------------------------------- ## + +# Override the default configuration, if necessary. +# Make sure that bootstrap.conf is sourced from the current directory +# if we were invoked as "sh bootstrap". +case "$0" in + */*) test -r "$0.conf" && . "$0.conf" ;; + *) test -r "$0.conf" && . ./"$0.conf" ;; +esac + + +## ------------------------------- ## +## Actually perform the bootstrap. ## +## ------------------------------- ## + +func_bootstrap ${1+"$@"} + +# The End. +exit $exit_status + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/Build/source/utils/psutils/psutils-1.21/bootstrap.conf b/Build/source/utils/psutils/psutils-1.21/bootstrap.conf new file mode 100644 index 00000000000..2925724bad0 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/bootstrap.conf @@ -0,0 +1,104 @@ +# bootstrap.conf (psutils) +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010 Gary V. Vaughan. + +# This file is part of psutils. +# See LICENSE for license. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# Additional gnulib-tool options to use. +gnulib_tool_options=' + --no-changelog +' + +# gnulib modules used by this package. +gnulib_modules=' + warnings + manywarnings + fstat +' + +# Extra gnulib files that are not in modules, which override files of +# the same name installed by other bootstrap tools. +gnulib_non_module_files=' + build-aux/config.guess + build-aux/config.sub + build-aux/install-sh +' + +# The not-synced with gnulib warning is bogus until upstream adopts +# the saner bootstrap script. +require_bootstrap_uptodate=: + +## --------------- ## +## Hook functions. ## +## --------------- ## + +# psutils_ignore_gnulib_ignore +# ---------------------------- +# gnulib-tool updates m4/.gitignore and lib/.gitignore, and keeping +# generated files under version control does not make sense. Since +# lib is entirely ignored, we only need to prepopulate the m4 ignore +# files with generated files not tracked by gnulib-tool. +psutils_ignore_gnulib_ignore () +{ + $debug_cmd + + $require_macro_dir + + if test -f "$macro_dir/.gitignore" ; then + : + else + func_verbose "creating initial \`$macro_dir/.gitignore'" + cat > $macro_dir/.gitignore <<\EOF +# files created by bootstrap, but that gnulib doesn't track +*~ +/.gitignore +/gnulib-cache.m4 +/gnulib-comp.m4 +/libtool.m4 +/ltoptions.m4 +/ltsugar.m4 +/ltversion.m4 +/lt~obsolete.m4 +EOF + fi +} +func_add_hook func_prep psutils_ignore_gnulib_ignore + + +# psutils_force_changelog +# ----------------------- +# Automake requires that ChangeLog exist. +psutils_force_changelog () +{ + $debug_cmd + + touch ChangeLog || exit 1 +} +func_add_hook func_gnulib_tool psutils_force_changelog + + +# psutils_finish +# ---------------------- +# Configure script does not require ChangeLog. +# Copy dummy.c with correct license. +psutils_finish () +{ + $debug_cmd + + cp -fp ./dummy.c $source_base/ + rm ChangeLog || exit 1 +} +func_add_hook func_fini psutils_finish + + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# End: diff --git a/Build/source/utils/psutils/psutils-1.21/configure.ac b/Build/source/utils/psutils/psutils-1.21/configure.ac new file mode 100644 index 00000000000..40f2ab20683 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/configure.ac @@ -0,0 +1,80 @@ +dnl Process this file with autoconf to produce a configure script + +AC_INIT(psutils, 1.21, rrt@sc3d.org) +AC_CONFIG_AUX_DIR([build-aux]) + +AM_INIT_AUTOMAKE([-Wall -Werror foreign]) + +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +dnl Check for programs +AC_PROG_CC +gl_EARLY +AC_PROG_LN_S +AM_PROG_AR + +AC_USE_SYSTEM_EXTENSIONS +AC_ARG_ENABLE([gcc-warnings], + [AS_HELP_STRING([--enable-gcc-warnings], + [turn on lots of GCC warnings (for developers)])], + [case $enableval in + yes|no) ;; + *) AC_MSG_ERROR([bad value $enableval for gcc-warnings option]) ;; + esac + gl_gcc_warnings=$enableval], + [gl_gcc_warnings=no] +) + +if test "$gl_gcc_warnings" = yes; then + gl_WARN_ADD([-Werror], [WERROR_CFLAGS]) + + # Set up the list of undesired warnings. + nw= + nw="$nw -Wundef" # All compiler preprocessors support #if UNDEF + nw="$nw -Wtraditional" # All compilers nowadays support ANSI C + nw="$nw -Wstrict-overflow" # Use a lower level (see below). + nw="$nw -Wconversion" # These warnings usually don’t point to mistakes. + nw="$nw -Wsign-conversion" # Likewise. + nw="$nw -Waggregate-return" # We do this on purpose. + nw="$nw -Wtraditional-conversion" # Don't care. + nw="$nw -Wpadded" # Don't care. + nw="$nw -Wc++-compat" # Don't care. + nw="$nw -Woverlength-strings" # Don't care. + nw="$nw -Wmissing-format-attribute" # Don't care. + nw="$nw -Wshadow" # Don't care. + nw="$nw -Wunreachable-code" # Seems buggy. + nw="$nw -Wsystem-headers" # glibc headers fail as of glibc 2.15, gcc 4.7 + nw="$nw -Wall" + nw="$nw -Wunused-macros" # those macros might come in handy later + + gl_MANYWARN_ALL_GCC([warnings]) + + # Enable all GCC warnings not in this list. + gl_MANYWARN_COMPLEMENT([warnings], [$warnings], [$nw]) + for w in $warnings; do + gl_WARN_ADD([$w]) + done + + # Add an extra warning + gl_WARN_ADD([-Wstrict-overflow=1]) + # Add some more safety measures + gl_WARN_ADD([-D_FORTIFY_SOURCE=2]) + gl_WARN_ADD([-fmudflap]) +fi + +gl_INIT + +dnl Check for header files +AC_HEADER_STDC +AC_CHECK_HEADER([paper.h], [], [AC_MSG_FAILURE([cannot find libpaper header])]) + +dnl Check for libraries +AC_PROG_RANLIB +AC_CHECK_LIB([paper], [paperinfo], [], + [AC_MSG_FAILURE([cannot find libpaper library])]) + +dnl Generate output files +AC_CONFIG_MACRO_DIR(m4) +AC_CONFIG_HEADER(config.h) +AC_CONFIG_FILES(Makefile lib/Makefile) +AC_OUTPUT diff --git a/Build/source/utils/psutils/psutils-1.21/dummy.c b/Build/source/utils/psutils/psutils-1.21/dummy.c new file mode 100644 index 00000000000..061a78c34b2 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/dummy.c @@ -0,0 +1,30 @@ +/* A dummy file, to prevent empty libraries from breaking builds. + + This file is in the public domain. -- Bruno Haible */ + +/* Some systems, reportedly OpenBSD and Mac OS X, refuse to create + libraries without any object files. You might get an error like: + + > ar cru .libs/libgl.a + > ar: no archive members specified + + Compiling this file, and adding its object file to the library, will + prevent the library from being empty. */ + +/* Some systems, such as Solaris with cc 5.0, refuse to work with libraries + that don't export any symbol. You might get an error like: + + > cc ... libgnu.a + > ild: (bad file) garbled symbol table in archive ../gllib/libgnu.a + + Compiling this file, and adding its object file to the library, will + prevent the library from exporting no symbols. */ + +#ifdef __sun +/* This declaration ensures that the library will export at least 1 symbol. */ +int gl_dummy_symbol; +#else +/* This declaration is solely to ensure that after preprocessing + this file is never empty. */ +typedef int dummy; +#endif diff --git a/Build/source/utils/psutils/psutils-1.21/epsffit.1 b/Build/source/utils/psutils/psutils-1.21/epsffit.1 new file mode 100644 index 00000000000..3519cd3576d --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/epsffit.1 @@ -0,0 +1,51 @@ +.TH EPSFFIT 1 "PSUtils" +.SH NAME +epsffit \- fit encapsulated PostScript file (EPSF) into constrained size +.SH SYNOPSIS +.B epsffit +[ +.B \-c +] [ +.B \-r +] [ +.B \-a +] [ +.B \-m +] [ +.B \-s +] +.I "llx lly urx ury" +[ +.B infile +[ +.B outfile +] ] +.SH DESCRIPTION +.I Epsffit +fits an EPSF file (encapsulated PostScript) to a given bounding box. +The coordinates of the box are given by \fB(llx,lly)\fR for the lower +left, and \fB(urx,ury)\fR for the upper right, in PostScript units (points). +.PP +If no input or output files are specified, +.I epsffit +read from the standard input and writes to the standard output. +.SH OPTIONS +.IP \fB\-c\fP 1i +Center the image in the given bounding box. +.IP \fB\-r\fP 1i +Rotate the image by 90 degrees counter-clockwise. +.IP \fB\-a\fP 1i +Adjust the aspect ratio to fit the bounding box. The default is to preserve +the aspect ratio. +.IP \fB\-m\fP 1i +Rotates the image to maximise the size if it would fit the specified bounding +box better. +.IP \fB\-s\fP 1i +Add a \fIshowpage\fP at the end of the file to force the image to print. +.SH AUTHOR +Written by Angus J. C. Duggan. +.SH "SEE ALSO" +psutils(1) +.SH TRADEMARKS +.B PostScript +is a trademark of Adobe Systems Incorporated. diff --git a/Build/source/utils/psutils/psutils-1.21/epsffit.c b/Build/source/utils/psutils/psutils-1.21/epsffit.c new file mode 100644 index 00000000000..8ff3f7ec3ee --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/epsffit.c @@ -0,0 +1,174 @@ +/* epsffit.c + * Fit EPSF file into constrained size + * + * (c) Reuben Thomas 2012 + * (c) Angus J. C. Duggan 1991-1997 + * See file LICENSE for details. + * + * Added filename spec (from Larry Weissman) 5 Feb 93 + * Accepts double %%BoundingBox input, outputs proper BB, 4 Jun 93. (I don't + * like this; developers should read the Big Red Book before writing code which + * outputs PostScript. + */ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include "psutil.h" + +const char *syntax = "[-c] [-r] [-a] [-m] [-s] LLX LLY URX URY [INFILE [OUTFILE]]\n"; + +const char *argerr_message = ""; + +int +main(int argc, char **argv) +{ + int bbfound = 0; /* %%BoundingBox: found */ + int urx = 0, ury = 0, llx = 0, lly = 0; + int furx, fury, fllx, flly; + int showpage = 0, centre = 0, rotate = 0, aspect = 0, maximise = 0; + char buf[BUFSIZ]; + FILE *input = stdin; + FILE *output = stdout; + int opt; + + SET_BINARY(stdin); + SET_BINARY(stdout); + + program = *argv; + + while((opt = getopt(argc, argv, "csramv")) != EOF) { + switch(opt) { + case 'c': centre = 1; break; + case 's': showpage = 1; break; + case 'r': rotate = 1; break; + case 'a': aspect = 1; break; + case 'm': maximise = 1; break; + case 'v': + default: + usage(); + break; + } + } + + if ((argc - optind) < 4 || (argc - optind) > 6) usage(); + + fllx = atoi(argv[optind++]); + flly = atoi(argv[optind++]); + furx = atoi(argv[optind++]); + fury = atoi(argv[optind++]); + + /* Be defensive */ + if((argc - optind) < 0 || (argc - optind) > 2) usage(); + + if ((argc - optind) > 0) { + if(!(input = fopen(argv[optind], "rb"))) + message(FATAL, "can't open input file %s\n", argv[optind]); + optind++; + } + + if ((argc - optind) > 0) { + if(!(output = fopen(argv[optind], "wb"))) + message(FATAL, "can't open output file %s\n", argv[optind]); + optind++; + } + + while (fgets(buf, BUFSIZ, input)) { + if (buf[0] == '%' && (buf[1] == '%' || buf[1] == '!')) { + /* still in comment section */ + if (!strncmp(buf, "%%BoundingBox:", 14)) { + double illx, illy, iurx, iury; /* input bbox parameters */ + if (sscanf(buf, "%%%%BoundingBox:%lf %lf %lf %lf\n", + &illx, &illy, &iurx, &iury) == 4) { + bbfound = 1; + llx = (int)illx; /* accept doubles, but convert to int */ + lly = (int)illy; + urx = (int)(iurx+0.5); + ury = (int)(iury+0.5); + } + } else if (!strncmp(buf, "%%EndComments", 13)) { + strcpy(buf, "\n"); /* don't repeat %%EndComments */ + break; + } else fputs(buf, output); + } else break; + } + + if (bbfound) { /* put BB, followed by scale&translate */ + int fwidth, fheight; + double xscale, yscale; + double xoffset = fllx, yoffset = flly; + double width = urx-llx, height = ury-lly; + + if (maximise) + if ((width > height && fury-flly > furx-fllx) || + (width < height && fury-flly < furx-fllx)) + rotate = 1; + + if (rotate) { + fwidth = fury - flly; + fheight = furx - fllx; + } else { + fwidth = furx - fllx; + fheight = fury - flly; + } + + xscale = fwidth/width; + yscale = fheight/height; + + if (!aspect) { /* preserve aspect ratio ? */ + xscale = yscale = MIN(xscale,yscale); + } + width *= xscale; /* actual width and height after scaling */ + height *= yscale; + if (centre) { + if (rotate) { + xoffset += (fheight - height)/2; + yoffset += (fwidth - width)/2; + } else { + xoffset += (fwidth - width)/2; + yoffset += (fheight - height)/2; + } + } + fprintf(output, + "%%%%BoundingBox: %d %d %d %d\n", (int)xoffset, (int)yoffset, + (int)(xoffset+(rotate ? height : width)), + (int)(yoffset+(rotate ? width : height))); + if (rotate) { /* compensate for original image shift */ + xoffset += height + lly * yscale; /* displacement for rotation */ + yoffset -= llx * xscale; + } else { + xoffset -= llx * xscale; + yoffset -= lly * yscale; + } + fputs("%%EndComments\n", output); + if (showpage) + fputs("save /showpage{}def /copypage{}def /erasepage{}def\n", output); + else + fputs("%%BeginProcSet: epsffit 1 0\n", output); + fputs("gsave\n", output); + fprintf(output, "%.3f %.3f translate\n", xoffset, yoffset); + if (rotate) + fputs("90 rotate\n", output); + fprintf(output, "%.3f %.3f scale\n", xscale, yscale); + if (!showpage) + fputs("%%EndProcSet\n", output); + } + do { + fputs(buf, output); + } while (fgets(buf, BUFSIZ, input)); + if (bbfound) { + fputs("grestore\n", output); + if (showpage) + fputs("restore showpage\n", output); /* just in case */ + } else + message(FATAL, "no %%%%BoundingBox:\n"); + + return 0; +} diff --git a/Build/source/utils/psutils/psutils-1.21/extractres b/Build/source/utils/psutils/psutils-1.21/extractres new file mode 100755 index 00000000000..87f8377b34d --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/extractres @@ -0,0 +1,117 @@ +#!/usr/bin/env perl +# extractres: extract resources from PostScript file +# includeres: add resources to a PostScript file +# +# (c) Reuben Thomas 2012 +# (c) Angus J. C. Duggan 1991-1997 +# See file LICENSE for details. + +use strict; +use warnings; + +use File::Basename; +use Getopt::Long; + +my $prog = basename($0); + +# Resource extensions +my %extn = ("font" => ".pfa", "file" => ".ps", "procset" => ".ps", + "pattern" => ".pat", "form" => ".frm", "encoding" => ".enc"); +# Resource types +my %type = ("%%BeginFile:" => "file", "%%BeginProcSet:" => "procset", + "%%BeginFont:" => "font"); + +sub filename { # make filename for resource in @_ + my $name; + foreach (@_) { # sanitise name + s/[!()\$\#*&\\\|\`\'\"\~\{\}\[\]\<\>\?]//g; + $name .= $_; + } + $name =~ s@.*/@@; # drop directories + die "$prog: filename not found for resource ", join(" ", @_), "\n" + if $name =~ /^$/; + return $name; +} + +sub extract { + my %resources = (); # list of resources included + my %merge = (); # list of resources extracted this time + + my $merge; + unless (GetOptions('merge' => \$merge)) { + print STDERR "Usage: $prog [-merge] [FILE]\n"; + exit 1; + } + + my $prolog = ""; + my $body = ""; + my $resource = ""; + my $output = \$prolog; + my $saveout; + while (<>) { + if (/^%%BeginResource:/ || /^%%BeginFont:/ || /^%%BeginProcSet:/) { + my ($comment, @res) = split(/\s+/); # look at resource type + my $type = defined($type{$comment}) ? $type{$comment} : shift(@res); + my $name = filename(@res, $extn{$type}); # make file name + $saveout = $output; + if (!defined($resources{$name})) { + $prolog .= "%%IncludeResource: $type " . join(" ", @res) . "\n"; + if (!-e $name) { + open RES, ">$name" || die "$prog: can't write file `$name'\n"; + $resources{$name} = ""; + $merge{$name} = $merge; + $output = \$resources{$name}; + } else { # resource already exists + close(RES); + undef $output; + } + } elsif ($merge{$name}) { + open RES, ">>$name" || die "$prog: can't append to file `$name'\n"; + $resources{$name} = ""; + $output = \$resources{$name}; + } else { # resource already included + undef $output; + } + } elsif (/^%%EndResource/ || /^%%EndFont/ || /^%%EndProcSet/) { + if (defined $output) { + $$output .= $_; + print RES $$output; + } + $output = $saveout; + next; + } elsif ((/^%%EndProlog/ || /^%%BeginSetup/ || /^%%Page:/)) { + $output = \$body; + } + $$output .= $_ if defined $output; + } + + print $prolog . $body; +} + +sub include { + while (<>) { + if (/^%%IncludeResource:/ || /^%%IncludeFont:/ || /^%%IncludeProcSet:/) { + my ($comment, @res) = split(/\s+/); + my $type = defined($type{$comment}) ? $type{$comment} : shift(@res); + my $name = filename(@res); + if (open(RES, $name) || open(RES, "$name$extn{$type}")) { + print do { local $/; <RES> }; + close(RES); + } else { + print "%%IncludeResource: ", join(" ", $type, @res), "\n"; + print STDERR "$prog: resource `$name' not found\n"; + } + } else { + print $_; + } + } +} + +# Perform function according to name +if ($prog eq "extractres") { + extract(); +} elsif ($prog eq "includeres") { + include(); +} else { + die "$prog: I need to be called `extractres' or `includeres'\n"; +} diff --git a/Build/source/utils/psutils/psutils-1.21/extractres.1 b/Build/source/utils/psutils/psutils-1.21/extractres.1 new file mode 100644 index 00000000000..33d96f7cb0e --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/extractres.1 @@ -0,0 +1,47 @@ +.TH EXTRACTRES 1 "PSUtils" +.SH NAME +extractres \- filter to extract resources from a PostScript document +.SH SYNOPSIS +.B extractres +[ +.B \-m +] < +.I document.ps +> +.I output.ps +.SH DESCRIPTION +.I Extractres +extracts resources (fonts, procsets, patterns, files, etc) appearing in a +PostScript document, and puts appropriate +.I %%IncludeResource +comments in the document prologue. The extracted resources are written to +files with the same name as the resource, and an appropriate extension. The +pipeline +.sp +.ce +extractres file.ps | includeres >out.ps +.sp +will move all resources appearing in a document to the document prologue, +removing redundant copies. The output file can then be put through page +re-arrangement filters such as +.I psnup +or +.I pstops +safely. +.PP +The +.B \-m +option combines the resources of the same name into one file; this must be +used for some programs which download fonts a bit at a time. +.SH AUTHOR +Written by Angus J. C. Duggan. +.SH "SEE ALSO" +psutils(1) +.SH TRADEMARKS +.B PostScript +is a trademark of Adobe Systems Incorporated. +.SH BUGS +.I extractres +does not alter the +.I %%DocumentSuppliedResources +comments. diff --git a/Build/source/utils/psutils/psutils-1.21/includeres.1 b/Build/source/utils/psutils/psutils-1.21/includeres.1 new file mode 100644 index 00000000000..281dc187146 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/includeres.1 @@ -0,0 +1,39 @@ +.TH INCLUDERES 1 "PSUtils" +.SH NAME +includeres \- filter to include resources in a PostScript document +.SH SYNOPSIS +.B includeres +< +.I document.ps +> +.I output.ps +.SH DESCRIPTION +.I Includeres +includes resources (fonts, procsets, patterns, files, etc.) in place of +.I %%IncludeResource +comments in a PostScript document. The resources are searched for +under the resource name, and with an appropriate extension. +The pipeline +.sp +.ce +extractres file.ps | includeres >out.ps +.sp +will move all resources appearing in a document to the document prologue, +removing redundant copies. The output file can then be put through page +re-arrangement filters such as +.I psnup +or +.I pstops +safely. +.SH AUTHOR +Written by Angus J. C. Duggan. +.SH "SEE ALSO" +psutils(1) +.SH TRADEMARKS +.B PostScript +is a trademark of Adobe Systems Incorporated. +.SH BUGS +.I includeres +does not alter the +.I %%DocumentNeededResources +comments. diff --git a/Build/source/utils/psutils/psutils-1.21/psbook.1 b/Build/source/utils/psutils/psutils-1.21/psbook.1 new file mode 100644 index 00000000000..53fd770a5e4 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psbook.1 @@ -0,0 +1,42 @@ +.TH PSBOOK 1 "PSUtils" +.SH NAME +psbook \- rearrange pages in PostScript file into signatures +.SH SYNOPSIS +.B psbook +[ +.B \-q +] [ +.B \-s\fIsignature\fR +] [ +.I infile +[ +.I outfile +] ] +.SH DESCRIPTION +.I Psbook +rearranges pages from a PostScript document into ``signatures'' for +printing books or booklets, creating a new PostScript file. The +input PostScript file should follow the Adobe Document Structuring +Conventions. +.PP +The +.I \-s +option selects the size of signature which will be used. The signature size is +the number of sides which will be folded and bound together; the number given +should be a multiple of four. The default is to use one signature for the +whole file. Extra blank sides will be added if the file does not contain a +multiple of four pages. +.PP +Psbook normally prints the page numbers of the pages rearranged; the +.I \-q +option suppresses this. +.SH AUTHOR +Written by Angus J. C. Duggan. +.SH "SEE ALSO" +psutils(1) +.SH TRADEMARKS +.B PostScript +is a trademark of Adobe Systems Incorporated. +.SH BUGS +.I Psbook +does not accept all DSC comments. diff --git a/Build/source/utils/psutils/psutils-1.21/psbook.c b/Build/source/utils/psutils/psutils-1.21/psbook.c new file mode 100644 index 00000000000..b77c223d229 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psbook.c @@ -0,0 +1,106 @@ +/* psbook.c + * (c) Reuben Thomas 2012 + * (c) Angus J. C. Duggan 1991-1997 + * See file LICENSE for details. + * + * rearrange pages in conforming PS file for printing in signatures + */ + +#include "config.h" +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include "psutil.h" + +const char *syntax = "[-q] [-sSIGNATURE] [INFILE [OUTFILE]]\n SIGNATURE must be positive and divisible by 4\n"; + +const char *argerr_message = ""; + +int +main(int argc, char *argv[]) +{ + int signature = 0; + int currentpg, maxpage; + int opt; + + SET_BINARY(stdin); + SET_BINARY(stdout); + + verbose = 1; + program = *argv; + + while((opt = getopt(argc, argv, "vqs:")) != EOF) { + switch(opt) { + case 's': /* signature size */ + signature = atoi(optarg); + if (signature < 1 || signature % 4) usage(); + break; + case 'q': /* quiet */ + verbose = 0; + break; + case 'v': /* version */ + default: + usage(); + break; + } + } + + infile = stdin; + outfile = stdout; + + /* Be defensive */ + if((argc - optind) < 0 || (argc - optind) > 2) usage(); + + if (optind != argc) { + /* User specified an input file */ + if ((infile = fopen(argv[optind], "rb")) == NULL) + message(FATAL, "can't open input file %s\n", argv[optind]); + optind++; + } + + if (optind != argc) { + /* User specified an output file */ + if ((outfile = fopen(argv[optind], "wb")) == NULL) + message(FATAL, "can't open output file %s\n", argv[optind]); + optind++; + } + + if(optind != argc) usage(); + + if ((infile=seekable(infile))==NULL) + message(FATAL, "can't seek input\n"); + + scanpages(NULL); + + if (!signature) + signature = maxpage = pages+(4-pages%4)%4; + else + maxpage = pages+(signature-pages%signature)%signature; + + /* rearrange pages */ + writeheader(maxpage, NULL); + writeprolog(); + writesetup(); + for (currentpg = 0; currentpg < maxpage; currentpg++) { + int actualpg = currentpg - currentpg%signature; + switch(currentpg%4) { + case 0: + case 3: + actualpg += signature-1-(currentpg%signature)/2; + break; + case 1: + case 2: + actualpg += (currentpg%signature)/2; + break; + default: /* Avoid a compiler warning */ + break; + } + if (actualpg < pages) + writepage(actualpg); + else + writeemptypage(); + } + writetrailer(); + + return 0; +} diff --git a/Build/source/utils/psutils/psutils-1.21/psjoin b/Build/source/utils/psutils/psutils-1.21/psjoin new file mode 100755 index 00000000000..21dfaffeef3 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psjoin @@ -0,0 +1,220 @@ +#!/usr/bin/env perl +# +# psjoin - concatenate PostScript files +# +# version 0.2, 2002-07-18 +# version 0.3, 2003-11-30 +# version 0.31, 2013-10-20 +# +# versions up to 0.3 by Tom Sato <VEF00200@nifty.ne.jp>, http://homepage3.nifty.com/tsato/ +# versions from 0.31 by Reuben Thomas <rrt@sc3d.org> + +use strict; +use warnings; + +use Getopt::Long; + +my $version = 0.31; + +sub usage { + my ($exit_code) = @_; + print STDERR <<END; +Usage: psjoin [OPTION...] FILENAME... +Concatenate PostScript files + + --even, -a force each file to take an even number of pages + --save, -s try to close unclosed save operators + --strip, -p do not strip prolog or trailer from input files + --help, -h print this help, then exit + --version,-V print version information and exit +END + exit $exit_code; +} + +my $force_even = 0; +my $force_save = 0; +my $dont_strip = 0; +my $save = "save %psjoin\n"; +my $restore = "restore %psjoin\n"; +my ($help_flag, $version_flag); + +GetOptions( + "even|a" => \$force_even, + "save|s" => \$force_save, + "strip|p" => \$dont_strip, + "help|h" => \$help_flag, + "version|V" => \$version_flag, + ) or usage(1); + +if ($help_flag) { + usage(0); +} elsif ($version_flag) { + print "psjoin (version $version)\n"; + print "(c) Tom Sato <VEF00200\@nifty.ne.jp> and Reuben Thomas <rrt\@sc3d.org>\n"; + exit 0; +} + +if ($force_save) { + $save = "/#psjoin-save# save def %psjoin\n"; + $restore = "#psjoin-save# restore %psjoin\n"; +} +my (@prolog, $prolog_inx, @trailer, @comments, @pages); +if ($dont_strip) { + $prolog_inx = 9999; + $prolog[$prolog_inx] = "% [ psjoin: don't strip ]\n"; + $trailer[$prolog_inx] = "% [ psjoin: don't strip ]\n"; +} else { + for (my $i = 0; $i <= $#ARGV; $i++) { + open(IN, $ARGV[$i]) || die "$0: can't open \"$ARGV[$i]\" ($!)"; + + my $in_comment = 1; + my $in_prolog = 1; + my $in_trailer = 0; + $comments[$i] = ""; + $prolog[$i] = ""; + $trailer[$i] = ""; + $pages[$i] = 0; + while (<IN>) { + next if /^%%BeginDocument/ .. /^%%EndDocument/; + + if ($in_comment) { + next if /^%!PS-Adobe-/; + next if /^%%Title/; + next if /^%%Pages/; + next if /^%%Creator/; + $in_comment = 0 if /^%%EndComments/; + $comments[$i] .= $_; + next; + } elsif ($in_prolog) { + if (/^%%Page:/) { + $in_prolog = 0; + } else { + $prolog[$i] .= $_; + next; + } + } + + $in_trailer = 1 if /^%%Trailer/; + if ($in_trailer) { + $trailer[$i] .= $_; + next; + } + + $pages[$i]++ if /^%%Page:/; + } + close(IN); + + if ($prolog[$i]) { + for (my $j = 0; $j < $i; $j++) { + if ($prolog[$j] eq $prolog[$i]) { + $pages[$j] += $pages[$i]; + last; + } + } + } + } + + my $largest = 0; + $prolog_inx = 0; + for (my $i = 0; $i <= $#ARGV; $i++) { + my $size = length($prolog[$i]) * $pages[$i]; + if ($largest < $size) { + $largest = $size; + $prolog_inx = $i; + } + } +} + +print <<END; +%!PS-Adobe-3.0 +%%Title: @ARGV +%%Creator: psjoin $version +%%Pages: (atend) +END +print $comments[$prolog_inx]; + +print "\n$prolog[$prolog_inx]"; +for (my $i = 0; $i <= $#ARGV; $i++) { + $prolog[$i] =~ s/^%%/% %%/; + $prolog[$i] =~ s/\n%%/\n% %%/g; + $trailer[$i] =~ s/^%%/% %%/; + $trailer[$i] =~ s/\n%%/\n% %%/g; +} + +my $total_pages = 0; +for (my $i = 0; $i <= $#ARGV; $i++) { + print "\n% [ psjoin: file = $ARGV[$i] ]\n"; + if ($prolog[$i] ne $prolog[$prolog_inx]) { + print "% [ psjoin: Prolog/Trailer will be inserted in each page ]\n"; + } else { + print "% [ psjoin: common Prolog/Trailer will be used ]\n"; + } + + my $in_comment = 1 if !$dont_strip; + my $in_prolog = 1 if !$dont_strip; + my $in_trailer = 0; + my $saved = 0; + my $pages = 0; + + open(IN, $ARGV[$i]) || die "$0: can't open \"$ARGV[$i]\" ($!)"; + while (<IN>) { + if (/^%%BeginDocument/ .. /^%%EndDocument/) { + # s/^(%[%!])/% \1/; + print $_; + } else { + if ($in_comment) { + $in_comment = 0 if /^%%EndComments/; + } elsif ($in_prolog) { + if (/^%%Page:/) { + $in_prolog = 0; + } else { + next; + } + } + $in_trailer = 1 if !$dont_strip && /^%%Trailer/; + next if $in_trailer; + + if (/^%%Page:/) { + if ($saved) { + print $trailer[$i]; + print $restore; + $saved = 0; + } + + $pages++; + $total_pages++; + print "\n"; + print "%%Page: ($i-$pages) $total_pages\n"; + if ($prolog[$i] ne $prolog[$prolog_inx]) { + print $save; + print $prolog[$i]; + $saved = 1; + } elsif ($force_save) { + print $save; + } + } else { + s/^(%[%!])/% $1/; + print $_; + } + } + } + close(IN); + + if ($force_even && $pages % 2 != 0) { + $pages++; + $total_pages++; + print <<END; + +%%Page: ($i-E) $total_pages +% [ psjoin: empty page inserted to force even pages ] +showpage +END + } + + print $trailer[$i] if $saved; + print $restore if $saved || $force_save; +} + +print "\n%%Trailer\n"; +print $trailer[$prolog_inx]; +print "\n%%Pages: $total_pages\n%%EOF"; diff --git a/Build/source/utils/psutils/psutils-1.21/psjoin.1 b/Build/source/utils/psutils/psutils-1.21/psjoin.1 new file mode 100644 index 00000000000..c048d4708e8 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psjoin.1 @@ -0,0 +1,18 @@ +.TH PSJOIN "1" "November 2003" "psjoin 0.3" "User Commands" +.SH NAME +psjoin \- psjoin +.SH SYNOPSIS +.B psjoin +[ \fIoptions\fR... ] \fIfilenames\fR... +.SH DESCRIPTION +psjoin \- concatenate PostScript files (version 0.3) +by Tom Sato <VEF00200@nifty.ne.jp>, http://member.nifty.ne.jp/tsato/ +.SS "Option:" +.HP +\fB\-a\fR: align first page of each documents to odd page +.HP +\fB\-s\fR: try to close unclosed save operators +.HP +\fB\-p\fR: not strip prolog/trailer of the input files +.HP +\fB\-h\fR: display help diff --git a/Build/source/utils/psutils/psutils-1.21/psnup.1 b/Build/source/utils/psutils/psutils-1.21/psnup.1 new file mode 100644 index 00000000000..200b4eb6406 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psnup.1 @@ -0,0 +1,155 @@ +.TH PSNUP 1 "PSUtils" +.SH NAME +psnup \- multiple pages per sheet +.SH SYNOPSIS +.B psnup +[ +.B \-w\fIwidth\fR +] [ +.B \-h\fIheight\fR +] [ +.B \-p\fIpaper\fR +] [ +.B \-W\fIwidth\fR +] [ +.B \-H\fIheight\fR +] [ +.B \-P\fIpaper\fR +] [ +.B \-l +] [ +.B \-r +] [ +.B \-f +] [ +.B \-c +] [ +.B \-m\fImargin\fR +] [ +.B \-b\fIborder\fR +] [ +.B \-d\fIlwidth\fR +] [ +.B \-s\fIscale\fR +] [ +.B \-n\fIup\fR +] [ +.B \-q +] [ +.I infile +[ +.I outfile +] ] +.SH DESCRIPTION +.I Psnup +puts multiple logical pages onto each physical sheet of paper. +The input PostScript file should follow the Adobe Document Structuring +Conventions. +.PP +The +.I \-w +option gives the paper width, and the +.I \-h +option gives the paper height, specified in +.BR pt , +.BR mm , +.BR cm , +or +.BR in . +The +.I \-p +option can be used instead, to set the paper size; otherwise a default value is used. +See +.BR papersize (5). +The +.I \-W, \-H, +and +.I \-P +options set the input paper size, if it is different from the output +size. This makes it easy to impose pages of one size on a different size of +paper. +.PP +The +.I \-l +option should be used for pages which are in landscape orientation (rotated 90 +degrees anticlockwise). The +.I \-r +option should be used for pages which are in seascape orientation (rotated 90 +degrees clockwise), and the +.I \-f +option should be used for pages which have the width and height interchanged, +but are not rotated. +.PP +.I Psnup +normally uses `row-major' layout, where adjacent pages are placed in rows +across the paper. +The +.I \-c +option changes the order to `column-major', where successive pages are placed +in columns down the paper. +.PP +A margin to leave around the whole page can be specified with the +.I \-m +option. This is useful for sheets of `thumbnail' pages, because the normal +page margins are reduced by putting multiple pages on a single sheet. +.PP +The +.I \-b +option is used to specify an additional margin around each page on a sheet. +.PP +The +.I \-d +option draws a line around the border of each page, of the specified width. +If the \fIlwidth\fR parameter is omitted, a default linewidth of 1 point is +assumed. The linewidth is relative to the original page dimensions, +\fIi.e.\fR it is scaled down with the rest of the page. +.PP +The scale chosen by +.I psnup +can be overridden with the +.I \-s +option. This is useful to merge pages which are already reduced. +.PP +The +.I \-\fInup\fR +option selects the number of logical pages to put on each sheet of paper. This +can be any whole number; +.I psnup +tries to optimise the layout so that the minimum amount of space is wasted. If +.I psnup +cannot find a layout within its tolerance limit, it will abort with an error +message. The alternative form +.I \i \fInup\fR +can also be used, for compatibility with other n-up programs. +.PP +.I Psnup +normally prints the page numbers of the pages re-arranged; the +.I \-q +option suppresses this. +.SH EXAMPLES +The potential use of this utility is varied but one particular +use is in conjunction with +.I psbook(1). +For example, using groff to create a PostScript document and lpr as +the +.SM UNIX +print spooler a typical command line might look like this: +.sp +groff -Tps -ms \fIfile\fP | psbook | psnup -2 | lpr +.sp +Where file is a 4 page document this command will result in a +two page document printing two pages of \fIfile\fP per page and +rearranges the page order to match the input pages 4 and 1 +on the first output page and +pages 2 then 3 of the input document +on the second output page. +.SH AUTHOR +Written by Angus J. C. Duggan. +.SH "SEE ALSO" +psutils(1) +.SH TRADEMARKS +.B PostScript +is a trademark of Adobe Systems Incorporated. +.SH BUGS +.I Psnup +does not accept all DSC comments. diff --git a/Build/source/utils/psutils/psutils-1.21/psnup.c b/Build/source/utils/psutils/psutils-1.21/psnup.c new file mode 100644 index 00000000000..cfbe5f6968a --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psnup.c @@ -0,0 +1,318 @@ +/* psnup.c + * Put multiple pages on to one page + * + * (c) Reuben Thomas 2012 + * (c) Angus J. C. Duggan 1991-1997 + * See file LICENSE for details. + */ + +#include "config.h" +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <string.h> +#include <paper.h> + +#include "psutil.h" +#include "psspec.h" + +const char *syntax = "[-q] [-wWIDTH] [-hHEIGHT] [-pPAPER] [-WWIDTH] [-HHEIGHT] [-PPAPER] [-l] [-r] [-c] [-f] [-mMARGIN] [-bBORDER] [-dLWIDTH] [-sSCALE] [-NUP] [INFILE [OUTFILE]]\n"; + +const char *argerr_message = "bad dimension\n"; + +/* return next larger exact divisor of number, or 0 if none. There is probably + * a much more efficient method of doing this, but the numbers involved are + * small, so it's not a big loss. */ +_GL_ATTRIBUTE_CONST static int nextdiv(int n, int m) +{ + while (++n <= m) { + if (m%n == 0) + return (n); + } + return (0); +} + +int +main(int argc, char *argv[]) +{ + int horiz = 0, vert = 0, rotate = 0, column = 0; + int flip = 0, leftright = 0, topbottom = 0; + int nup = 1; + double draw = 0; /* draw page borders */ + double scale = 1.0; /* page scale */ + double uscale = 0; /* user supplied scale */ + double ppwid, pphgt; /* paper dimensions */ + double margin, border; /* paper & page margins */ + double vshift, hshift; /* page centring shifts */ + double iwidth, iheight ; /* input paper size */ + double tolerance = 100000; /* layout tolerance */ + off_t sizeheaders[20]; /* headers to remove */ + int opt; + const struct paper *paper = NULL; + + SET_BINARY(stdin); + SET_BINARY(stdout); + + set_paper_size(NULL); + + margin = border = vshift = hshift = column = flip = 0; + leftright = topbottom = 1; + iwidth = iheight = -1 ; + + verbose = 1; + program = *argv; + + while((opt = + getopt(argc, argv, + "qd::lrfcw:W:h:H:m:b:t:s:p:P:n:1::2::3::4::5::6::7::8::9::")) + != EOF) { + switch(opt) { + case 'q': /* quiet */ + verbose = 0; + break; + case 'd': /* draw borders */ + if (optarg) + draw = singledimen(optarg); + else + draw = 1; + break; + case 'l': /* landscape (rotated left) */ + column = !column; + topbottom = !topbottom; + break; + case 'r': /* seascape (rotated right) */ + column = !column; + leftright = !leftright; + break; + case 'f': /* flipped */ + flip = 1; + break; + case 'c': /* column major layout */ + column = !column; + break; + case 'w': /* page width */ + width = singledimen(optarg); + break; + case 'W': /* input page width */ + iwidth = singledimen(optarg); + break; + case 'h': /* page height */ + height = singledimen(optarg); + break; + case 'H': /* input page height */ + iheight = singledimen(optarg); + break; + case 'm': /* margins around whole page */ + margin = singledimen(optarg); + break; + case 'b': /* border around individual pages */ + border = singledimen(optarg); + break; + case 't': /* layout tolerance */ + tolerance = atof(optarg); + break; + case 's': /* override scale */ + uscale = atof(optarg); + break; + case 'p': /* output (and by default input) paper type */ + if ( (paper = paperinfo(optarg)) != NULL ) { + width = paperpswidth(paper); + height = paperpsheight(paper); + } else + message(FATAL, "paper size '%s' not recognised\n", optarg); + break; + case 'P': /* paper type */ + if ( (paper = paperinfo(optarg)) != NULL ) { + iwidth = paperpswidth(paper); + iheight = paperpsheight(paper); + } else + message(FATAL, "paper size '%s' not recognised\n", optarg); + break; + case 'n': /* n-up, for compatibility with other psnups */ + if ((nup = atoi(optarg)) < 1) + message(FATAL, "-n %d too small\n", nup); + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if(optarg) { + char *valuestr = (char *) malloc(strlen(optarg) + 2); + valuestr[0] = opt; + strcpy(&(valuestr[1]), optarg); + + /* really should check that valuestr is only digits here...*/ + if ((nup = atoi(valuestr)) < 1) + message(FATAL, "-n %d too small\n", nup); + free(valuestr); + } else { + nup = (opt - '0'); + } + break; + case 'v': /* version */ + default: + usage(); + } + } + + infile = stdin; + outfile = stdout; + + /* Be defensive */ + if((argc - optind) < 0 || (argc - optind) > 2) usage(); + + if (optind != argc) { + /* User specified an input file */ + if ((infile = fopen(argv[optind], "rb")) == NULL) + message(FATAL, "can't open input file %s\n", argv[optind]); + optind++; + } + + if (optind != argc) { + /* User specified an output file */ + if ((outfile = fopen(argv[optind], "wb")) == NULL) + message(FATAL, "can't open output file %s\n", argv[optind]); + optind++; + } + + if (optind != argc) usage(); + + if ((infile=seekable(infile))==NULL) + message(FATAL, "can't seek input\n"); + + if (width <= 0 || height <= 0) + message(FATAL, "page width and height must be set\n"); + + /* subtract paper margins from height & width */ + ppwid = width - margin*2; + pphgt = height - margin*2; + + if (ppwid <= 0 || pphgt <= 0) + message(FATAL, "paper margins are too large\n"); + + scanpages(sizeheaders); + + /* set default values of input height & width */ + if ( iwidth > 0 && width == -1 ) + width = iwidth ; + if ( iheight > 0 && height == -1 ) + height = iheight ; + + /* Finding the best layout is an optimisation problem. We try all of the + * combinations of width*height in both normal and rotated form, and + * minimise the wasted space. */ + { + double best = tolerance; + int hor; + for (hor = 1; hor; hor = nextdiv(hor, nup)) { + int ver = nup/hor; + /* try normal orientation first */ + double scl = MIN(pphgt/(height*ver), ppwid/(width*hor)); + double optim = (ppwid-scl*width*hor)*(ppwid-scl*width*hor) + + (pphgt-scl*height*ver)*(pphgt-scl*height*ver); + if (optim < best) { + best = optim; + /* recalculate scale to allow for internal borders */ + scale = MIN((pphgt-2*border*ver)/(height*ver), + (ppwid-2*border*hor)/(width*hor)); + hshift = (ppwid/hor - width*scale)/2; + vshift = (pphgt/ver - height*scale)/2; + horiz = hor; vert = ver; + rotate = flip; + } + /* try rotated orientation */ + scl = MIN(pphgt/(width*hor), ppwid/(height*ver)); + optim = (pphgt-scl*width*hor)*(pphgt-scl*width*hor) + + (ppwid-scl*height*ver)*(ppwid-scl*height*ver); + if (optim < best) { + best = optim; + /* recalculate scale to allow for internal borders */ + scale = MIN((pphgt-2*border*hor)/(width*hor), + (ppwid-2*border*ver)/(height*ver)); + hshift = (ppwid/ver - height*scale)/2; + vshift = (pphgt/hor - width*scale)/2; + horiz = ver; vert = hor; + rotate = !flip; + } + } + + /* fail if nothing better than worst tolerance was found */ + if (best == tolerance) + message(FATAL, "can't find acceptable layout for %d-up\n", nup); + } + + if (flip) { /* swap width & height for clipping */ + double tmp = width; + width = height; + height = tmp; + } + + if (rotate) { /* rotate leftright and topbottom orders */ + int tmp = topbottom; + topbottom = !leftright; + leftright = tmp; + column = !column; + } + + /* now construct specification list and run page rearrangement procedure */ + { + int page = 0; + PageSpec *specs, *tail; + + tail = specs = newspec(); + + while (page < nup) { + int up, across; /* page index */ + + if (column) { + if (leftright) /* left to right */ + across = page/vert; + else /* right to left */ + across = horiz-1-page/vert; + if (topbottom) /* top to bottom */ + up = vert-1-page%vert; + else /* bottom to top */ + up = page%vert; + } else { + if (leftright) /* left to right */ + across = page%horiz; + else /* right to left */ + across = horiz-1-page%horiz; + if (topbottom) /* top to bottom */ + up = vert-1-page/horiz; + else /* bottom to top */ + up = page/horiz; + } + if (rotate) { + tail->xoff = margin + (across+1)*ppwid/horiz - hshift; + tail->rotate = 90; + tail->flags |= ROTATE; + } else { + tail->xoff = margin + across*ppwid/horiz + hshift; + } + tail->pageno = page; + if (uscale > 0) + tail->scale = uscale; + else + tail->scale = scale; + tail->flags |= SCALE; + tail->yoff = margin + up*pphgt/vert + vshift; + tail->flags |= OFFSET; + if (++page < nup) { + tail->flags |= ADD_NEXT; + tail->next = newspec(); + tail = tail->next; + } + } + + pstops_write(nup, 1, 0, specs, draw, sizeheaders); /* do page rearrangement */ + } + + return 0; +} + diff --git a/Build/source/utils/psutils/psutils-1.21/psresize.1 b/Build/source/utils/psutils/psutils-1.21/psresize.1 new file mode 100644 index 00000000000..3e5e751b194 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psresize.1 @@ -0,0 +1,78 @@ +.TH PSRESIZE 1 "PSUtils" +.SH NAME +psresize \- rescales and centers a document for new output paper size +.SH SYNOPSIS +.B psresize +[ +.B \-w\fIwidth\fR +] [ +.B \-h\fIheight\fR +] [ +.B \-p\fIpaper\fR +] [ +.B \-W\fIwidth\fR +] [ +.B \-H\fIheight\fR +] [ +.B \-P\fIpaper\fR +] [ +.B \-q +] [ +.I infile +[ +.I outfile +] ] +.SH DESCRIPTION +.I Psresize +rescales and centres a document on a different size of paper. +The input PostScript file should follow the Adobe Document Structuring +Conventions. +.PP +The +.I \-w +option gives the output paper width, and the +.I \-h +option gives the output paper height, normally specified in +.B "cm" +or +.B "in" +to convert +PostScript's points (1/72 of an inch) +to centimeters or inches. +The +.I \-p +option can be used instead, to set the paper size; otherwise a default value is used. +See +.BR papersize (5). +.PP +The +.I \-W +option gives the input paper width, and the +.I \-H +option gives the input paper height. +The +.I \-P +option can be used instead, to set the paper size; otherwise a default value is used. +See +.BR papersize (5). +.PP +.I Psresize +normally prints the page numbers of the pages output; the +.I \-q +option suppresses this. +.SH EXAMPLES +The following command can be used to convert a document on A4 size paper to +letter size paper: +.sp +psresize -PA4 -pletter in.ps out.ps +.sp +.SH AUTHOR +Written by Angus J. C. Duggan. +.SH "SEE ALSO" +psutils(1) +.SH TRADEMARKS +.B PostScript +is a trademark of Adobe Systems Incorporated. +.SH BUGS +.I Psresize +does not accept all DSC comments. diff --git a/Build/source/utils/psutils/psutils-1.21/psresize.c b/Build/source/utils/psutils/psutils-1.21/psresize.c new file mode 100644 index 00000000000..bd1f961488b --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psresize.c @@ -0,0 +1,162 @@ +/* psresize.c + * Alter page size of document + * + * (c) Reuben Thomas 2012 + * (c) Angus J. C. Duggan 1991-1997 + * See file LICENSE for details. + */ + +#include "config.h" +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <paper.h> + +#include "psutil.h" +#include "psspec.h" + +const char *syntax = "[-q] [-wWIDTH] [-hHEIGHT] [-pPAPER] [-WWIDTH] [-HHEIGHT] [-PPAPER] [INFILE [OUTFILE]]\n"; + +const char *argerr_message = "bad dimension\n"; + +int +main(int argc, char *argv[]) +{ + double scale, rscale; /* page scale */ + double waste, rwaste; /* amount wasted */ + double vshift, hshift; /* page centring shifts */ + int rotate; + double inwidth = -1; + double inheight = -1; + off_t sizeheaders[20]; /* headers to remove */ + PageSpec *specs; + int opt; + const struct paper *paper = NULL; + + SET_BINARY(stdin); + SET_BINARY(stdout); + + set_paper_size(NULL); + + vshift = hshift = 0; + rotate = 0; + + verbose = 1; + + program = *argv; + + while((opt = getopt(argc, argv, + "qw:h:p:W:H:P:")) != EOF) { + switch(opt) { + + case 'q': /* quiet */ + verbose = 0; + break; + case 'w': /* page width */ + width = singledimen(optarg); + break; + case 'h': /* page height */ + height = singledimen(optarg); + break; + case 'p': /* paper type */ + if ( (paper = paperinfo(optarg)) != NULL ) { + width = paperpswidth(paper); + height = paperpsheight(paper); + } else + message(FATAL, "paper size '%s' not recognised\n", optarg); + break; + case 'W': /* input page width */ + inwidth = singledimen(optarg); + break; + case 'H': /* input page height */ + inheight = singledimen(optarg); + break; + case 'P': /* input paper type */ + if ( (paper = paperinfo(optarg)) != NULL ) { + inwidth = paperpswidth(paper); + inheight = paperpsheight(paper); + } else + message(FATAL, "paper size '%s' not recognised\n", optarg); + break; + case 'v': /* version */ + default: + usage(); + } + } + + infile = stdin; + outfile = stdout; + + /* Be defensive */ + if((argc - optind) < 0 || (argc - optind) > 2) usage(); + + if (optind != argc) { + /* User specified an input file */ + if ((infile = fopen(argv[optind], "rb")) == NULL) + message(FATAL, "can't open input file %s\n", argv[optind]); + optind++; + } + + if (optind != argc) { + /* User specified an output file */ + if ((outfile = fopen(argv[optind], "wb")) == NULL) + message(FATAL, "can't open output file %s\n", argv[optind]); + optind++; + } + + if (optind != argc) usage(); + + if ((infile=seekable(infile))==NULL) + message(FATAL, "can't seek input\n"); + + if (width <= 0 || height <= 0) + message(FATAL, "output page width and height must be set\n"); + + scanpages(sizeheaders); + + if (inwidth <= 0 || inheight <= 0) + message(FATAL, "input page width and height must be set\n"); + + /* try normal orientation first */ + scale = MIN(width/inwidth, height/inheight); + waste = (width-scale*inwidth)*(width-scale*inwidth) + + (height-scale*inheight)*(height-scale*inheight); + hshift = (width - inwidth*scale)/2; + vshift = (height - inheight*scale)/2; + + /* try rotated orientation */ + rscale = MIN(height/inwidth, width/inheight); + rwaste = (height-scale*inwidth)*(height-scale*inwidth) + + (width-scale*inheight)*(width-scale*inheight); + if (rwaste < waste) { + double tmp = width; + scale = rscale; + hshift = (width + inheight*scale)/2; + vshift = (height - inwidth*scale)/2; + rotate = 1; + width = height; + height = tmp; + } + + width /= scale; + height /= scale; + + /* now construct specification list and run page rearrangement procedure */ + specs = newspec(); + + if (rotate) { + specs->rotate = 90; + specs->flags |= ROTATE; + } + specs->pageno = 0; + specs->scale = scale; + specs->flags |= SCALE; + specs->xoff = hshift; + specs->yoff = vshift; + specs->flags |= OFFSET; + + pstops_write(1, 1, 0, specs, 0.0, sizeheaders); /* do page rearrangement */ + + return 0; +} + diff --git a/Build/source/utils/psutils/psutils-1.21/psselect.1 b/Build/source/utils/psutils/psutils-1.21/psselect.1 new file mode 100644 index 00000000000..be1260a7a51 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psselect.1 @@ -0,0 +1,84 @@ +.TH PSSELECT 1 "PSUtils" +.SH NAME +psselect \- select pages from a PostScript file +.SH SYNOPSIS +.B psselect +[ +.B \-q +] [ +.B \-e +] [ +.B \-o +] [ +.B \-r +] [ +.B \-p\fIpages\fR +] [ +.I pages +] [ +.I infile +[ +.I outfile +] ] +.SH DESCRIPTION +.I Psselect +selects pages from a PostScript document, creating a new PostScript file. The +input PostScript file should follow the Adobe Document Structuring +Conventions. +.PP +The +.I \-e +option selects all of the even pages; it may be used in conjunction with the +other page selection options to select the even pages from a range of pages. +.PP +The +.I \-o +option selects all of the odd pages; it may be used in conjunction with the +other page selection options. +.PP +The +.I \-p\fIpages\fR +option specifies the pages which are to be selected. +.I Pages +is a comma separated list of page ranges, each of which may be a page number, +or a page range of the form \fIfirst\fR-\fIlast\fR. If \fIfirst\fR is omitted, +the +first page is assumed, and if \fIlast\fR is omitted, the last page is assumed. + +The prefix character `_' indicates that the page number is relative to the end +of the document, counting backwards. If just this character with no page +number is used, a blank page will be inserted. +.PP +The +.I \-r +option causes +.I psselect +to output the selected pages in reverse order. +.PP +Psselect normally prints the page numbers of the pages rearranged; the +.I \-q +option suppresses this. +.PP +If any of the +.I \-r, \-e, +or +.I \-o +options are specified, the page range must be given with the +.I \-p +option. This is for backwards compatibility with previous versions. + +.SH NOTES +The page number given to +.I psselect +is the number of the page counting from the start or end of the file, starting +at one. The actual page number in the document may be different. +.SH AUTHOR +Written by Angus J. C. Duggan. +.SH "SEE ALSO" +psutils(1) +.SH TRADEMARKS +.B PostScript +is a trademark of Adobe Systems Incorporated. +.SH BUGS +.I Psselect +does not accept all DSC comments. diff --git a/Build/source/utils/psutils/psutils-1.21/psselect.c b/Build/source/utils/psutils/psutils-1.21/psselect.c new file mode 100644 index 00000000000..8166f5942f9 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psselect.c @@ -0,0 +1,240 @@ +/* psselect.c + * Rearrange pages in conforming PS file for printing in signatures + * + * (c) Reuben Thomas 2012 + * (c) Angus J. C. Duggan 1991-1997 + * See file LICENSE for details. + */ + +#include "config.h" +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include "psutil.h" + +const char *syntax = "[-q] [-e] [-o] [-r] [-pPAGES] [INFILE [OUTFILE]]\n"; + +const char *argerr_message = ""; + +typedef struct pgrange { + int first, last; + struct pgrange *next; +} PageRange ; + +static PageRange *makerange(int beg, int end, PageRange *next) +{ + PageRange *new; + if ((new = (PageRange *)malloc(sizeof(PageRange))) == NULL) + message(FATAL, "out of memory\n"); + new->first = beg; + new->last = end; + new->next = next; + return (new); +} + + +static PageRange *addrange(char *str, PageRange *rp) +{ + int first=0; + int sign; + + if(!str) return NULL; + + sign = (*str == '_' && ++str) ? -1 : 1; + if (isdigit(*str)) { + first = sign*atoi(str); + while (isdigit(*str)) str++; + } + switch (*str) { + case '\0': + if (first || sign < 0) + return (makerange(first, first, rp)); + break; + case ',': + if (first || sign < 0) + return (addrange(str+1, makerange(first, first, rp))); + break; + case '-': + case ':': + str++; + sign = (*str == '_' && ++str) ? -1 : 1; + if (!first) + first = 1; + if (isdigit(*str)) { + int last = sign*atoi(str); + while (isdigit(*str)) str++; + if (*str == '\0') + return (makerange(first, last, rp)); + if (*str == ',') + return (addrange(str+1, makerange(first, last, rp))); + } else if (*str == '\0') + return (makerange(first, -1, rp)); + else if (*str == ',') + return (addrange(str+1, makerange(first, -1, rp))); + default: /* Avoid a compiler warning */ + break; + } + message(FATAL, "invalid page range\n"); + return (PageRange *)0 ; +} + + +int +main(int argc, char *argv[]) +{ + int opt; + int currentpg, maxpage = 0; + int even = 0, odd = 0, reverse = 0; + int pass, all; + PageRange *pagerange = NULL; + + SET_BINARY(stdin); + SET_BINARY(stdout); + + verbose = 1; + program = *argv; + + while((opt = getopt(argc, argv, "eorqvp:")) != EOF) { + switch(opt) { + case 'e': /* even pages */ + even = 1; + break; + case 'o': /* odd pages */ + odd = 1; + break; + case 'r': /* reverse */ + reverse = 1; + break; + case 'p': /* page spec */ + pagerange = addrange(optarg, pagerange); + break; + case 'q': /* quiet */ + verbose = 0; + break; + case 'v': /* version */ + default: + usage(); + break; + } + } + + infile = stdin; + outfile = stdout; + + /* If we haven't gotten a page range yet, we better get one now */ + if (pagerange == NULL && !reverse && !even && !odd) { + pagerange = addrange(argv[optind], NULL); + optind++; + } + + /* Be defensive */ + if((argc - optind) < 0 || (argc - optind) > 2) usage(); + + if (optind != argc) { + /* User specified an input file */ + if ((infile = fopen(argv[optind], "rb")) == NULL) + message(FATAL, "can't open input file %s\n", argv[optind]); + optind++; + } + + if (optind != argc) { + /* User specified an output file */ + if ((outfile = fopen(argv[optind], "wb")) == NULL) + message(FATAL, "can't open output file %s\n", argv[optind]); + optind++; + } + + if(optind != argc) usage(); + + if ((infile=seekable(infile))==NULL) + message(FATAL, "can't seek input\n"); + + scanpages(NULL); + + /* select all pages or all in range if odd or even not set */ + all = !(odd || even); + + /* add default page range */ + if (!pagerange) + pagerange = makerange(1, -1, NULL); + + /* reverse page list if not reversing pages (list constructed bottom up) */ + if (!reverse) { + PageRange *revlist = NULL; + PageRange *next = NULL; + while (pagerange) { + next = pagerange->next; + pagerange->next = revlist; + revlist = pagerange; + pagerange = next; + } + pagerange = revlist; + } else { /* swap start & end if reversing */ + PageRange *r; + for (r = pagerange; r; r = r->next) { + int temp = r->last; + r->last = r->first; + r->first = temp; + } + } + + { /* adjust for end-relative pageranges */ + PageRange *r; + for (r = pagerange; r; r = r->next) { + if (r->first < 0) { + r->first += pages + 1; + if (r->first < 1) + r->first = 1; + } + if (r->last < 0) { + r->last += pages + 1; + if (r->last < 1) + r->last = 1; + } + } + } + + /* count pages on first pass, select pages on second pass */ + for (pass = 0; pass < 2; pass++) { + PageRange *r; + if (pass) { /* write header on second pass */ + writeheader(maxpage, NULL); + writeprolog(); + writesetup(); + } + for (r = pagerange; r; r = r->next) { + if (r->last < r->first) { + for (currentpg = r->first; currentpg >= r->last; currentpg--) { + if (currentpg == 0 || + (currentpg <= pages && + ((currentpg&1) ? (odd || all) : (even || all)))) { + if (pass) { + if (currentpg) + writepage(currentpg-1); + else + writeemptypage() ; + } else + maxpage++; + } + } + } else { + for (currentpg = r->first; currentpg <= r->last; currentpg++) { + if (currentpg == 0 || + (currentpg <= pages && + ((currentpg&1) ? (odd || all) : (even || all)))) { + if (pass) { + if (currentpg) + writepage(currentpg-1); + else + writeemptypage() ; + } else + maxpage++; + } + } + } + } + } + writetrailer(); + + return 0; +} diff --git a/Build/source/utils/psutils/psutils-1.21/psspec.c b/Build/source/utils/psutils/psutils-1.21/psspec.c new file mode 100644 index 00000000000..9ec2e2e3a18 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psspec.c @@ -0,0 +1,246 @@ +/* psspec.c + * Page spec routines for page rearrangement + * + * (c) Reuben Thomas 2012 + * (c) Angus J. C. Duggan 1991-1997 + * See file LICENSE for details. + */ + +#include "config.h" + +#include "psutil.h" +#include "psspec.h" + +#include <string.h> + +double width = -1; +double height = -1; + +/* create a new page spec */ +PageSpec *newspec(void) +{ + PageSpec *temp = (PageSpec *)malloc(sizeof(PageSpec)); + if (temp == NULL) + message(FATAL, "out of memory\n"); + temp->pageno = temp->flags = temp->rotate = 0; + temp->scale = 1; + temp->xoff = temp->yoff = 0; + temp->next = NULL; + return (temp); +} + +/* dimension parsing routines */ +int parseint(char **sp) +{ + char *s = *sp; + int num = atoi(s); + + while (isdigit(*s)) + s++; + if (*sp == s) argerror(); + *sp = s; + return (num); +} + +double parsedouble(char **sp) +{ + char *s = *sp; + double num = atof(s); + + while (isdigit(*s) || *s == '-' || *s == '.') + s++; + if (*sp == s) argerror(); + *sp = s; + return (num); +} + +double parsedimen(char **sp) +{ + double num = parsedouble(sp); + char *s = *sp; + + if (strncmp(s, "pt", 2) == 0) { + s += 2; + } else if (strncmp(s, "in", 2) == 0) { + num *= 72; + s += 2; + } else if (strncmp(s, "cm", 2) == 0) { + num *= 28.346456692913385211; + s += 2; + } else if (strncmp(s, "mm", 2) == 0) { + num *= 2.8346456692913385211; + s += 2; + } else if (*s == 'w') { + if (width < 0) + message(FATAL, "width not initialised\n"); + num *= width; + s++; + } else if (*s == 'h') { + if (height < 0) + message(FATAL, "height not initialised\n"); + num *= height; + s++; + } + *sp = s; + return (num); +} + +double singledimen(char *str) +{ + double num = parsedimen(&str); + if (*str) usage(); + return (num); +} + +static const char *prologue[] = { /* PStoPS procset */ + /* Wrap these up with our own versions. We have to */ + "userdict begin", + "[/showpage/erasepage/copypage]{dup where{pop dup load", + " type/operatortype eq{ /PStoPSenablepage cvx 1 index" + " load 1 array astore cvx {} bind /ifelse cvx 4 array" + " astore cvx def}{pop}ifelse}{pop}ifelse}forall" + " /PStoPSenablepage true def", + "[/letter/legal/executivepage/a4/a4small/b5/com10envelope", /* nullify */ + " /monarchenvelope/c5envelope/dlenvelope/lettersmall/note", /* paper */ + " /folio/quarto/a5]{dup where{dup wcheck{exch{}put}", /* operators */ + " {pop{}def}ifelse}{pop}ifelse}forall", + "/setpagedevice {pop}bind 1 index where{dup wcheck{3 1 roll put}", + " {pop def}ifelse}{def}ifelse", + "/PStoPSmatrix matrix currentmatrix def", + "/PStoPSxform matrix def/PStoPSclip{clippath}def", + "/defaultmatrix{PStoPSmatrix exch PStoPSxform exch concatmatrix}bind def", + "/initmatrix{matrix defaultmatrix setmatrix}bind def", + "/initclip[{matrix currentmatrix PStoPSmatrix setmatrix", + " [{currentpoint}stopped{$error/newerror false put{newpath}}", + " {/newpath cvx 3 1 roll/moveto cvx 4 array astore cvx}ifelse]", + " {[/newpath cvx{/moveto cvx}{/lineto cvx}", + " {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}", + " stopped{$error/errorname get/invalidaccess eq{cleartomark", + " $error/newerror false put cvx exec}{stop}ifelse}if}bind aload pop", + " /initclip dup load dup type dup/operatortype eq{pop exch pop}", + " {dup/arraytype eq exch/packedarraytype eq or", + " {dup xcheck{exch pop aload pop}{pop cvx}ifelse}", + " {pop cvx}ifelse}ifelse", + " {newpath PStoPSclip clip newpath exec setmatrix} bind aload pop]cvx def", + "/initgraphics{initmatrix newpath initclip 1 setlinewidth", + " 0 setlinecap 0 setlinejoin []0 setdash 0 setgray", + " 10 setmiterlimit}bind def", + "end", + NULL + }; + +void pstops(int modulo, int pps, int nobind, PageSpec *specs, double draw) { + + scanpages(NULL); + pstops_write(modulo, pps, nobind, specs, draw, NULL); +} + +void pstops_write(int modulo, int pps, int nobind, PageSpec *specs, double draw, off_t *ignorelist) +{ + int thispg, maxpage; + int pageindex = 0; + const char **pro; + + maxpage = ((pages+modulo-1)/modulo)*modulo; + + /* rearrange pages: doesn't cope properly with loaded definitions */ + writeheadermedia((maxpage/modulo)*pps, ignorelist, width, height); + writestring("%%BeginProcSet: PStoPS"); + if (nobind) + writestring("-nobind"); + writestring(" 1 15\n"); + for (pro = prologue; *pro; pro++) { + writestring(*pro); + writestring("\n"); + } + if (nobind) /* desperation measures */ + writestring("/bind{}def\n"); + writestring("%%EndProcSet\n"); + /* save transformation from original to current matrix */ + if (writepartprolog()) { + writestring("userdict/PStoPSxform PStoPSmatrix matrix currentmatrix\n"); + writestring(" matrix invertmatrix matrix concatmatrix\n"); + writestring(" matrix invertmatrix put\n"); + } + writesetup(); + for (thispg = 0; thispg < maxpage; thispg += modulo) { + int add_last = 0; + PageSpec *ps; + for (ps = specs; ps != NULL; ps = ps->next) { + int actualpg; + int add_next = ((ps->flags & ADD_NEXT) != 0); + if (ps->flags & REVERSED) + actualpg = maxpage-thispg-modulo+ps->pageno; + else + actualpg = thispg+ps->pageno; + if (actualpg < pages) + seekpage(actualpg); + if (!add_last) { /* page label contains original pages */ + PageSpec *np = ps; + char *eob = pagelabel; + char sep = '('; + do { + *eob++ = sep; + if (np->flags & REVERSED) + sprintf(eob, "%d", maxpage-thispg-modulo+np->pageno); + else + sprintf(eob, "%d", thispg+np->pageno); + eob = eob + strlen(eob); + sep = ','; + } while ((np->flags & ADD_NEXT) && (np = np->next)); + strcpy(eob, ")"); + writepageheader(pagelabel, ++pageindex); + } + writestring("userdict/PStoPSsaved save put\n"); + if (ps->flags & GSAVE) { + char buffer[BUFSIZ]; + writestring("PStoPSmatrix setmatrix\n"); + if (ps->flags & OFFSET) { + sprintf(buffer, "%f %f translate\n", ps->xoff, ps->yoff); + writestring(buffer); + } + if (ps->flags & ROTATE) { + sprintf(buffer, "%d rotate\n", ps->rotate); + writestring(buffer); + } + if (ps->flags & HFLIP) { + sprintf(buffer, "[ -1 0 0 1 %f 0 ] concat\n", width*ps->scale); + writestring(buffer); + } + if (ps->flags & VFLIP) { + sprintf(buffer, "[ 1 0 0 -1 0 %f ] concat\n", height*ps->scale); + writestring(buffer); + } + if (ps->flags & SCALE) { + sprintf(buffer, "%f dup scale\n", ps->scale); + writestring(buffer); + } + writestring("userdict/PStoPSmatrix matrix currentmatrix put\n"); + if (width > 0 && height > 0) { + writestring("userdict/PStoPSclip{0 0 moveto\n"); + sprintf(buffer, " %f 0 rlineto 0 %f rlineto -%f 0 rlineto\n", + width, height, width); + writestring(buffer); + writestring(" closepath}put initclip\n"); + if (draw > 0) { + sprintf(buffer, "gsave clippath 0 setgray %f setlinewidth stroke grestore\n", draw); + writestring(buffer); + } + } + } + if (add_next) + writestring("/PStoPSenablepage false def\n"); + if (actualpg < pages) { + writepagesetup(); + writestring("PStoPSxform concat\n"); + writepagebody(actualpg); + } else { + writestring("PStoPSxform concat\n"); + writestring("showpage\n"); + } + writestring("PStoPSsaved restore\n"); + add_last = add_next; + } + } + writetrailer(); +} diff --git a/Build/source/utils/psutils/psutils-1.21/psspec.h b/Build/source/utils/psutils/psutils-1.21/psspec.h new file mode 100644 index 00000000000..e62d1cfd3f2 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psspec.h @@ -0,0 +1,35 @@ +/* psspec.h + * Page spec routines for page rearrangement + * + * (c) Reuben Thomas 2012 + * (c) Angus J. C. Duggan 1991-1997 + * See file LICENSE for details. + */ + +/* pagespec flags */ +#define ADD_NEXT (0x01) +#define ROTATE (0x02) +#define HFLIP (0x04) +#define VFLIP (0x08) +#define SCALE (0x10) +#define OFFSET (0x20) +#define REVERSED (0x40) +#define GSAVE (ROTATE|HFLIP|VFLIP|SCALE|OFFSET) + +typedef struct pagespec { + int pageno, flags, rotate; + double xoff, yoff, scale; + struct pagespec *next; +} PageSpec ; + +extern double width, height; + +extern PageSpec *newspec(void); +extern int parseint(char **sp); +extern double parsedouble(char **sp); +extern double parsedimen(char **sp); +extern double singledimen(char *str); +extern void pstops(int modulo, int pps, int nobind, PageSpec *specs, + double draw); +extern void pstops_write(int modulo, int pps, int nobind, PageSpec *specs, + double draw, off_t *ignorelist); diff --git a/Build/source/utils/psutils/psutils-1.21/pstops.1 b/Build/source/utils/psutils/psutils-1.21/pstops.1 new file mode 100644 index 00000000000..1a65d1e92ee --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/pstops.1 @@ -0,0 +1,166 @@ +.TH PSTOPS 1 "PSUtils" +.SH NAME +pstops \- shuffle pages in a PostScript file +.SH SYNOPSIS +.B pstops +[ +.B \-q +] [ +.B \-b +] [ +.B \-w\fIwidth\fR +] [ +.B \-h\fIheight\fR +] [ +.B \-p\fIpaper\fR +] [ +.B \-d\fIlwidth\fR +] +.I pagespecs +[ +.I infile +[ +.I outfile +] ] +.SH DESCRIPTION +.I Pstops +rearranges pages from a PostScript document, creating a new PostScript file. +The input PostScript file should follow the Adobe Document Structuring +Conventions. +.I Pstops +can be used to perform a large number of arbitrary re-arrangements of +Documents, including arranging for printing 2-up, 4-up, booklets, reversing, +selecting front or back sides of documents, scaling, etc. +.PP +.I pagespecs +follow the syntax: +.RS +.TP 12 +.I pagespecs +.I = [modulo:]specs +.TP +.I specs +.I = spec[+specs][,specs] +.TP +.I spec +.I = [-]pageno[L][R][U][H][V][@scale][(xoff,yoff)] +.RE +.sp +.I modulo +is the number of pages in each block. The value of +.I modulo +should be greater than 0; the default value is 1. +.I specs +are the page specifications for the pages in each block. The value of the +.I pageno +in each +.I spec +should be between 0 (for the first page in the block) and \fImodulo\fR-1 +(for the last page in each block) inclusive. +The optional dimensions +.I xoff +and +.I yoff +shift the page by the specified amount. +.I xoff +and +.I yoff +are in PostScript's points, but may be followed by the units +.B "cm" +or +.B "in" +to convert to centimetres or inches, or the flag +.B "w" +or +.B "h" +to specify as a multiple of the width or height. +The optional parameters \fIL\fR, \fIR\fR, \fIU\fR, \fIH\fR and \fIV\fR +rotate the page left, right, or upside-down, and flip (mirror) page +horizontally or vertically. +The optional +.I scale +parameter scales the page by the fraction specified. +If the optional minus sign is specified, the page is relative to the end of +the document, instead of the start. + +If page \fIspec\fRs are separated by +.B \+ +the pages will be merged into one page; if they are separated by +.B , +they will be on separate pages. +If there is only one page specification, with +.I pageno +zero, the \fIpageno\fR may be omitted. + +The shift, rotation, and scaling are applied +to the PostScript transformation matrix +in that order regardless of which order +they appear on the command line. +The matrix accumulates the individual transformations. +The effect on the image is to first scale with respect to an origin +at the lower left corner, then rotate about the same origin, and +finally shift. +.PP +The +.I \-w +option gives the width which is used by the +.B "w" +dimension specifier, and the +.I \-h +option gives the height which is used by the +.B "h" +dimension specifier. These dimensions are also used (after scaling) to set the +clipping path for each page. +The +.I \-p +.PP +The +.I \-b +option prevents any +.B bind +operators in the PostScript prolog from binding. This may be needed in cases +where complex multi-page re-arrangements are being done. +.PP +The +.I \-d +option draws a line around the border of each page, of the specified width. +If the \fIlwidth\fR parameter is omitted, a default linewidth of 1 point is +assumed. The linewidth is relative to the original page dimensions, +\fIi.e.\fR it is scaled up or down with the rest of the page. +.PP +Pstops normally prints the page numbers of the pages re-arranged; the +.I \-q +option suppresses this. +.SH EXAMPLES +This section contains some sample re-arrangements. To put two pages on one +sheet (of A4 paper), the pagespec to use is: +.sp +.ce +"2:0L@.7(21cm,0)+1L@.7(21cm,14.85cm)" +.sp +To select all of the odd pages in reverse order, use: +.sp +.ce +2:-0 +.sp +To re-arrange pages for printing 2-up booklets, use +.sp +.ce +"4:-3L@.7(21cm,0)+0L@.7(21cm,14.85cm)" +.sp +for the front sides, and +.sp +.ce +"4:1L@.7(21cm,0)+-2L@.7(21cm,14.85cm)" +.sp +for the reverse sides (or join them with a comma for duplex printing). +.SH AUTHOR +Written by Angus J. C. Duggan. +.SH "SEE ALSO" +psutils(1) +.SH TRADEMARKS +.B PostScript +is a trademark of Adobe Systems Incorporated. +.SH BUGS +.I Pstops +does not accept all DSC comments. diff --git a/Build/source/utils/psutils/psutils-1.21/pstops.c b/Build/source/utils/psutils/psutils-1.21/pstops.c new file mode 100644 index 00000000000..cb1f658c80a --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/pstops.c @@ -0,0 +1,212 @@ +/* pstops.c + * Rearrange pages in conforming PS file + * + * (c) Reuben Thomas 2012 + * (c) Angus J. C. Duggan 1991-1997 + * See file LICENSE for details. + */ + +#include "config.h" +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <string.h> +#include <paper.h> + +#include "psutil.h" +#include "psspec.h" + +const char *syntax = "[-q] [-b] [-wWIDTH] [-hHEIGHT] [-dLWIDTH] [-pPAPER] PAGESPECS [INFILE [OUTFILE]]\n"; + +const char *argerr_message = "%page specification error:\n" + " pagespecs = [modulo:]spec\n" + " spec = [-]pageno[@scale][L|R|U|H|V][(xoff,yoff)][,spec|+spec]\n" + " modulo >= 1, 0 <= pageno < modulo\n"; + +static int modulo = 1; +static int pagesperspec = 1; + +static PageSpec *parsespecs(char *str) +{ + PageSpec *head, *tail; + unsigned long spec_count = 0; + long num = -1; + + head = tail = newspec(); + while (*str) { + if (isdigit(*str)) { + num = parseint(&str); + } else { + switch (*str++) { + case ':': + if (spec_count || head != tail || num < 1) argerror(); + modulo = num; + num = -1; + break; + case '-': + tail->flags ^= REVERSED; + break; + case '@': + tail->scale *= parsedouble(&str); + tail->flags |= SCALE; + break; + case 'l': case 'L': + tail->rotate += 90; + tail->flags |= ROTATE; + break; + case 'r': case 'R': + tail->rotate -= 90; + tail->flags |= ROTATE; + break; + case 'u': case 'U': + tail->rotate += 180; + tail->flags |= ROTATE; + break; + case 'h': case 'H': + tail->flags ^= HFLIP; + break; + case 'v': case 'V': + tail->flags ^= VFLIP; + break; + case '(': + tail->xoff += parsedimen(&str); + if (*str++ != ',') argerror(); + tail->yoff += parsedimen(&str); + if (*str++ != ')') argerror(); + tail->flags |= OFFSET; + break; + case '+': + tail->flags |= ADD_NEXT; + case ',': + if (num < 0 || num >= modulo) argerror(); + if ((tail->flags & ADD_NEXT) == 0) + pagesperspec++; + tail->pageno = num; + tail->next = newspec(); + tail = tail->next; + num = -1; + break; + default: + argerror(); + } + spec_count++; + } + } + if (num >= modulo) + argerror(); + else if (num >= 0) + tail->pageno = num; + return (head); +} + +int +main(int argc, char *argv[]) +{ + PageSpec *specs = NULL; + int nobinding = 0; + double draw = 0; + const struct paper *paper = NULL; + int opt; + + SET_BINARY(stdin); + SET_BINARY(stdout); + + set_paper_size(NULL); + + verbose = 1; + + program = *argv; + + while((opt = getopt(argc, argv, "qd::bw:h:p:v0123456789")) != EOF) { + switch(opt) { + case 'q': /* quiet */ + verbose = 0; + break; + case 'd': /* draw borders */ + if(optarg) + draw = singledimen(optarg); + else + draw = 1; + break; + case 'b': /* no bind operator */ + nobinding = 1; + break; + case 'w': /* page width */ + width = singledimen(optarg); + break; + case 'h': /* page height */ + height = singledimen(optarg); + break; + case 'p': /* paper type */ + if ( (paper = paperinfo(optarg)) != NULL ) { + width = paperpswidth(paper); + height = paperpsheight(paper); + } else + message(FATAL, "paper size '%s' not recognised\n", optarg); + break; + case 'v': /* version */ + usage(); + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (specs == NULL) { + char *spec_txt = malloc((optarg ? strlen(optarg) : 0) + 3); + if(!spec_txt) message(FATAL, "no memory for spec allocation\n"); + spec_txt[0] = '-'; + spec_txt[1] = opt; + spec_txt[2] = 0; + if (optarg) strcat(spec_txt, optarg); + specs = parsespecs(spec_txt); + free(spec_txt); + } else { + usage(); + } + break; + default: + usage(); + break; + } + } + + if (specs == NULL) { + if(optind == argc) usage(); + specs = parsespecs(argv[optind]); + optind++; + } + + infile = stdin; + outfile = stdout; + + /* Be defensive */ + if((argc - optind) < 0 || (argc - optind) > 2) usage(); + + if (optind != argc) { + /* User specified an input file */ + if ((infile = fopen(argv[optind], "rb")) == NULL) + message(FATAL, "can't open input file %s\n", argv[optind]); + optind++; + } + + if (optind != argc) { + /* User specified an output file */ + if ((outfile = fopen(argv[optind], "wb")) == NULL) + message(FATAL, "can't open output file %s\n", argv[optind]); + optind++; + } + + if (optind != argc || specs == NULL) usage(); + + if ((infile=seekable(infile))==NULL) + message(FATAL, "can't seek input\n"); + + pstops(modulo, pagesperspec, nobinding, specs, draw); + + return 0; +} diff --git a/Build/source/utils/psutils/psutils-1.21/psutil.c b/Build/source/utils/psutils/psutils-1.21/psutil.c new file mode 100644 index 00000000000..a6ef8456b6f --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psutil.c @@ -0,0 +1,412 @@ +/* psutil.c + * PSUtils utility functions + * + * (c) Reuben Thomas 2012 + * (c) Angus J. C. Duggan 1991-1997 + * See file LICENSE for details. + */ + +#include "config.h" + +#define _FILE_OFFSET_BITS 64 + +#include "psutil.h" +#include "psspec.h" + +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <paper.h> + +#define iscomment(x,y) (strncmp(x,y,strlen(y)) == 0) + +char *program; +int pages; +int verbose; +FILE *infile; +FILE *outfile; +char pagelabel[BUFSIZ]; +int pageno; + +static char buffer[BUFSIZ]; +static long bytes = 0; +static off_t pagescmt = 0; +static off_t headerpos = 0; +static off_t endsetup = 0; +static off_t beginprocset = 0; /* start of pstops procset */ +static off_t endprocset = 0; +static int outputpage = 0; +static int maxpages = 100; +static off_t *pageptr; + +_Noreturn void usage(void) +{ + fprintf(stderr, "%s %s\n", program, PACKAGE_VERSION); + fprintf(stderr, COPYRIGHT_STRING); + fprintf(stderr, "Usage: %s %s", program, syntax); + fflush(stderr); + exit(1); +} + +void argerror(void) +{ + message(FATAL, argerr_message); +} + +/* Message function: for messages, warnings, and errors sent to stderr. + If called with the flag MESSAGE_EXIT set, the routine does not return. */ +void message(int flags, const char *format, ...) +{ + va_list args ; + + if ( flags & MESSAGE_PROGRAM ) + fprintf(stderr, "%s: ", program) ; + + if ( (flags & MESSAGE_NL) ) + putc('\n', stderr) ; + + va_start(args, format) ; + vfprintf(stderr, format, args); + va_end(args) ; + + if ( flags & MESSAGE_EXIT ) /* don't return to program */ + exit(1) ; +} + +static void maybe_init_libpaper(void) +{ + static int libpaper_initted = 0; + if (!libpaper_initted) { + paperinit(); + libpaper_initted = 1; + } +} + +void set_paper_size(const char *paper_name) +{ + const struct paper *paper = get_paper(paper_name); + if (paper) { + width = paperpswidth(paper); + height = paperpsheight(paper); + } +} + +const struct paper *get_paper(const char *paper_name) +{ + maybe_init_libpaper(); + if (paper_name == NULL) + paper_name = systempapername(); + if (paper_name) + return paperinfo(paper_name); + return NULL; +} + +/* Make a file seekable, using temporary files if necessary */ +FILE *seekable(FILE *fp) +{ + FILE *ft; + long r, w ; + char *p; + char buffer[BUFSIZ] ; + off_t fpos; + + if ((fpos = ftello(fp)) >= 0) + if (!fseeko(fp, (off_t) 0, SEEK_END) && !fseeko(fp, fpos, SEEK_SET)) + return (fp); + + if ((ft = tmpfile()) == NULL) + return (NULL); + + while ((r = fread(p = buffer, sizeof(char), BUFSIZ, fp)) > 0) { + do { + if ((w = fwrite(p, sizeof(char), r, ft)) == 0) + return (NULL) ; + p += w ; + r -= w ; + } while (r > 0) ; + } + + if (!feof(fp)) + return (NULL) ; + + /* discard the input file, and rewind the temporary */ + (void) fclose(fp); + if (fseeko(ft, (off_t) 0, SEEK_SET) != 0) + return (NULL) ; + + return (ft); +} + + +/* copy input file from current position upto new position to output file, + * ignoring the lines starting at something ignorelist points to */ +static int fcopy(off_t upto, off_t *ignorelist) +{ + off_t here = ftello(infile); + off_t bytes_left; + + if (ignorelist != NULL) { + while (*ignorelist > 0 && *ignorelist < here) + ignorelist++; + + while (*ignorelist > 0 && *ignorelist < upto) { + int r = fcopy(*ignorelist, NULL); + if (!r || fgets(buffer, BUFSIZ, infile) == NULL) + return 0; + ignorelist++; + here = ftello(infile); + while (*ignorelist > 0 && *ignorelist < here) + ignorelist++; + } + } + bytes_left = upto - here; + + while (bytes_left > 0) { + size_t rw_result; + const size_t numtocopy = (bytes_left > BUFSIZ) ? BUFSIZ : bytes_left; + rw_result = fread(buffer, 1, numtocopy, infile); + if (rw_result < numtocopy) return (0); + rw_result = fwrite(buffer, 1, numtocopy, outfile); + if (rw_result < numtocopy) return (0); + bytes_left -= numtocopy; + bytes += numtocopy; + } + return (1); +} + +/* build array of pointers to start/end of pages */ +void scanpages(off_t *sizeheaders) +{ + register char *comment = buffer+2; + register int nesting = 0; + register off_t record; + + if (sizeheaders) + *sizeheaders = 0; + + if ((pageptr = (off_t *)malloc(sizeof(off_t)*maxpages)) == NULL) + message(FATAL, "out of memory\n"); + pages = 0; + fseeko(infile, (off_t) 0, SEEK_SET); + while (record = ftello(infile), fgets(buffer, BUFSIZ, infile) != NULL) + if (*buffer == '%') { + if (buffer[1] == '%') { + if (nesting == 0 && iscomment(comment, "Page:")) { + if (pages >= maxpages-1) { + maxpages *= 2; + if ((pageptr = (off_t *)realloc((char *)pageptr, + sizeof(off_t)*maxpages)) == NULL) + message(FATAL, "out of memory\n"); + } + pageptr[pages++] = record; + } else if (headerpos == 0 && iscomment(comment, "BoundingBox:")) { + if (sizeheaders) { + *(sizeheaders++) = record; + *sizeheaders = 0; + } + } else if (headerpos == 0 && iscomment(comment, "HiResBoundingBox:")) { + if (sizeheaders) { + *(sizeheaders++) = record; + *sizeheaders = 0; + } + } else if (headerpos == 0 && iscomment(comment,"DocumentPaperSizes:")) { + if (sizeheaders) { + *(sizeheaders++) = record; + *sizeheaders = 0; + } + } else if (headerpos == 0 && iscomment(comment,"DocumentMedia:")) { + if (sizeheaders) { + *(sizeheaders++) = record; + *sizeheaders = 0; + } + } else if (headerpos == 0 && iscomment(comment, "Pages:")) + pagescmt = record; + else if (headerpos == 0 && iscomment(comment, "EndComments")) + headerpos = ftello(infile); + else if (iscomment(comment, "BeginDocument") || + iscomment(comment, "BeginBinary") || + iscomment(comment, "BeginFile")) + nesting++; + else if (iscomment(comment, "EndDocument") || + iscomment(comment, "EndBinary") || + iscomment(comment, "EndFile")) + nesting--; + else if (nesting == 0 && iscomment(comment, "EndSetup")) + endsetup = record; + else if (nesting == 0 && iscomment(comment, "BeginProlog")) + headerpos = ftello(infile); + else if (nesting == 0 && + iscomment(comment, "BeginProcSet: PStoPS")) + beginprocset = record; + else if (beginprocset && !endprocset && + iscomment(comment, "EndProcSet")) + endprocset = ftello(infile); + else if (nesting == 0 && (iscomment(comment, "Trailer") || + iscomment(comment, "EOF"))) { + fseeko(infile, record, SEEK_SET); + break; + } + } else if (headerpos == 0 && buffer[1] != '!') + headerpos = record; + } else if (headerpos == 0) + headerpos = record; + pageptr[pages] = ftello(infile); + if (endsetup == 0 || endsetup > pageptr[0]) + endsetup = pageptr[0]; +} + +/* seek a particular page */ +void seekpage(int p) +{ + fseeko(infile, pageptr[p], SEEK_SET); + if (fgets(buffer, BUFSIZ, infile) != NULL && + iscomment(buffer, "%%Page:")) { + char *start, *end; + for (start = buffer+7; isspace(*start); start++); + if (*start == '(') { + int paren = 1; + for (end = start+1; paren > 0; end++) + switch (*end) { + case '\0': + message(FATAL, "Bad page label while seeking page %d\n", p); + case '(': + paren++; + break; + case ')': + paren--; + break; + default: + break; + } + } else + for (end = start; !isspace(*end); end++); + strncpy(pagelabel, start, end-start); + pagelabel[end-start] = '\0'; + pageno = atoi(end); + } else + message(FATAL, "I/O error seeking page %d\n", p); +} + +/* Output routines. These all update the global variable bytes with the number + * of bytes written */ +void writestring(const char *s) +{ + fputs(s, outfile); + bytes += strlen(s); +} + +/* write page comment */ +void writepageheader(const char *label, int page) +{ + if (verbose) + message(LOG, "[%d] ", page); + sprintf(buffer, "%%%%Page: %s %d\n", label, ++outputpage); + writestring(buffer); +} + +/* search for page setup */ +void writepagesetup(void) +{ + char buffer[BUFSIZ]; + if (beginprocset) { + for (;;) { + if (fgets(buffer, BUFSIZ, infile) == NULL) + message(FATAL, "I/O error reading page setup %d\n", outputpage); + if (!strncmp(buffer, "PStoPSxform", 11)) + break; + if (fputs(buffer, outfile) == EOF) + message(FATAL, "I/O error writing page setup %d\n", outputpage); + bytes += strlen(buffer); + } + } +} + +/* write the body of a page */ +void writepagebody(int p) +{ + if (!fcopy(pageptr[p+1], NULL)) + message(FATAL, "I/O error writing page %d\n", outputpage); +} + +/* write a whole page */ +void writepage(int p) +{ + seekpage(p); + writepageheader(pagelabel, p+1); + writepagebody(p); +} + +/* write from start of file to end of header comments */ +void writeheader(int p, off_t *ignore) +{ + writeheadermedia(p, ignore, -1, -1); +} + +void writeheadermedia(int p, off_t *ignore, double width, double height) +{ + fseeko(infile, (off_t) 0, SEEK_SET); + if (pagescmt) { + if (!fcopy(pagescmt, ignore) || fgets(buffer, BUFSIZ, infile) == NULL) + message(FATAL, "I/O error in header\n"); + if (width > -1 && height > -1) { + sprintf(buffer, "%%%%DocumentMedia: plain %d %d 0 () ()\n", (int) width, (int) height); + writestring(buffer); + sprintf(buffer, "%%%%BoundingBox: 0 0 %d %d\n", (int) width, (int) height); + writestring(buffer); + } + sprintf(buffer, "%%%%Pages: %d 0\n", p); + writestring(buffer); + } + if (!fcopy(headerpos, ignore)) + message(FATAL, "I/O error in header\n"); +} + +/* write prologue to end of setup section excluding PStoPS procset */ +int writepartprolog(void) +{ + if (beginprocset && !fcopy(beginprocset, NULL)) + message(FATAL, "I/O error in prologue\n"); + if (endprocset) + fseeko(infile, endprocset, SEEK_SET); + writeprolog(); + return !beginprocset; +} + +/* write prologue up to end of setup section */ +void writeprolog(void) +{ + if (!fcopy(endsetup, NULL)) + message(FATAL, "I/O error in prologue\n"); +} + +/* write from end of setup to start of pages */ +void writesetup(void) +{ + if (!fcopy(pageptr[0], NULL)) + message(FATAL, "I/O error in prologue\n"); +} + +/* write trailer */ +void writetrailer(void) +{ + fseeko(infile, pageptr[pages], SEEK_SET); + while (fgets(buffer, BUFSIZ, infile) != NULL) { + writestring(buffer); + } + if (verbose) + message(LOG, "Wrote %d pages, %ld bytes\n", outputpage, bytes); +} + +/* write a page with nothing on it */ +void writeemptypage(void) +{ + if (verbose) + message(LOG, "[*] "); + sprintf(buffer, "%%%%Page: * %d\n", ++outputpage); + writestring(buffer); + if (beginprocset) + writestring("PStoPSxform concat\n"); + writestring("showpage\n"); +} + diff --git a/Build/source/utils/psutils/psutils-1.21/psutil.h b/Build/source/utils/psutils/psutils-1.21/psutil.h new file mode 100644 index 00000000000..4cd2f22eebb --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psutil.h @@ -0,0 +1,82 @@ +/* psutil.h + * PSUtils utility functions + * + * (c) Reuben Thomas 2012 + * (c) Angus J. C. Duggan 1991-1997 + * See file LICENSE for details. + */ +#define _FILE_OFFSET_BITS 64 +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <stdarg.h> + +/* message flags */ +#define MESSAGE_NL 1 /* Newline before message if necessary */ +#define MESSAGE_PROGRAM 2 /* announce program name */ +#define MESSAGE_EXIT 4 /* do not return */ + +/* message types */ +#define FATAL (MESSAGE_EXIT|MESSAGE_PROGRAM|MESSAGE_NL) +#define WARN (MESSAGE_NL|MESSAGE_PROGRAM) +#define LOG 0 + +/* change mode of a file pointer on Windows */ +#if defined(WIN32) +#include <io.h> +#include <fcntl.h> +#define SET_BINARY(fp) (void)_setmode(fileno(fp), _O_BINARY) +#undef off_t +#undef ftello +#undef fseeko +#if defined(__MINGW32__) +#define off_t off64_t +#define ftello ftello64 +#define fseeko fseeko64 +#else +#define off_t __int64 +#define xfseeko xfseek64 +#define xftello xftell64 +#endif +#else /* !WIN32 */ +#define SET_BINARY(fp) (void)0 +#endif + +/* Definitions for functions found in psutil.c */ +extern void usage(void); +extern void message(int flags, const char *format, ...); +extern void argerror(void); +extern void set_paper_size(const char *paper_name); +const struct paper *get_paper(const char *paper_name); +extern FILE *seekable(FILE *fp); +extern void writepage(int p); +extern void seekpage(int p); +extern void writepageheader(const char *label, int p); +extern void writepagesetup(void); +extern void writepagebody(int p); +extern void writeheader(int p, off_t *ignorelist); +extern void writeheadermedia(int p, off_t *ignorelist, double width, double height); +extern int writepartprolog(void); +extern void writeprolog(void); +extern void writesetup(void); +extern void writetrailer(void); +extern void writeemptypage(void); +extern void scanpages(off_t *sizeheaders); +extern void writestring(const char *s); + +/* These variables are exported to the client program */ +extern char *program ; +extern int pages; +extern int verbose; +extern FILE *infile; +extern FILE *outfile; +extern char pagelabel[BUFSIZ]; +extern int pageno; + +/* Variables imported from the client program */ +extern const char *syntax; +extern const char *argerr_message; + +/* Useful macros */ +#define MIN(x,y) ((x) > (y) ? (y) : (x)) +#define COPYRIGHT_STRING "(c) Reuben Thomas <rrt@sc3d.org> 2012\n(c) Angus J. C. Duggan 1991-1997\nSee file LICENSE for details.\n" diff --git a/Build/source/utils/psutils/psutils-1.21/psutils.1 b/Build/source/utils/psutils/psutils-1.21/psutils.1 new file mode 100644 index 00000000000..5ddc7b94925 --- /dev/null +++ b/Build/source/utils/psutils/psutils-1.21/psutils.1 @@ -0,0 +1,13 @@ +.TH PSUTILS 1 "PSUtils" +.SH NAME +PSUtils \- utilities +.SH DESCRIPTION +PSUtils is a set of utilities for manipulating PostScript +documents which follow the Adobe Document Structuring Conventions. +.SH AUTHOR +Written by Angus J. C. Duggan. +.SH "SEE ALSO" +psbook(1), psselect(1), pstops(1), epsffit(1), psnup(1), psresize(1), psjoin(1), extractres(1), includeres(1) +.SH TRADEMARKS +.B PostScript +is a trademark of Adobe Systems Incorporated. |